@lumen-stack/react 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +24 -2
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../core/src/errors.ts","../../core/src/client.ts","../../core/src/conceal.ts","../../core/src/capture-screenshot.ts","../../core/src/redact.ts","../../core/src/capture-runtime.ts","../../core/src/capture-context.ts","../../core/src/dom-contract.ts","../../core/src/native-bridge.ts","../../core/src/keyboard-inset.ts","../../core/src/record-audio.ts","../../core/src/record-video.ts","../src/context.ts","../src/trigger/useViewportKeyboard.ts","../src/trigger/useKeyboardInset.ts","../src/AnnotationLayer.tsx","../src/icons.tsx","../src/video-poster.ts","../src/CaptureModal.tsx","../src/LumenErrorBoundary.tsx","../src/RecordingHud.tsx","../src/ScreenCaptureHud.tsx","../src/record-availability.ts","../src/record-session.ts","../src/trigger/autoDetectAvoid.ts","../src/trigger/useCollisionInsets.ts","../src/trigger/useTriggerActivation.ts","../src/trigger/FloatingTrigger.tsx","../src/trigger/InlineTrigger.tsx","../src/trigger/NotchTrigger.tsx","../src/trigger/types.ts","../src/trigger/theme.ts","../src/trigger/useHideOn.ts","../src/trigger/useNativeShell.ts","../src/trigger/useRemoteConfig.ts","../src/trigger/useShakeToOpen.ts","../src/LumenProvider.tsx","../src/FeedbackButton.tsx"],"names":["LumenError","message","code","status","LumenOriginError","LumenRateLimitError","retryAfter","LumenNetworkError","DEFAULT_API_URL","SUBMIT_PATH","ERROR_PATH","LUMEN_SDK_VERSION","MAX_CLIENT_ERROR_REPORTS","RETRYABLE_STATUSES","LumenClient","#errorReportKeys","#errorReportCount","config","payload","options","url","body","#buildFormData","lastError","attempt","wait","#sendOnce","e","input","firstFrame","key","nav","mem","u","fd","amplitude","context","screenshotFilename","resolve","reject","xhr","onUploadProgress","signal","onAbort","parseError","parsed","blob","ms","r","text","obj","DEFAULT_CONCEAL","concealLumenChrome","selector","hidden","el","prev","DEFAULT_MAX_SCALE","SMALL_VIEWPORT_MAX_SCALE","SMALL_VIEWPORT_MAX_WIDTH","MAX_CANVAS_MEGAPIXELS","MAX_SCREENSHOT_BYTES","captureScreen","assertBrowser","mode","normalizeProviderResult","captureDisplayMedia","captureDom","domError","canUseDisplayMedia","result","uniq","createManualCaptureResult","warnings","viewport","currentViewport","domCaptureTail","run","doCaptureDom","html2canvas","loadHtml2Canvas","target","layout","layoutViewport","visual","originX","originY","scale","resolveScale","collectDomWarnings","isReactNativeWebView","inputSnapshots","snapshotInputs","waitForAnimationsToSettle","DEFAULT_AWAIT_ANIMATIONS_MS","nextFramePause","canvas","clonedDoc","clonedRef","applyInputSnapshots","maskSensitiveFields","encodeCanvas","MASK_SELECTOR","doc","field","SYNC_EXCLUDE_SELECTOR","collectSyncInputs","root","type","snapshots","inputs","i","snap","startDisplayMediaCapture","stream","video","waitForVideoFrame","track","liveVideo","stopped","endedCbs","cb","grabOptions","shouldConceal","restore","waitForFreshFrames","ctx","session","normalized","crossOriginImages","img","src","canvasToBlob","working","ratio","next","quality","cropWidth","cropHeight","dpr","max","isSmallTouchViewport","budgetScale","touch","layoutW","maxMs","animations","pending","a","timing","settled","cap","done","fail","start","MAX_WAIT_MS","minFrames","rvfc","seen","tick","values","SENSITIVE_PARAM","KNOWN_SECRET_PATTERNS","isLuhnValid","raw","digits","sum","double","d","redactText","s","re","whole","quote","value","m","redactUrl","k","out","stripUrlToPath","MAX_ENTRIES","MAX_STRING","consoleBuf","networkBuf","installed","ignoreUrlPrefix","installRuntimeCapture","patchConsole","patchFetch","patchXhr","readRuntimeCapture","pushBounded","buf","entry","safeStringify","args","arg","replacer","joined","_key","levels","level","original","isIgnored","originalFetch","init","method","started","res","sanitizeUrl","OriginalXHR","originalOpen","originalSend","rest","meta","onDone","truncate","captureContext","capture","toCaptureMetadata","runtime","snapshotDevice","device","LUMEN_ROOT_SELECTOR","LUMEN_MARKER_SELECTOR","isLumenEventTarget","event","path","isLumenNode","ISOLATED_EVENT_TYPES","isolateLumenEvents","stop","LUMEN_SHAKE_MESSAGE","DEFAULT_TIMEOUT_MS","DEFAULT_CAPTURE_SETTLE_MS","createNativeCaptureProvider","registry","ensureRegistry","send","defaultSend","timeoutMs","captureSettleMs","awaitAnimationsMs","id","newRequestId","settleAfterConceal","response","timer","dataUrlToBlob","platform","detectPlatform","request","rn","dataUrl","pixelRatio","error","onMessage","data","parseMessage","nextAnimationFrame","ua","match","mime","isBase64","binary","bytes","LUMEN_KEYBOARD_EVENT","LUMEN_KEYBOARD_CSS_VAR","setLumenKeyboardInset","insetPx","px","readLumenKeyboardInset","g","recordAudio","maxSeconds","mimeType","recorder","chunks","timeoutId","cancelled","resolveResult","rejectResult","durationMs","finalType","requestStop","recordVideo","release","LumenContext","createContext","useLumen","useContext","KEYBOARD_THRESHOLD","isEditableElementFocused","tag","CLOSED","decideKeyboardInset","explicit","open","delta","useKeyboardInset","enabled","override","state","setState","useState","baselineRef","useRef","overrideRef","useEffect","coarse","recompute","editable","injected","wt","vv","raf","schedule","se","BUBBLE_FONT","clamp01","v","AnnotationLayer","_n","screenshot","tool","color","strokeWidth","onDrawingChange","onHistoryChange","ref","baseCanvasRef","overlayCanvasRef","containerRef","imageBitmap","setImageBitmap","baseDrawFailed","setBaseDrawFailed","fallbackUrl","setFallbackUrl","annotations","setAnnotations","draftRef","isDrawingRef","lastSampleAtRef","rafPendingRef","comments","setComments","seqRef","undoStackRef","redoStackRef","annotationsRef","commentsRef","pendingFocusRef","onHistoryChangeRef","fireHistory","useCallback","handleCommentChange","cur","c","handleCommentRemove","decoded","bm","base","overlay","redraw","useImperativeHandle","last","removed","draft","all","liveComments","anno","drawAnno","renderedWidth","bubbleScale","drawBubble","clientToCanvas","rect","sx","sy","scheduleDraftPaint","onPointerDown","fx","fy","p","onPointerMove","dist2","now","elapsed","onPointerUp","dx","dy","jsxs","jsx","Bubble","comment","onChange","onRemove","elRef","x","y","w","h","drawSmoothPath","from","to","width","angle","head","points","first","second","mx","my","W","H","pad","fontPx","labelPx","radius","lineH","labelH","maxBoxW","lines","wrapText","textW","l","boxW","boxH","roundRect","tailX","tailY","ty","line","maxWidth","words","test","anyCtx","Svg","children","props","IconScreenshot","IconVideo","IconUpload","IconComment","IconArrow","IconBox","IconDraw","IconUndo","IconRefresh","IconRedo","IconTrash","IconChevronLeft","IconSend","IconMonitor","IconMic","METHOD_ICONS","drawPoster","b","seek","POSTER_DECODE_TIMEOUT_MS","posterFromVideoBlob","poster","deadline","posterFromStream","placeholderPoster","VOICE_MAX_SECONDS","VIDEO_SIZE_WARN_BYTES","SWATCHES","STROKE_SIZES","CATEGORIES","PRIORITIES","SOURCE_CHIPS","deriveSource","PriorityIcon","METHODS","CaptureModal","client","isOpen","closeCapture","user","initialCapture","initialCaptureError","startVideoSession","consumePendingVideo","canRecordScreen","consumeRecordStartError","startScreenCaptureSession","consumePendingScreenshot","isolateEvents","keyboardInset","step","setStep","setMethod","phase","setPhase","submitting","setSubmitting","progress","setProgress","setTool","strokeColor","setStrokeColor","setStrokeWidth","setText","category","setCategory","priority","setPriority","source","setSource","toolsHidden","setToolsHidden","sheetCollapsed","setSheetCollapsed","recapMenuOpen","setRecapMenuOpen","colorPickerOpen","setColorPickerOpen","submitterEmail","setSubmitterEmail","setRecorder","audio","setAudio","recordSecs","setRecordSecs","setVideo","videoError","setVideoError","drawing","setDrawing","history","setHistory","annotationRef","uploadInputRef","modalRef","backdropRef","previouslyFocusedRef","keyboard","captureCancelledRef","seededRef","pendingShot","showCaptureWarnings","toast","Se","posterBlob","startErr","runCapture","html","prevOverflow","prevPaddingRight","scrollbar","restored","onKey","focusables","getFocusable","active","stopOnBackdrop","onPaste","file","item","acceptUploadedFile","sec","finishRecording","recorderRef","A","selectMethod","discardVideo","startRecording","ht","discardRecording","renderVoiceNote","variant","controls","Fragment","Waveform","AudioPreview","beginVideoRecording","captured","goNext","submit","goBack","trimmed","captureResult","flatScreenshot","V","fraction","onBackdropMouseDown","uploadingPct","isVideoMethod","trueScreenAvailable","showExactCapture","nextDisabled","nextLabel","captureFullscreen","reviewFullscreen","fsMode","SheetGrabber","Stepper","Icon","RecordPrompt","o","ToolButton","captureLabel","steps","canRecord","onRecord","onUpload","isIOSBrowser","label","onClick","icon","onDismiss","startYRef","startTimeRef","targetRef","dt","velocity","canvasRef","cssWidth","cssHeight","AudioCtor","audioCtx","analyser","BARS","GAP","MIN_H","barW","frame","bucketSize","getCssVar","peak","j","roundRectPath","setUrl","name","FOCUSABLE_SELECTOR","LumenErrorBoundary","Qn","info","err","RecordingHud","portalTarget","onStop","onCancel","mounted","setMounted","createPortal","RecordingControl","startedAt","setElapsed","fmt","ScreenCaptureHud","onCapture","grabbing","resolveRecordCapability","providerUsable","isRecorderStopped","asError","driveRecordSession","provider","stopRequested","finishCancelled","finishResult","finishError","detectBottomFloor","probeY","probeXs","tallest","stack","cs","measureExplicitAvoidForSide","selectors","side","nodes","node","overlap","useCollisionInsets","insets","setInsets","lastRef","avoidKey","avoidToKey","placement","offsetX","offsetY","measure","xSide","yExtra","xExtra","ro","mo","avoid","STOP_ONLY_EVENTS","useTriggerActivation","pdRef","clickRef","isolateRef","cleanupRef","stopOnly","FloatingTrigger","setTarget","buttonRef","activate","setButton","sideY","sideX","placementBottom","liftPx","hideForKeyboard","useOcclusionWarning","yPx","xPx","concealed","style","warnedRef","t","cx","cy","ourZ","parseZ","candidate","z","n","InlineTrigger","mount","NotchTrigger","onActivatePointerDown","expanded","setExpanded","dragStartRef","className","onPointerCancel","resolveNotchConfig","cfg","resolveKeyboardBehavior","resolveFloatingConfig","VAR_MAP","useApplyTheme","theme","instanceId","useId","attr","slug","previous","setVar","cssVar","PATCH_FLAG","EVENT_NAME","ensureHistoryPatch","dispatch","origPush","origReplace","useHideOn","predicate","setHidden","evaluate","NATIVE_UA_TOKENS","useNativeShell","native","setNative","wk","STORAGE_PREFIX","STORAGE_TTL_MS","useRemoteConfig","apiKey","apiUrl","cached","readCache","triggerEnabled","controller","trigger","parseTrigger","shake","parseShake","brand","parseBrand","writeCache","VALID_PLACEMENTS","VALID_EDGES","HEX6","VALID_MODES","accent","isShakeMessage","nt","createMotionShakeDetector","threshold","neededHits","windowMs","throttleMs","hits","useShakeToOpen","onShake","lastFire","COOLDOWN_MS","fire","detector","onMotion","hasMotion","VIDEO_MAX_SECONDS","hasGetDisplayMedia","LumenProvider","floatingButton","hideOn","record","shakeToOpen","onOpenChange","beforeOpen","onTriggerActivate","suppressTrigger","setIsOpen","isOpening","setIsOpening","setInitialCapture","setInitialCaptureError","isSubmitting","openingRef","triggerPreparedRef","triggerPreparePromiseRef","useMemo","E","Be","onOpenChangeRef","prevIsOpenRef","beforeOpenRef","onTriggerActivateRef","prepareTriggerOpen","recordingBusyRef","screenCaptureBusyRef","close","boundaryKey","setBoundaryKey","resetAfterCrash","recording","setRecording","providerAvailable","setProviderAvailable","activeRecorderRef","providerControlRef","posterRef","pendingVideoRef","recordStartErrorRef","finalizeVideo","rec","fromProvider","probe","ok","handle","bt","stopVideoSession","cancelVideoSession","screenCapture","setScreenCapture","screenSessionRef","pendingScreenshotRef","cancelScreenCaptureSession","grabScreenCaptureFrame","Z","isNativeShell","hideTrigger","remote","brandToTheme","effectiveShake","effectiveTrigger","resolveEffectiveTrigger","report","SdkToaster","shouldRender","setShouldRender","Toaster","FeedbackButton","floating","openCapture","cls"],"mappings":"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","file":"index.cjs","sourcesContent":["export class LumenError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status?: number,\n ) {\n super(message);\n this.name = \"LumenError\";\n }\n}\n\nexport class LumenOriginError extends LumenError {\n constructor() {\n super(\n \"Origin not allowed. Add this origin in your Lumen project settings.\",\n \"ORIGIN_NOT_ALLOWED\",\n 403,\n );\n this.name = \"LumenOriginError\";\n }\n}\n\nexport class LumenRateLimitError extends LumenError {\n constructor(public readonly retryAfter: number) {\n super(\n `Rate limited — retry after ${retryAfter}s.`,\n \"RATE_LIMITED\",\n 429,\n );\n this.name = \"LumenRateLimitError\";\n }\n}\n\nexport class LumenNetworkError extends LumenError {\n constructor(message: string) {\n super(message, \"NETWORK_ERROR\");\n this.name = \"LumenNetworkError\";\n }\n}\n","import type {\n AmplitudeIdentity,\n ClientErrorReport,\n LumenClientConfig,\n LumenUser,\n SubmitOptions,\n SubmitPayload,\n SubmitResult,\n} from \"./types\";\nimport {\n LumenError,\n LumenNetworkError,\n LumenOriginError,\n LumenRateLimitError,\n} from \"./errors\";\n\nconst DEFAULT_API_URL = \"https://shakebugs.vercel.app\";\nconst SUBMIT_PATH = \"/api/v1/sdk/submit\";\nconst ERROR_PATH = \"/api/v1/sdk/error\";\n\n// Kept in sync with @lumen-stack/core's package version at publish time — a\n// coarse signal for which SDK build a crash came from. A patch of drift is\n// harmless; it just narrows \"which release\" in the telemetry.\nconst LUMEN_SDK_VERSION = \"0.13.2\";\n// Hard cap on crash reports per client session, so a render-loop that remounts\n// straight into another crash can't turn the boundary into a beacon flood.\nconst MAX_CLIENT_ERROR_REPORTS = 5;\n\nconst RETRYABLE_STATUSES = new Set([502, 503, 504]);\n\nexport class LumenClient {\n readonly apiKey: string;\n readonly apiUrl: string;\n user: LumenUser | undefined;\n amplitude: AmplitudeIdentity | undefined;\n // Per-session de-dupe + cap for client-error beacons.\n #errorReportKeys = new Set<string>();\n #errorReportCount = 0;\n\n constructor(config: LumenClientConfig) {\n if (!config.apiKey || !config.apiKey.startsWith(\"lk_pub_\")) {\n throw new LumenError(\n \"Invalid Lumen apiKey — expected a key starting with `lk_pub_`.\",\n \"INVALID_API_KEY\",\n );\n }\n this.apiKey = config.apiKey;\n this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, \"\");\n this.user = config.user;\n this.amplitude = config.amplitude;\n }\n\n /**\n * Submit a feedback payload. Uses XHR (not fetch) so we can surface\n * upload-progress events to the UI. Retries up to 2 times on 5xx /\n * network errors with exponential backoff.\n */\n async submit(\n payload: SubmitPayload,\n options: SubmitOptions = {},\n ): Promise<SubmitResult> {\n const url = `${this.apiUrl}${SUBMIT_PATH}`;\n const body = this.#buildFormData(payload);\n\n let lastError: unknown = null;\n for (let attempt = 0; attempt < 3; attempt++) {\n if (attempt > 0) {\n await wait(2 ** attempt * 250);\n }\n try {\n return await this.#sendOnce(url, body, options);\n } catch (e) {\n lastError = e;\n // Don't retry deterministic client errors.\n if (\n e instanceof LumenOriginError ||\n e instanceof LumenRateLimitError\n ) {\n throw e;\n }\n if (\n e instanceof LumenError &&\n typeof e.status === \"number\" &&\n !RETRYABLE_STATUSES.has(e.status)\n ) {\n throw e;\n }\n }\n }\n if (lastError instanceof Error) throw lastError;\n throw new LumenNetworkError(\"Submit failed after 3 attempts.\");\n }\n\n /**\n * Best-effort crash beacon. Called by the React error boundary when the\n * widget's own UI throws during render/commit — the channel that tells us\n * WHY the web widget \"hit a snag\", since the crash itself prevents a normal\n * feedback submission. Never throws, never blocks the page, and is capped +\n * deduped per session. The boundary supplies the error fields; this fills in\n * ambient environment (the memory fields directly test the OOM theory).\n */\n reportClientError(input: ClientErrorReport): void {\n try {\n if (typeof window === \"undefined\") return;\n if (this.#errorReportCount >= MAX_CLIENT_ERROR_REPORTS) return;\n const firstFrame = (input.stack ?? \"\").split(\"\\n\")[1]?.trim() ?? \"\";\n const key = `${input.name}:${input.message}@${firstFrame}`;\n if (this.#errorReportKeys.has(key)) return;\n this.#errorReportKeys.add(key);\n this.#errorReportCount += 1;\n\n const nav = typeof navigator !== \"undefined\" ? navigator : undefined;\n const mem =\n typeof performance !== \"undefined\"\n ? (\n performance as Performance & {\n memory?: { usedJSHeapSize?: number; jsHeapSizeLimit?: number };\n }\n ).memory\n : undefined;\n\n // Origin + path only — never the query/hash, which can carry tokens/PII.\n let url: string | undefined;\n try {\n const u = new URL(window.location.href);\n url = u.origin + u.pathname;\n } catch {\n url = undefined;\n }\n\n const body = {\n message: String(input.message ?? \"\").slice(0, 1000),\n name: String(input.name ?? \"Error\").slice(0, 200),\n stack: input.stack?.slice(0, 8000),\n componentStack: input.componentStack?.slice(0, 8000),\n url,\n userAgent: nav?.userAgent,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n dpr: window.devicePixelRatio,\n deviceMemory: (nav as Navigator & { deviceMemory?: number } | undefined)\n ?.deviceMemory,\n jsHeap: mem\n ? { used: mem.usedJSHeapSize, limit: mem.jsHeapSizeLimit }\n : undefined,\n sdkVersion: LUMEN_SDK_VERSION,\n context: input.context,\n };\n\n void fetch(`${this.apiUrl}${ERROR_PATH}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Lumen-Api-Key\": this.apiKey,\n },\n body: JSON.stringify(body),\n keepalive: true,\n credentials: \"omit\",\n mode: \"cors\",\n }).catch(() => {\n // Swallow — telemetry failure must never surface to the user.\n });\n } catch {\n // Telemetry must never throw back into the error boundary's recovery.\n }\n }\n\n #buildFormData(payload: SubmitPayload): FormData {\n const fd = new FormData();\n if (payload.rawText) fd.append(\"rawText\", payload.rawText);\n if (payload.category) fd.append(\"category\", payload.category);\n if (payload.priority) fd.append(\"priority\", payload.priority);\n if (payload.source) fd.append(\"source\", payload.source);\n if (payload.submitterEmail) fd.append(\"submitterEmail\", payload.submitterEmail);\n if (payload.submitterFingerprint) {\n fd.append(\"submitterFingerprint\", payload.submitterFingerprint);\n }\n // Inject the configured Amplitude identity into the context channel\n // (unless the caller already set one on the payload). These are\n // analytics ids, not PII — the server reads them to pull the user's\n // event timeline during enrichment.\n const amplitude = payload.context.amplitude ?? this.amplitude;\n const context = amplitude\n ? { ...payload.context, amplitude }\n : payload.context;\n fd.append(\"context\", JSON.stringify(context));\n if (payload.screenshot) {\n fd.append(\n \"screenshot\",\n payload.screenshot,\n screenshotFilename(payload.screenshot),\n );\n }\n if (payload.audio) {\n fd.append(\"audio\", payload.audio, \"audio\");\n }\n if (payload.audioDurationMs != null) {\n fd.append(\"audioDurationMs\", String(payload.audioDurationMs));\n }\n if (payload.video) {\n fd.append(\"video\", payload.video, \"video\");\n }\n if (payload.videoDurationMs != null) {\n fd.append(\"videoDurationMs\", String(payload.videoDurationMs));\n }\n // `user` (id/email/name) is intentionally NOT sent. The server has\n // never read these fields, so transmitting them just leaks PII over\n // the wire for no benefit. The `LumenUser` type stays in the public\n // API as a no-op until a future release adds an authenticated\n // identity flow that the server can actually trust.\n return fd;\n }\n\n #sendOnce(\n url: string,\n body: FormData,\n options: SubmitOptions,\n ): Promise<SubmitResult> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open(\"POST\", url, true);\n xhr.setRequestHeader(\"X-Lumen-Api-Key\", this.apiKey);\n xhr.responseType = \"text\";\n\n const { onUploadProgress, signal } = options;\n\n if (onUploadProgress) {\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable && e.total > 0) {\n onUploadProgress(Math.min(1, e.loaded / e.total));\n }\n });\n }\n\n const onAbort = () => {\n xhr.abort();\n reject(new LumenNetworkError(\"Submit aborted.\"));\n };\n if (signal) {\n if (signal.aborted) {\n reject(new LumenNetworkError(\"Submit aborted.\"));\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n xhr.addEventListener(\"load\", () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n\n if (xhr.status === 403) {\n reject(new LumenOriginError());\n return;\n }\n if (xhr.status === 429) {\n const retryAfter = Number(xhr.getResponseHeader(\"Retry-After\")) || 60;\n reject(new LumenRateLimitError(retryAfter));\n return;\n }\n if (xhr.status < 200 || xhr.status >= 300) {\n reject(\n new LumenError(\n parseError(xhr.responseText) ?? `HTTP ${xhr.status}`,\n \"HTTP_ERROR\",\n xhr.status,\n ),\n );\n return;\n }\n try {\n const parsed = JSON.parse(xhr.responseText) as SubmitResult;\n resolve(parsed);\n } catch {\n reject(new LumenError(\"Malformed response from server.\", \"BAD_RESPONSE\"));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n reject(new LumenNetworkError(\"Network error during submit.\"));\n });\n\n xhr.send(body);\n });\n }\n}\n\nfunction screenshotFilename(blob: Blob): string {\n const ext =\n blob.type === \"image/jpeg\"\n ? \"jpg\"\n : blob.type === \"image/webp\"\n ? \"webp\"\n : \"png\";\n return `screenshot.${ext}`;\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nfunction parseError(text: string): string | null {\n try {\n const obj = JSON.parse(text) as { error?: string; message?: string };\n return obj.error ?? obj.message ?? null;\n } catch {\n return text || null;\n }\n}\n","/**\n * Hide Lumen's own UI before a *real-pixel* capture (native screenshot,\n * browser `getDisplayMedia`). Unlike the DOM/html2canvas path — which can\n * skip elements via `data-lumen-capture-ignore` — a real screen grab records\n * whatever is actually painted, so the only way to keep the widget out of the\n * shot is to make it `visibility: hidden` for the duration of the capture.\n */\n\n/** Lumen-owned roots + anything tagged capture-ignore (trigger, sheet, HUDs). */\nexport const DEFAULT_CONCEAL =\n '[data-lumen-root], [data-lumen-capture-ignore=\"true\"]';\n\n/**\n * Hide matching elements via `visibility: hidden`; returns a `restore()` that\n * puts each element's previous inline visibility back. Safe to call with a\n * null selector or outside the browser (returns a no-op restore).\n */\nexport function concealLumenChrome(\n selector: string | null = DEFAULT_CONCEAL,\n): () => void {\n if (!selector || typeof document === \"undefined\") return () => {};\n const hidden: Array<{ el: HTMLElement; prev: string }> = [];\n for (const el of Array.from(\n document.querySelectorAll<HTMLElement>(selector),\n )) {\n hidden.push({ el, prev: el.style.visibility });\n el.style.visibility = \"hidden\";\n }\n return () => {\n for (const { el, prev } of hidden) el.style.visibility = prev;\n };\n}\n","import { concealLumenChrome } from \"./conceal\";\nimport { LumenError } from \"./errors\";\nimport type {\n CaptureResult,\n ScreenshotCaptureOptions,\n} from \"./types\";\n\nconst DEFAULT_MAX_SCALE = 2;\n// Phones (esp. iOS Safari/WKWebView) jettison the page when html2canvas\n// rasterizes a heavy document at full DPR. Clamp the raster scale harder on\n// small touch viewports and never let the output canvas exceed a pixel budget,\n// trading a little sharpness for not crashing.\nconst SMALL_VIEWPORT_MAX_SCALE = 1.5;\nconst SMALL_VIEWPORT_MAX_WIDTH = 820;\nconst MAX_CANVAS_MEGAPIXELS = 12;\nconst MAX_SCREENSHOT_BYTES = 8 * 1024 * 1024;\n\ntype Html2Canvas = typeof import(\"html2canvas-pro\").default;\n\nlet html2canvasForTest: Html2Canvas | null = null;\n\nexport function __setHtml2CanvasForTest(renderer: Html2Canvas | null): void {\n html2canvasForTest = renderer;\n}\n\n/**\n * Capture the visible app screen with method/platform metadata.\n *\n * `mode: \"auto\"` keeps the no-permission DOM path first, then falls\n * back to the browser Screen Capture API if DOM rendering fails.\n * Hosts that need native-quality pixels can pass a custom provider.\n */\nexport async function captureScreen(\n options: ScreenshotCaptureOptions = {},\n): Promise<CaptureResult> {\n assertBrowser();\n\n const mode = options.mode ?? \"auto\";\n\n if (options.provider && (mode === \"auto\" || mode === \"custom\")) {\n try {\n return normalizeProviderResult(await options.provider(), options);\n } catch (e) {\n if (mode === \"custom\") throw e;\n // In auto mode a broken custom provider should not strand web apps.\n options.onWarning?.([\n \"Custom capture provider failed; falling back to browser DOM capture.\",\n ]);\n }\n }\n\n if (mode === \"manual\") {\n throw new LumenError(\n \"Manual screenshot upload is required for this capture mode.\",\n \"MANUAL_CAPTURE_REQUIRED\",\n );\n }\n\n if (mode === \"true-screen\") {\n return captureDisplayMedia(options);\n }\n\n if (mode === \"dom\") {\n return captureDom(options);\n }\n\n if (mode === \"custom\") {\n throw new LumenError(\n \"`capture.provider` is required when capture mode is `custom`.\",\n \"CAPTURE_PROVIDER_REQUIRED\",\n );\n }\n\n try {\n return await captureDom(options);\n } catch (domError) {\n if (canUseDisplayMedia()) {\n const result = await captureDisplayMedia(options);\n result.warnings = uniq([\n \"DOM screenshot failed; used browser screen permission fallback.\",\n ...result.warnings,\n ]);\n options.onWarning?.(result.warnings);\n return result;\n }\n throw domError;\n }\n}\n\n/**\n * Back-compatible wrapper kept for existing integrations.\n * New code should prefer `captureScreen()` so capture quality metadata\n * can be stored with the feedback.\n */\nexport async function captureScreenshot(\n target?: HTMLElement,\n): Promise<Blob> {\n const result = await captureScreen({ target, mode: \"auto\" });\n return result.blob;\n}\n\nexport function createManualCaptureResult(\n blob: Blob,\n warnings: string[] = [],\n): CaptureResult {\n assertBrowser();\n const viewport = currentViewport();\n return {\n blob,\n method: \"manual-upload\",\n platform: \"web\",\n viewport,\n pixelRatio: window.devicePixelRatio ?? 1,\n warnings: uniq(warnings),\n };\n}\n\n// Serializes DOM captures: html2canvas mutates shared cache/clone state and\n// isn't concurrency-safe, and two heavy passes overlapping is exactly what OOMs\n// iOS Safari on a fast open→cancel→reopen. Each call queues behind the previous\n// one (regardless of how the previous settled) so only one pass runs at a time.\nlet domCaptureTail: Promise<unknown> = Promise.resolve();\n\nfunction captureDom(\n options: ScreenshotCaptureOptions,\n): Promise<CaptureResult> {\n const run = domCaptureTail.then(\n () => doCaptureDom(options),\n () => doCaptureDom(options),\n );\n domCaptureTail = run.catch(() => undefined);\n return run;\n}\n\nasync function doCaptureDom(\n options: ScreenshotCaptureOptions,\n): Promise<CaptureResult> {\n const html2canvas = await loadHtml2Canvas();\n\n const target = options.target ?? document.documentElement;\n // Visual viewport = the region the user actually sees (and the crop size).\n const viewport = currentViewport();\n // Layout viewport = where the page lays out (vw/vh, fixed elements). On iOS\n // Safari these diverge; sizing the clone to the layout viewport and offsetting\n // the crop by the visual viewport's position keeps the shot aligned.\n const layout = layoutViewport();\n const visual = window.visualViewport;\n const originX = window.scrollX + (visual?.offsetLeft ?? 0);\n const originY = window.scrollY + (visual?.offsetTop ?? 0);\n const scale = resolveScale(options, viewport.width, viewport.height);\n const warnings = collectDomWarnings(target);\n if (!options.provider && isReactNativeWebView()) {\n // The DOM path is an html2canvas re-render, not a real screen grab: it\n // can't match native rendering and drops native overlays plus the live\n // text a user typed into native inputs. Surface the misconfiguration\n // instead of silently shipping a wrong-looking shot.\n warnings.unshift(\n \"Lumen is capturing inside a React Native WebView with no native capture \" +\n \"provider, so this screenshot is a DOM re-render — it won't match the \" +\n \"native screen and omits native overlays/inputs. Wire \" +\n 'createNativeCaptureProvider() with capture mode \"custom\" (see ' +\n \"docs/native-screenshot-expo.md).\",\n );\n }\n\n // html2canvas renders an <input>'s text from the *cloned* node's `.value`,\n // but cloneNode() copies only the `value` attribute — not the live value a\n // user typed — so typed text reverts to the placeholder. Snapshot live input\n // state now and re-apply it onto the clone in onclone. (Textareas and selects\n // are already handled by html2canvas itself via `clone.value = node.value`.)\n const inputSnapshots = snapshotInputs(target);\n\n // Wait for any in-flight CSS transition/animation (e.g. a host bottom sheet\n // finishing its open animation) to settle so the shot captures the real\n // resting frame, not a mid-animation one.\n await waitForAnimationsToSettle(\n options.awaitAnimationsMs ?? DEFAULT_AWAIT_ANIMATIONS_MS,\n );\n\n // Give the browser a frame to composite and reclaim the previous capture\n // session's canvases/bitmaps before we allocate this one. Without it, a fast\n // open→cancel→reopen stacks two rasterizations and exhausts iOS Safari's\n // memory budget — the white-screen crash.\n await nextFramePause();\n\n const canvas = await html2canvas(target, {\n backgroundColor: null,\n logging: false,\n useCORS: true,\n allowTaint: false,\n width: viewport.width,\n height: viewport.height,\n windowWidth: layout.width,\n windowHeight: layout.height,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n x: originX,\n y: originY,\n scale,\n ignoreElements: (el) =>\n el instanceof HTMLElement &&\n (el.dataset.lumenCaptureIgnore === \"true\" ||\n Boolean(el.closest(\"[data-lumen-capture-ignore='true']\"))),\n onclone: (clonedDoc, clonedRef) => {\n // Order matters: restore live values first, then mask — so any secret is\n // overwritten with bullets before the clone is rasterized.\n applyInputSnapshots(clonedRef, inputSnapshots);\n maskSensitiveFields(clonedDoc);\n },\n });\n\n const blob = await encodeCanvas(canvas, warnings);\n const result = {\n blob,\n method: \"web-dom\",\n platform: \"web\",\n viewport,\n pixelRatio: scale,\n warnings: uniq(warnings),\n } satisfies CaptureResult;\n if (result.warnings.length > 0) options.onWarning?.(result.warnings);\n return result;\n}\n\n/**\n * Selectors whose on-screen values must never end up in a screenshot:\n * password inputs, payment-card and one-time-code fields, and anything\n * the host explicitly tags with `data-lumen-mask`. Runs against the\n * CLONED document html2canvas renders from, so the live page is\n * untouched. (The `true-screen`/native paths rasterize real pixels and\n * cannot be masked — hosts should use `data-lumen-capture-ignore` and\n * this masking via the default DOM mode for sensitive views.)\n */\nconst MASK_SELECTOR = [\n 'input[type=\"password\"]',\n 'input[autocomplete^=\"cc-\"]',\n 'input[autocomplete=\"one-time-code\"]',\n \"[data-lumen-mask]\",\n].join(\", \");\n\nfunction maskSensitiveFields(doc: Document): void {\n for (const el of Array.from(doc.querySelectorAll(MASK_SELECTOR))) {\n // html2canvas renders from a clone living in its own <iframe> realm, so\n // `instanceof HTMLInputElement` (this realm's constructor) is always false\n // there. Branch on nodeName, which is realm-agnostic, so masking actually\n // runs against the rendered clone.\n if (el.nodeName === \"INPUT\" || el.nodeName === \"TEXTAREA\") {\n const field = el as HTMLInputElement | HTMLTextAreaElement;\n if (field.value) field.value = \"••••••••\";\n continue;\n }\n // Any other element: blank the region but keep the layout. html2canvas\n // skips visibility:hidden subtrees, leaving the element's box empty.\n (el as HTMLElement).style.visibility = \"hidden\";\n }\n}\n\n/**\n * Live `<input>` state captured just before html2canvas clones the page, then\n * re-applied onto the cloned inputs in `onclone`. This restores the typed text\n * and checkbox/radio state that `cloneNode()` drops (it copies only the `value`\n * attribute, not an input's live \"dirty\" value), which otherwise makes typed\n * text fall back to the placeholder in the screenshot.\n */\ninterface InputSnapshot {\n /** Sensitive or unsettable inputs are skipped; masking blanks those. */\n skip: boolean;\n value?: string;\n checked?: boolean;\n}\n\n/** Lumen's own UI, excluded so live↔clone input indices stay aligned. */\nconst SYNC_EXCLUDE_SELECTOR =\n \"[data-lumen-root], [data-lumen-capture-ignore='true']\";\n\nfunction collectSyncInputs(root: ParentNode): HTMLInputElement[] {\n return Array.from(root.querySelectorAll<HTMLInputElement>(\"input\")).filter(\n (el) => !el.closest(SYNC_EXCLUDE_SELECTOR),\n );\n}\n\nfunction snapshotInputs(root: ParentNode): InputSnapshot[] {\n return collectSyncInputs(root).map((el) => {\n // Never copy sensitive values into the clone; maskSensitiveFields blanks\n // these instead. Skipping here also avoids relying on cross-realm masking.\n if (el.matches(MASK_SELECTOR)) return { skip: true };\n const type = el.type;\n if (type === \"checkbox\" || type === \"radio\") {\n return { skip: false, checked: el.checked };\n }\n // File inputs can't be assigned programmatically; nothing to restore.\n if (type === \"file\") return { skip: true };\n return { skip: false, value: el.value };\n });\n}\n\nfunction applyInputSnapshots(\n root: ParentNode,\n snapshots: InputSnapshot[],\n): void {\n const inputs = collectSyncInputs(root);\n // Indices only align when the live and cloned input sets match 1:1. If the\n // host mutated the DOM between snapshot and clone, skip rather than risk\n // writing a value into the wrong field.\n if (inputs.length !== snapshots.length) return;\n inputs.forEach((el, i) => {\n const snap = snapshots[i];\n if (!snap || snap.skip) return;\n if (snap.checked !== undefined) el.checked = snap.checked;\n else if (snap.value !== undefined) el.value = snap.value;\n });\n}\n\nfunction isReactNativeWebView(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof (window as unknown as { ReactNativeWebView?: unknown })\n .ReactNativeWebView !== \"undefined\"\n );\n}\n\nasync function loadHtml2Canvas(): Promise<Html2Canvas> {\n if (html2canvasForTest) return html2canvasForTest;\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n return html2canvas;\n}\n\n/**\n * A live `getDisplayMedia` capture held open between the browser surface picker\n * and the actual frame grab. This lets the UI hide its own chrome and let the\n * user arrange/scroll the page before deciding the exact moment to capture —\n * instead of grabbing the first frame the instant the picker resolves.\n */\nexport interface DisplayMediaCaptureSession {\n readonly stream: MediaStream;\n /**\n * Draw the current live frame to a `CaptureResult`. By default it first\n * conceals Lumen's own UI (`visibility: hidden`) and waits for the live\n * stream to reflect that — real screen pixels can't be masked, so this is\n * the only way to keep the widget out of the shot. Pass `{ conceal: false }`\n * for one-shot captures taken when no Lumen UI is on screen.\n */\n grab(options?: { conceal?: boolean }): Promise<CaptureResult>;\n /** Stop all tracks and release the video element. Idempotent. */\n stop(): void;\n /** Register a callback fired when the user ends sharing (\"Stop sharing\"). */\n onEnded(cb: () => void): void;\n}\n\n/**\n * Open a `getDisplayMedia` session and wait for its first frame, but do NOT\n * grab yet — the caller decides when via `session.grab()`. Throws if the\n * picker is dismissed or screen capture is unavailable.\n */\nexport async function startDisplayMediaCapture(\n options: ScreenshotCaptureOptions = {},\n): Promise<DisplayMediaCaptureSession> {\n assertBrowser();\n if (!canUseDisplayMedia()) {\n throw new LumenError(\n \"Browser screen capture is unavailable in this environment.\",\n \"DISPLAY_MEDIA_UNAVAILABLE\",\n );\n }\n\n const stream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: false,\n });\n\n let video: HTMLVideoElement | null = null;\n try {\n video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n video.srcObject = stream;\n await waitForVideoFrame(video);\n } catch (e) {\n for (const track of stream.getTracks()) track.stop();\n throw e;\n }\n\n const liveVideo = video;\n let stopped = false;\n const endedCbs: Array<() => void> = [];\n\n // The user can end sharing from the browser's own UI; surface that as a\n // track 'ended' so the host can tear the session down and reopen the sheet.\n for (const track of stream.getTracks()) {\n track.addEventListener(\"ended\", () => {\n if (!stopped) endedCbs.forEach((cb) => cb());\n });\n }\n\n return {\n stream,\n onEnded(cb) {\n endedCbs.push(cb);\n },\n async grab(grabOptions) {\n const shouldConceal = grabOptions?.conceal ?? true;\n const restore = shouldConceal ? concealLumenChrome() : () => {};\n try {\n // Give the live stream a few frames to reflect the just-concealed UI\n // so the widget's own chrome never lands in the real-pixel shot.\n if (shouldConceal) await waitForFreshFrames(liveVideo, 3, 400);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = liveVideo.videoWidth;\n canvas.height = liveVideo.videoHeight;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new LumenError(\n \"Could not create a drawing context for screen capture.\",\n \"CANVAS_CONTEXT_UNAVAILABLE\",\n );\n }\n ctx.drawImage(liveVideo, 0, 0, canvas.width, canvas.height);\n\n const viewport = currentViewport();\n const warnings = [\n \"Browser screen capture uses the window or tab selected by the user.\",\n ];\n const blob = await encodeCanvas(canvas, warnings);\n const result = {\n blob,\n method: \"web-display-media\",\n platform: \"web\",\n viewport,\n pixelRatio:\n viewport.width > 0 ? canvas.width / viewport.width : undefined,\n warnings: uniq(warnings),\n } satisfies CaptureResult;\n options.onWarning?.(result.warnings);\n return result;\n } finally {\n restore();\n }\n },\n stop() {\n if (stopped) return;\n stopped = true;\n for (const track of stream.getTracks()) track.stop();\n liveVideo.srcObject = null;\n },\n };\n}\n\n/**\n * One-shot screen capture: open a session, grab the first frame, stop. Used by\n * the auto-fallback path (DOM capture failed) where no Lumen UI is on screen,\n * so concealment is unnecessary.\n */\nasync function captureDisplayMedia(\n options: ScreenshotCaptureOptions,\n): Promise<CaptureResult> {\n const session = await startDisplayMediaCapture(options);\n try {\n return await session.grab({ conceal: false });\n } finally {\n session.stop();\n }\n}\n\nfunction normalizeProviderResult(\n result: CaptureResult,\n options: ScreenshotCaptureOptions,\n): CaptureResult {\n const viewport = currentViewport();\n const normalized = {\n ...result,\n method: result.method ?? \"custom\",\n platform: result.platform ?? \"custom\",\n viewport: result.viewport ?? viewport,\n pixelRatio: result.pixelRatio ?? window.devicePixelRatio ?? 1,\n warnings: uniq(result.warnings ?? []),\n } satisfies CaptureResult;\n if (normalized.warnings.length > 0) options.onWarning?.(normalized.warnings);\n return normalized;\n}\n\nfunction collectDomWarnings(target: HTMLElement): string[] {\n const warnings = new Set<string>();\n\n if (target.querySelector(\"iframe\")) {\n warnings.add(\"Embedded iframes may be blank or incomplete in DOM capture.\");\n }\n if (target.querySelector(\"video\")) {\n warnings.add(\"Video frames may be blank or stale in DOM capture.\");\n }\n if (target.querySelector(\"canvas\")) {\n warnings.add(\"Canvas/WebGL content may be blank if it is cross-origin tainted.\");\n }\n if (document.fonts && document.fonts.status !== \"loaded\") {\n warnings.add(\"Web fonts were still loading when the screenshot was captured.\");\n }\n\n let crossOriginImages = 0;\n for (const img of Array.from(target.querySelectorAll(\"img\"))) {\n const src = img.currentSrc || img.src;\n if (!src) continue;\n try {\n const url = new URL(src, window.location.href);\n if (url.origin !== window.location.origin && !img.crossOrigin) {\n crossOriginImages += 1;\n }\n } catch {\n // Invalid image URLs are ignored here; html2canvas will handle them.\n }\n }\n if (crossOriginImages > 0) {\n warnings.add(\n `${crossOriginImages} cross-origin image${crossOriginImages === 1 ? \"\" : \"s\"} without CORS may be omitted from the screenshot.`,\n );\n }\n\n return Array.from(warnings);\n}\n\nasync function encodeCanvas(\n canvas: HTMLCanvasElement,\n warnings: string[],\n): Promise<Blob> {\n let blob = await canvasToBlob(canvas, \"image/png\", 0.92);\n if (blob.size <= MAX_SCREENSHOT_BYTES) return blob;\n\n warnings.push(\"Screenshot exceeded the upload cap and was compressed.\");\n\n // Progressively downscale + re-encode until we're under the cap, or until\n // the image is too small to be useful. Without this loop a very large\n // screenshot from a 4K monitor at 2x DPR could still exceed the cap after\n // a single pass and silently fail to upload server-side.\n let working = canvas;\n let attempt = 0;\n while (blob.size > MAX_SCREENSHOT_BYTES && attempt < 6) {\n const ratio = Math.max(\n 0.35,\n Math.min(0.95, Math.sqrt(MAX_SCREENSHOT_BYTES / blob.size) * 0.9),\n );\n const next = document.createElement(\"canvas\");\n next.width = Math.max(1, Math.round(working.width * ratio));\n next.height = Math.max(1, Math.round(working.height * ratio));\n const ctx = next.getContext(\"2d\");\n if (!ctx) return blob;\n ctx.drawImage(working, 0, 0, next.width, next.height);\n working = next;\n\n for (const quality of [0.86, 0.74, 0.62, 0.5]) {\n blob = await canvasToBlob(working, \"image/jpeg\", quality);\n if (blob.size <= MAX_SCREENSHOT_BYTES) return blob;\n }\n\n attempt += 1;\n if (next.width < 480 || next.height < 320) break;\n }\n\n if (blob.size > MAX_SCREENSHOT_BYTES) {\n warnings.push(\n \"Screenshot remained large after compression; upload may be rejected.\",\n );\n }\n return blob;\n}\n\nfunction canvasToBlob(\n canvas: HTMLCanvasElement,\n type: \"image/png\" | \"image/jpeg\",\n quality: number,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new LumenError(\"Could not encode screenshot.\", \"ENCODE_FAILED\"));\n return;\n }\n resolve(blob);\n },\n type,\n quality,\n );\n });\n}\n\nfunction currentViewport(): { width: number; height: number } {\n const visual = window.visualViewport;\n return {\n width: Math.round(visual?.width ?? window.innerWidth),\n height: Math.round(visual?.height ?? window.innerHeight),\n };\n}\n\n/** Layout viewport — where the page lays out (vw/vh, fixed positioning). */\nfunction layoutViewport(): { width: number; height: number } {\n const doc = document.documentElement;\n return {\n width: Math.round(doc.clientWidth || window.innerWidth),\n height: Math.round(doc.clientHeight || window.innerHeight),\n };\n}\n\n/**\n * Resolve the raster scale: DPR capped by maxScale (default 2), clamped to 1.5×\n * on small touch viewports, and finally bounded so the output canvas never\n * exceeds MAX_CANVAS_MEGAPIXELS however large the page × DPR is.\n */\nfunction resolveScale(\n options: ScreenshotCaptureOptions,\n cropWidth: number,\n cropHeight: number,\n): number {\n const dpr = window.devicePixelRatio ?? 1;\n let max = options.maxScale ?? DEFAULT_MAX_SCALE;\n if (isSmallTouchViewport()) max = Math.min(max, SMALL_VIEWPORT_MAX_SCALE);\n const scale = Math.max(1, Math.min(dpr, max));\n const budgetScale = Math.sqrt(\n (MAX_CANVAS_MEGAPIXELS * 1_000_000) /\n Math.max(1, cropWidth * cropHeight),\n );\n return Math.max(1, Math.min(scale, budgetScale));\n}\n\nfunction isSmallTouchViewport(): boolean {\n const touch =\n (typeof navigator !== \"undefined\" && (navigator.maxTouchPoints ?? 0) > 0) ||\n (typeof window !== \"undefined\" && \"ontouchstart\" in window);\n const layoutW = document.documentElement.clientWidth || window.innerWidth || 0;\n return touch && layoutW > 0 && layoutW <= SMALL_VIEWPORT_MAX_WIDTH;\n}\n\n/**\n * Yield one painted frame (double rAF) so the browser can reclaim memory before\n * the next allocation. Falls back to a short timeout where rAF is unavailable\n * (non-browser test envs).\n */\nfunction nextFramePause(): Promise<void> {\n if (typeof requestAnimationFrame !== \"function\") {\n return new Promise((resolve) => setTimeout(resolve, 32));\n }\n return new Promise((resolve) =>\n requestAnimationFrame(() => requestAnimationFrame(() => resolve())),\n );\n}\n\nconst DEFAULT_AWAIT_ANIMATIONS_MS = 400;\n\n/**\n * Wait (bounded) for in-flight CSS transitions/animations to finish before a\n * snapshot, so capture reflects the settled frame rather than a mid-animation\n * one — the cause of the \"half-dismissed bottom sheet\" screenshot. Looping /\n * infinite animations (spinners) are ignored so they can't stall capture.\n * Always resolves within `maxMs`.\n */\nexport async function waitForAnimationsToSettle(maxMs: number): Promise<void> {\n if (\n typeof document === \"undefined\" ||\n typeof (document as Document).getAnimations !== \"function\" ||\n !(maxMs > 0)\n ) {\n return;\n }\n let animations: Animation[];\n try {\n animations = document.getAnimations();\n } catch {\n return;\n }\n const pending = animations.filter((a) => {\n if (a.playState !== \"running\") return false;\n const timing = a.effect?.getComputedTiming?.();\n // Skip endless loops (spinners, pulsing dots) — they never finish.\n return Boolean(timing) && timing!.iterations !== Infinity;\n });\n if (pending.length === 0) return;\n const settled = Promise.allSettled(pending.map((a) => a.finished)).then(\n () => undefined,\n );\n const cap = new Promise<void>((resolve) => setTimeout(resolve, maxMs));\n await Promise.race([settled, cap]);\n}\n\nfunction canUseDisplayMedia(): boolean {\n return Boolean(navigator.mediaDevices?.getDisplayMedia);\n}\n\nasync function waitForVideoFrame(video: HTMLVideoElement): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const done = () => resolve();\n const fail = () =>\n reject(new LumenError(\"Could not read screen capture video.\", \"VIDEO_FAILED\"));\n video.addEventListener(\"loadedmetadata\", done, { once: true });\n video.addEventListener(\"error\", fail, { once: true });\n void video.play().catch(fail);\n });\n\n // Wait until the browser actually reports a non-zero frame size. We poll\n // via rAF (cheap, paints-aligned) with a hard cap so a stalled stream\n // can't hang the capture flow.\n const start = performance.now();\n const MAX_WAIT_MS = 1500;\n while (video.videoWidth === 0 || video.videoHeight === 0) {\n if (performance.now() - start > MAX_WAIT_MS) {\n throw new LumenError(\n \"Screen capture did not produce a frame in time.\",\n \"VIDEO_TIMEOUT\",\n );\n }\n await new Promise<void>((resolve) =>\n requestAnimationFrame(() => resolve()),\n );\n }\n}\n\n/**\n * Resolve once the live capture stream has presented `minFrames` new frames\n * (so a just-applied DOM change — e.g. concealing Lumen's chrome — is reflected\n * in the pixels we're about to grab), bounded by `maxMs` so a stalled/low-fps\n * stream can never hang the grab. Uses `requestVideoFrameCallback` where\n * available; otherwise falls back to a single bounded delay.\n */\nasync function waitForFreshFrames(\n video: HTMLVideoElement,\n minFrames: number,\n maxMs: number,\n): Promise<void> {\n const rvfc = (\n video as HTMLVideoElement & {\n requestVideoFrameCallback?: (cb: () => void) => number;\n }\n ).requestVideoFrameCallback?.bind(video);\n if (typeof rvfc !== \"function\") {\n await new Promise<void>((resolve) =>\n setTimeout(resolve, Math.min(maxMs, 250)),\n );\n return;\n }\n const start = performance.now();\n let seen = 0;\n await new Promise<void>((resolve) => {\n const tick = () => {\n seen += 1;\n if (seen >= minFrames || performance.now() - start >= maxMs) {\n resolve();\n return;\n }\n rvfc(tick);\n };\n rvfc(tick);\n setTimeout(resolve, maxMs); // hard cap; resolve() is idempotent\n });\n}\n\nfunction assertBrowser(): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new LumenError(\n \"Screenshot capture can only run in the browser.\",\n \"INVALID_ENV\",\n );\n }\n}\n\nfunction uniq(values: string[]): string[] {\n return Array.from(new Set(values.filter(Boolean)));\n}\n","/**\n * Client-side secret scrubbing for captured breadcrumbs and page context.\n *\n * This is the FIRST line of defense: it runs before anything enters the\n * ring buffers, so tokens logged by the host app never leave the page at\n * all. The server applies the same rules again at ingest (defense in\n * depth — a hostile client can skip this file, but honest SDKs shouldn't\n * ship secrets). Mirrors `packages/ai/src/breadcrumbs.ts`; kept as a\n * standalone copy because the published SDK deliberately has no\n * workspace dependencies.\n *\n * Conservative by design: masks obvious credentials and opaque\n * high-entropy tokens, leaves ordinary text intact so the debugging\n * signal survives.\n */\n\n/** Query/body params whose VALUES are credentials/PII and must be masked. */\nconst SENSITIVE_PARAM =\n /^(token|access_token|refresh_token|id_token|api_?key|key|secret|password|passwd|pwd|auth|authorization|sig|signature|session|sessionid|sid|email|jwt)$/i;\n\n/**\n * Fixed-shape secrets that must be masked wherever they appear — even when\n * logged bare (`console.log(token)`), space-separated, or nested in JSON,\n * none of which the `key=value` rule below catches. Each has a distinctive\n * prefix or structure, so false positives on ordinary text are negligible.\n */\nconst KNOWN_SECRET_PATTERNS: readonly RegExp[] = [\n // PEM private key blocks.\n /-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----[\\s\\S]*?-----END (?:[A-Z]+ )?PRIVATE KEY-----/g,\n // JSON Web Tokens (header.payload.signature).\n /\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+/g,\n // AWS access key IDs.\n /\\b(?:AKIA|ASIA|AGPA|AIDA|AROA|ANPA|ANVA|AIPA)[A-Z0-9]{16}\\b/g,\n // GitHub tokens (PAT / OAuth / app / refresh) + fine-grained PATs.\n /\\bgh[posru]_[A-Za-z0-9]{20,}\\b/g,\n /\\bgithub_pat_[A-Za-z0-9_]{20,}\\b/g,\n // GitLab personal access tokens.\n /\\bglpat-[A-Za-z0-9_-]{18,}\\b/g,\n // Slack tokens.\n /\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b/g,\n // Google API keys.\n /\\bAIza[A-Za-z0-9_-]{35}\\b/g,\n // Stripe-style prefixed secret/restricted/publishable keys.\n /\\b[srp]k_(?:live|test)_[A-Za-z0-9]{10,}\\b/g,\n // OpenAI / Anthropic style keys (long, to avoid masking kebab-case text).\n /\\bsk-(?:proj-|ant-)?[A-Za-z0-9_-]{32,}\\b/g,\n];\n\n/** Luhn check so credit-card masking doesn't fire on arbitrary digit runs. */\nfunction isLuhnValid(raw: string): boolean {\n const digits = raw.replace(/\\D/g, \"\");\n if (digits.length < 13 || digits.length > 19) return false;\n let sum = 0;\n let double = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48;\n if (double) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n double = !double;\n }\n return sum % 10 === 0;\n}\n\n/** Best-effort secret scrubbing for an arbitrary log string. */\nexport function redactText(input: string): string {\n let s = input;\n\n // Fixed-shape secrets first — masks bare/JSON-nested tokens the pair rule\n // can't see, and collapses real JWT values to *** before later passes.\n for (const re of KNOWN_SECRET_PATTERNS) s = s.replace(re, \"***\");\n\n // Authorization headers / bearer tokens embedded in messages.\n s = s.replace(/\\b(Bearer|Basic)\\s+[A-Za-z0-9._\\-+/=]+/gi, \"$1 ***\");\n\n // `key=value` / `key: value` / `\"key\":\"value\"` credential pairs in free\n // text, query strings, or JSON (the optional `\"?` after the key matches\n // a quoted JSON property name).\n s = s.replace(\n /\\b([A-Za-z_][\\w-]*)\"?\\s*[=:]\\s*(\"?)([^\"\\s&]{6,})\\2/g,\n (whole, key: string, quote: string, value: string) => {\n // Scheme keyword (e.g. `Authorization: Bearer ***`) — the bearer rule\n // above already masked the real token; don't re-chew the keyword.\n if (/^(Bearer|Basic)$/i.test(value)) return whole;\n if (SENSITIVE_PARAM.test(key)) return `${key}=${quote}***${quote}`;\n // Mask long opaque tokens regardless of key name (JWTs, hex, base64url).\n if (\n value.length >= 24 &&\n /^[A-Za-z0-9._\\-+/=]+$/.test(value) &&\n !value.includes(\" \")\n ) {\n return `${key}=${quote}${value.slice(0, 4)}…${quote}`;\n }\n return whole;\n },\n );\n\n // Credit-card-like digit runs (Luhn-validated) and US SSNs.\n s = s.replace(/\\b\\d(?:[ -]?\\d){12,18}\\b/g, (m) => (isLuhnValid(m) ? \"***\" : m));\n s = s.replace(/\\b\\d{3}-\\d{2}-\\d{4}\\b/g, \"***\");\n\n // Bare email addresses.\n s = s.replace(/\\b[\\w.+-]+@[\\w-]+\\.[\\w.-]+\\b/g, \"***@***\");\n\n return s;\n}\n\n/**\n * Mask credential query params in a URL while keeping it a usable URL\n * (scheme, host, path, and harmless params survive). Falls back to plain\n * text redaction when the input doesn't parse.\n */\nexport function redactUrl(raw: string): string {\n try {\n const u = new URL(raw, \"http://relative.invalid\");\n for (const k of [...u.searchParams.keys()]) {\n if (SENSITIVE_PARAM.test(k)) u.searchParams.set(k, \"***\");\n }\n // URL fragments never reach servers but DO reach our capture — and\n // OAuth implicit flows put access tokens there. Drop them outright.\n u.hash = \"\";\n const out = u.toString();\n // Relative inputs keep their relative form.\n return redactText(\n u.host === \"relative.invalid\"\n ? out.replace(/^http:\\/\\/relative\\.invalid/, \"\")\n : out,\n );\n } catch {\n return redactText(raw);\n }\n}\n\n/**\n * Reduce a page URL to origin + path. Query strings and fragments\n * routinely carry reset tokens, magic-link tokens, and PII — none of\n * which a feedback tool needs to identify the page.\n */\nexport function stripUrlToPath(raw: string): string {\n try {\n const u = new URL(raw);\n return `${u.origin}${u.pathname}`;\n } catch {\n return redactUrl(raw);\n }\n}\n","/**\n * Lightweight runtime capture: console + fetch/XHR ring buffers.\n *\n * Patched lazily on first install; idempotent. The buffers are drained\n * (not cleared) when `readRuntimeCapture()` is called so multiple\n * submissions in one session each get the latest tail.\n *\n * Entries are redacted BEFORE they enter the buffers (see redact.ts):\n * tokens/credentials a host app logs to the console or puts in request\n * URLs never leave the page, rather than being scrubbed server-side\n * after the fact.\n *\n * Keep this file dependency-free and small — it sits on every host\n * page's main bundle.\n */\nimport { redactText, redactUrl } from \"./redact\";\n\nconst MAX_ENTRIES = 200;\nconst MAX_STRING = 4096;\n\ntype ConsoleLevel = \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\";\n\nexport interface ConsoleEntry {\n level: ConsoleLevel;\n ts: number;\n message: string;\n}\n\nexport interface NetworkEntry {\n type: \"fetch\" | \"xhr\";\n method: string;\n url: string;\n status: number;\n ok: boolean;\n durationMs: number;\n ts: number;\n error?: string;\n}\n\nconst consoleBuf: ConsoleEntry[] = [];\nconst networkBuf: NetworkEntry[] = [];\n\nlet installed = false;\nlet ignoreUrlPrefix: string | null = null;\n\nexport interface InstallRuntimeCaptureOptions {\n /**\n * Requests to URLs starting with this prefix are skipped — prevents\n * the SDK from logging its own submit/config calls in a recursive\n * loop and from leaking apiKey headers into the buffer.\n */\n ignoreUrlPrefix?: string;\n}\n\nexport function installRuntimeCapture(\n options: InstallRuntimeCaptureOptions = {},\n): void {\n if (installed) return;\n if (typeof window === \"undefined\") return;\n installed = true;\n ignoreUrlPrefix = options.ignoreUrlPrefix ?? null;\n patchConsole();\n patchFetch();\n patchXhr();\n}\n\nexport function readRuntimeCapture(): {\n consoleLog: ConsoleEntry[];\n networkLog: NetworkEntry[];\n} {\n return {\n consoleLog: consoleBuf.slice(),\n networkLog: networkBuf.slice(),\n };\n}\n\nfunction pushBounded<T>(buf: T[], entry: T): void {\n buf.push(entry);\n if (buf.length > MAX_ENTRIES) buf.splice(0, buf.length - MAX_ENTRIES);\n}\n\nfunction safeStringify(args: unknown[]): string {\n const out: string[] = [];\n for (const arg of args) {\n if (typeof arg === \"string\") {\n out.push(arg);\n continue;\n }\n if (arg instanceof Error) {\n out.push(`${arg.name}: ${arg.message}${arg.stack ? `\\n${arg.stack}` : \"\"}`);\n continue;\n }\n try {\n out.push(JSON.stringify(arg, replacer));\n } catch {\n out.push(String(arg));\n }\n }\n const joined = out.join(\" \");\n return joined.length > MAX_STRING\n ? joined.slice(0, MAX_STRING) + \"…[truncated]\"\n : joined;\n}\n\n// Drops common circular refs (DOM nodes, React fibers) so JSON.stringify\n// doesn't throw and the buffer stays small.\nfunction replacer(_key: string, value: unknown): unknown {\n if (value instanceof Element) return `[Element ${(value as Element).tagName}]`;\n if (typeof value === \"function\") return \"[Function]\";\n return value;\n}\n\nfunction patchConsole(): void {\n const target = window.console;\n if (!target) return;\n const levels: ConsoleLevel[] = [\"log\", \"info\", \"warn\", \"error\", \"debug\"];\n for (const level of levels) {\n const original = target[level]?.bind(target);\n if (!original) continue;\n target[level] = (...args: unknown[]) => {\n try {\n pushBounded(consoleBuf, {\n level,\n ts: Date.now(),\n message: redactText(safeStringify(args)),\n });\n } catch {\n // Never let our interception throw into the host app.\n }\n original(...args);\n };\n }\n}\n\nfunction isIgnored(url: string): boolean {\n if (!ignoreUrlPrefix) return false;\n return url.startsWith(ignoreUrlPrefix);\n}\n\nfunction patchFetch(): void {\n const originalFetch = window.fetch;\n if (typeof originalFetch !== \"function\") return;\n window.fetch = async function patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n const method = (init?.method ?? (input instanceof Request ? input.method : \"GET\")).toUpperCase();\n if (isIgnored(url)) {\n return originalFetch.call(window, input as RequestInfo, init);\n }\n const started = performance.now();\n try {\n const res = await originalFetch.call(window, input as RequestInfo, init);\n pushBounded(networkBuf, {\n type: \"fetch\",\n method,\n url: sanitizeUrl(url),\n status: res.status,\n ok: res.ok,\n durationMs: Math.round(performance.now() - started),\n ts: Date.now(),\n });\n return res;\n } catch (e) {\n pushBounded(networkBuf, {\n type: \"fetch\",\n method,\n url: sanitizeUrl(url),\n status: 0,\n ok: false,\n durationMs: Math.round(performance.now() - started),\n ts: Date.now(),\n error: e instanceof Error ? e.message : \"fetch error\",\n });\n throw e;\n }\n } as typeof window.fetch;\n}\n\nfunction patchXhr(): void {\n const OriginalXHR = window.XMLHttpRequest;\n if (!OriginalXHR) return;\n const originalOpen = OriginalXHR.prototype.open;\n const originalSend = OriginalXHR.prototype.send;\n\n OriginalXHR.prototype.open = function patchedOpen(\n this: XMLHttpRequest & { __lumen?: { method: string; url: string; t: number } },\n method: string,\n url: string | URL,\n ...rest: unknown[]\n ) {\n this.__lumen = {\n method: String(method).toUpperCase(),\n url: typeof url === \"string\" ? url : url.toString(),\n t: 0,\n };\n // @ts-expect-error variadic passthrough\n return originalOpen.call(this, method, url, ...rest);\n } as typeof OriginalXHR.prototype.open;\n\n OriginalXHR.prototype.send = function patchedSend(\n this: XMLHttpRequest & { __lumen?: { method: string; url: string; t: number } },\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n const meta = this.__lumen;\n if (meta && !isIgnored(meta.url)) {\n meta.t = performance.now();\n const onDone = () => {\n try {\n pushBounded(networkBuf, {\n type: \"xhr\",\n method: meta.method,\n url: sanitizeUrl(meta.url),\n status: this.status,\n ok: this.status >= 200 && this.status < 400,\n durationMs: Math.round(performance.now() - meta.t),\n ts: Date.now(),\n });\n } catch {\n // ignore\n }\n this.removeEventListener(\"loadend\", onDone);\n };\n this.addEventListener(\"loadend\", onDone);\n }\n return originalSend.call(this, body ?? null);\n } as typeof OriginalXHR.prototype.send;\n}\n\nfunction truncate(s: string): string {\n return s.length > 512 ? s.slice(0, 512) + \"…\" : s;\n}\n\n/** Redact-then-truncate for captured request URLs. */\nfunction sanitizeUrl(url: string): string {\n return truncate(redactUrl(url));\n}\n","import { readRuntimeCapture } from \"./capture-runtime\";\nimport { stripUrlToPath } from \"./redact\";\nimport type {\n CapturedContext,\n CaptureMetadata,\n CaptureResult,\n DeviceContext,\n} from \"./types\";\n\n/**\n * Snapshot of basic page context at submit-time.\n *\n * Console + network logs are sourced from the runtime ring buffer when\n * `installRuntimeCapture()` has been called by the host (the React\n * provider does this on mount). When the host hasn't installed\n * interception the buffer is empty and the legacy `[]` is sent — same\n * shape, no migration impact.\n */\nexport function captureContext(\n capture?: CaptureResult | CaptureMetadata,\n): CapturedContext {\n if (typeof window === \"undefined\") {\n return {\n url: \"\",\n userAgent: \"\",\n viewport: { width: 0, height: 0 },\n capture: toCaptureMetadata(capture),\n consoleLog: [],\n networkLog: [],\n };\n }\n\n const runtime = readRuntimeCapture();\n return {\n // Origin + path only. Query strings and fragments routinely carry\n // reset tokens, magic links, and PII — none needed to identify the\n // page a report came from.\n url: stripUrlToPath(window.location.href),\n userAgent: navigator.userAgent,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n capture: toCaptureMetadata(capture),\n device: snapshotDevice(),\n consoleLog: runtime.consoleLog,\n networkLog: runtime.networkLog,\n };\n}\n\nfunction snapshotDevice(): DeviceContext {\n const device: DeviceContext = {};\n try {\n device.screen = {\n width: window.screen?.width ?? 0,\n height: window.screen?.height ?? 0,\n };\n device.pixelRatio = window.devicePixelRatio ?? 1;\n device.language = navigator.language;\n device.languages = Array.from(navigator.languages ?? []);\n device.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n device.colorScheme = window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n device.referrer = document.referrer\n ? stripUrlToPath(document.referrer)\n : undefined;\n device.title = document.title || undefined;\n device.online = navigator.onLine;\n const nav = performance.getEntriesByType(\"navigation\")[0] as\n | PerformanceNavigationTiming\n | undefined;\n if (nav) {\n device.uptimeMs = Math.round(performance.now());\n }\n } catch {\n // Best-effort snapshot — don't block submit on a missing API.\n }\n return device;\n}\n\nfunction toCaptureMetadata(\n capture?: CaptureResult | CaptureMetadata,\n): CaptureMetadata | undefined {\n if (!capture) return undefined;\n return {\n method: capture.method,\n platform: capture.platform,\n viewport: capture.viewport,\n pixelRatio: capture.pixelRatio,\n warnings: capture.warnings,\n };\n}\n","const LUMEN_ROOT_SELECTOR = \"[data-lumen-root]\";\nconst LUMEN_MARKER_SELECTOR =\n \"[data-lumen-root], [data-lumen-trigger], [data-lumen-capture-ignore='true']\";\n\n/**\n * Public DOM contract for host overlay outside-click handlers.\n *\n * Lumen mounts its owned UI under a stable `[data-lumen-root]` host when using\n * the framework-agnostic mount. React trigger elements also carry stable Lumen\n * markers. Use this helper from document-level pointer/click handlers to keep\n * host sheets or modals open when the user activates Lumen.\n */\nexport function isLumenEventTarget(event: Event): boolean {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n\n for (const entry of path) {\n if (isLumenNode(entry)) return true;\n }\n\n return isLumenNode(event.target);\n}\n\n/**\n * Pointer/click event types a host overlay's outside-click listener typically\n * reacts to. Stopping their bubble-phase propagation keeps a tap on Lumen-owned\n * UI from reading as an outside-click in the host's sheet/dialog layer.\n */\nconst ISOLATED_EVENT_TYPES = [\n \"pointerdown\",\n \"mousedown\",\n \"touchstart\",\n \"click\",\n] as const;\n\n/**\n * Make a Lumen-owned element a good citizen inside host overlays: stop its own\n * pointer/click events from bubbling into host document-level outside-click\n * handlers (Silk / Vaul / Radix dismissable layers). Bubble-phase only — hosts\n * that listen in the *capture* phase should additionally guard with\n * {@link isLumenEventTarget}. Returns a cleanup function.\n *\n * Safe for all-native subtrees (the framework-agnostic mount). React widgets\n * must instead bind their activation handlers natively (see the React SDK's\n * `useTriggerActivation`) because React 18 delegates events at the tree root, so\n * a `stopPropagation` from a synthetic handler runs *after* the host already saw\n * the event.\n */\nexport function isolateLumenEvents(el: Element): () => void {\n if (!el || typeof el.addEventListener !== \"function\") return () => {};\n const stop = (event: Event) => event.stopPropagation();\n for (const type of ISOLATED_EVENT_TYPES) {\n el.addEventListener(\n type,\n stop,\n type === \"touchstart\" ? { passive: true } : undefined,\n );\n }\n return () => {\n for (const type of ISOLATED_EVENT_TYPES) {\n el.removeEventListener(type, stop);\n }\n };\n}\n\nfunction isLumenNode(value: unknown): boolean {\n if (!value) return false;\n\n if (typeof Element !== \"undefined\" && value instanceof Element) {\n if (value.matches(LUMEN_MARKER_SELECTOR)) return true;\n return Boolean(value.closest(LUMEN_ROOT_SELECTOR));\n }\n\n if (typeof ShadowRoot !== \"undefined\" && value instanceof ShadowRoot) {\n return isLumenNode(value.host);\n }\n\n return false;\n}\n","import { waitForAnimationsToSettle } from \"./capture-screenshot\";\nimport { concealLumenChrome, DEFAULT_CONCEAL } from \"./conceal\";\nimport { LumenError } from \"./errors\";\nimport type {\n CaptureMethod,\n CaptureResult,\n CapturePlatform,\n ScreenshotCaptureProvider,\n} from \"./types\";\n\n/**\n * Native-screenshot bridge for WebView hosts (Expo / react-native-webview,\n * Capacitor, …).\n *\n * The browser DOM renderer (`html2canvas`) only rasterizes what lives in the\n * DOM, so anything the native layer draws — native overlays, modals, tab\n * bars, the OS status bar — never shows up. To get a pixel-accurate shot of\n * what the user actually sees, capture has to happen on the native side\n * (e.g. `react-native-view-shot`).\n *\n * This helper builds a `ScreenshotCaptureProvider` you can pass straight into\n * `<LumenProvider capture={{ mode: \"custom\", provider }}>`. When Lumen needs a\n * screenshot it:\n * 1. requests the native host to capture after screen updates; if this is a\n * recapture while Lumen UI is already open, the provider also conceals\n * `[data-lumen-root]` / `data-lumen-capture-ignore` before the request,\n * 2. posts a `lumen:capture-request` message to the native host,\n * 3. waits for the host to send back a PNG/JPEG data URL,\n * 4. restores the sheet and resolves with a native `CaptureResult`.\n *\n * On the native side, respond by injecting JS that calls\n * `window.__lumenNativeCapture.resolve(id, dataUrl)` (or post a\n * `{ type: \"lumen:capture-response\", id, dataUrl }` message back into the\n * WebView). See the package README for a full Expo example.\n */\nexport interface NativeCaptureProviderOptions {\n /** Recorded in the submission metadata. Defaults to platform autodetection. */\n platform?: Extract<CapturePlatform, \"ios\" | \"android\">;\n /** Give up after this long if the native host never answers. Default 8000ms. */\n timeoutMs?: number;\n /**\n * How to deliver the capture request to the native host. Defaults to\n * `window.ReactNativeWebView.postMessage(JSON.stringify(request))`, which is\n * what react-native-webview exposes. Override for Capacitor / custom shells.\n */\n send?: (request: NativeCaptureRequest) => void;\n /**\n * CSS selector for elements to hide while the native shot is taken. Defaults\n * to the Lumen root and sheet markers so the feedback UI stays out of the\n * screenshot during recapture/legacy submit-time captures.\n * Pass `null` to disable hiding entirely.\n */\n concealSelector?: string | null;\n /**\n * Extra delay after concealment before `send` fires. Native iOS hosts should\n * still snapshot with `afterScreenUpdates: true`; this delay gives the\n * WebView compositor a chance to flush hidden DOM state first.\n */\n captureSettleMs?: number;\n /**\n * Before requesting the native shot, wait up to this many ms for in-flight\n * CSS transitions/animations (e.g. a host bottom sheet finishing its open\n * animation) to settle, so the screenshot reflects the resting frame.\n * Looping animations are ignored. Default 400ms; set to 0 to disable.\n */\n awaitAnimationsMs?: number;\n}\n\nexport interface NativeCaptureRequest {\n type: \"lumen:capture-request\";\n /** Correlates the response with this request. */\n id: string;\n /**\n * Native hosts should honor this by capturing after pending screen updates\n * have committed, e.g. `drawHierarchy(..., afterScreenUpdates: true)` on iOS.\n */\n afterScreenUpdates: true;\n}\n\n/**\n * Message a native host posts into the WebView to open the Lumen sheet when\n * it detects a device shake. Deliver it the same way as any other bridge\n * message — `window.ReactNativeWebView` round-trips it back via the WebView's\n * `onMessage`, or inject `window.dispatchEvent(new MessageEvent(\"message\", …))`.\n * The React SDK listens for it when shake-to-open is enabled.\n */\nexport const LUMEN_SHAKE_MESSAGE = \"lumen:shake\";\n\nexport interface ShakeMessage {\n type: typeof LUMEN_SHAKE_MESSAGE;\n}\n\nexport interface NativeCaptureResponse {\n type: \"lumen:capture-response\";\n id: string;\n /** A `data:image/png;base64,…` (or jpeg/webp) URL of the captured screen. */\n dataUrl?: string;\n /** Set instead of `dataUrl` when the native capture failed. */\n error?: string;\n /** Optional device pixel ratio so metadata matches the native render. */\n pixelRatio?: number;\n}\n\ninterface PendingCapture {\n resolve: (response: NativeCaptureResponse) => void;\n reject: (error: Error) => void;\n}\n\ninterface NativeCaptureRegistry {\n pending: Map<string, PendingCapture>;\n /** Called by the native host (via injected JS) to deliver a result. */\n resolve: (id: string, dataUrl: string, pixelRatio?: number) => void;\n /** Called by the native host to report a capture failure. */\n reject: (id: string, error?: string) => void;\n}\n\ndeclare global {\n interface Window {\n __lumenNativeCapture?: NativeCaptureRegistry;\n ReactNativeWebView?: { postMessage: (msg: string) => void };\n }\n}\n\nconst DEFAULT_TIMEOUT_MS = 8000;\nconst DEFAULT_CAPTURE_SETTLE_MS = 50;\nconst DEFAULT_AWAIT_ANIMATIONS_MS = 400;\n\n/**\n * Build a native-screenshot provider for a WebView host. Safe to call at\n * module scope; the registry + message listener install lazily on first use.\n */\nexport function createNativeCaptureProvider(\n options: NativeCaptureProviderOptions = {},\n): ScreenshotCaptureProvider {\n return async function nativeCaptureProvider(): Promise<CaptureResult> {\n if (typeof window === \"undefined\") {\n throw new LumenError(\n \"Native capture bridge requires a WebView/browser window.\",\n \"INVALID_ENV\",\n );\n }\n\n const registry = ensureRegistry();\n const send = options.send ?? defaultSend;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const captureSettleMs =\n options.captureSettleMs ?? DEFAULT_CAPTURE_SETTLE_MS;\n const awaitAnimationsMs =\n options.awaitAnimationsMs ?? DEFAULT_AWAIT_ANIMATIONS_MS;\n const id = newRequestId();\n\n const restore = concealLumenChrome(\n options.concealSelector === undefined\n ? DEFAULT_CONCEAL\n : options.concealSelector,\n );\n try {\n await settleAfterConceal(captureSettleMs, awaitAnimationsMs);\n\n const response = await new Promise<NativeCaptureResponse>(\n (resolve, reject) => {\n const timer = window.setTimeout(() => {\n registry.pending.delete(id);\n reject(\n new LumenError(\n \"Native screenshot timed out; the host did not respond.\",\n \"NATIVE_CAPTURE_TIMEOUT\",\n ),\n );\n }, timeoutMs);\n\n registry.pending.set(id, {\n resolve: (r) => {\n window.clearTimeout(timer);\n resolve(r);\n },\n reject: (e) => {\n window.clearTimeout(timer);\n reject(e);\n },\n });\n\n try {\n send({ type: \"lumen:capture-request\", id, afterScreenUpdates: true });\n } catch (e) {\n registry.pending.delete(id);\n window.clearTimeout(timer);\n reject(\n new LumenError(\n \"Could not reach the native host for screen capture.\",\n \"NATIVE_CAPTURE_UNAVAILABLE\",\n ),\n );\n void e;\n }\n },\n );\n\n if (response.error || !response.dataUrl) {\n throw new LumenError(\n response.error ?? \"Native screenshot returned no image.\",\n \"NATIVE_CAPTURE_FAILED\",\n );\n }\n\n const blob = dataUrlToBlob(response.dataUrl);\n const platform = options.platform ?? detectPlatform();\n const method: CaptureMethod =\n platform === \"android\" ? \"android-native\" : \"ios-native\";\n\n return {\n blob,\n method,\n platform,\n viewport: {\n width: Math.round(window.innerWidth),\n height: Math.round(window.innerHeight),\n },\n pixelRatio: response.pixelRatio ?? window.devicePixelRatio ?? 1,\n warnings: [],\n } satisfies CaptureResult;\n } finally {\n restore();\n }\n };\n}\n\n/** Default transport: react-native-webview's postMessage channel. */\nfunction defaultSend(request: NativeCaptureRequest): void {\n const rn = window.ReactNativeWebView;\n if (!rn?.postMessage) {\n throw new LumenError(\n \"window.ReactNativeWebView is unavailable; pass a custom `send`.\",\n \"NATIVE_CAPTURE_UNAVAILABLE\",\n );\n }\n rn.postMessage(JSON.stringify(request));\n}\n\nfunction ensureRegistry(): NativeCaptureRegistry {\n if (window.__lumenNativeCapture) return window.__lumenNativeCapture;\n\n const registry: NativeCaptureRegistry = {\n pending: new Map(),\n resolve(id, dataUrl, pixelRatio) {\n const entry = registry.pending.get(id);\n if (!entry) return;\n registry.pending.delete(id);\n entry.resolve({ type: \"lumen:capture-response\", id, dataUrl, pixelRatio });\n },\n reject(id, error) {\n const entry = registry.pending.get(id);\n if (!entry) return;\n registry.pending.delete(id);\n entry.resolve({ type: \"lumen:capture-response\", id, error });\n },\n };\n\n // Hosts that prefer postMessage (instead of injected JS) can post a\n // capture-response back into the WebView; accept it on window and document.\n const onMessage = (event: MessageEvent) => {\n const data = parseMessage(event.data);\n if (!data || data.type !== \"lumen:capture-response\") return;\n const entry = registry.pending.get(data.id);\n if (!entry) return;\n registry.pending.delete(data.id);\n entry.resolve(data);\n };\n window.addEventListener(\"message\", onMessage);\n document.addEventListener(\"message\", onMessage as EventListener);\n\n window.__lumenNativeCapture = registry;\n return registry;\n}\n\nfunction parseMessage(data: unknown): NativeCaptureResponse | null {\n if (data && typeof data === \"object\" && \"type\" in data) {\n return data as NativeCaptureResponse;\n }\n if (typeof data === \"string\") {\n try {\n const parsed = JSON.parse(data);\n if (parsed && typeof parsed === \"object\" && parsed.type) return parsed;\n } catch {\n // Not a Lumen message — ignore.\n }\n }\n return null;\n}\n\nasync function settleAfterConceal(\n captureSettleMs: number,\n awaitAnimationsMs: number,\n): Promise<void> {\n // Let any in-flight host transition (bottom sheet open/close) finish first so\n // the native shot reflects the settled frame, not a mid-animation one.\n await waitForAnimationsToSettle(awaitAnimationsMs);\n await nextAnimationFrame();\n if (captureSettleMs > 0) {\n await new Promise((resolve) => window.setTimeout(resolve, captureSettleMs));\n }\n}\n\nfunction nextAnimationFrame(): Promise<void> {\n return new Promise((resolve) => {\n requestAnimationFrame(() => resolve());\n });\n}\n\nfunction detectPlatform(): \"ios\" | \"android\" {\n const ua = navigator.userAgent || \"\";\n return /android/i.test(ua) ? \"android\" : \"ios\";\n}\n\nfunction newRequestId(): string {\n const rand =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : Math.random().toString(36).slice(2);\n return `lumen-cap-${rand}`;\n}\n\n/** Decode a data: URL into a Blob without relying on fetch() (some old\n * WebViews block fetch on data: URIs). */\nfunction dataUrlToBlob(dataUrl: string): Blob {\n const match = /^data:([^;,]*)(;base64)?,(.*)$/s.exec(dataUrl);\n if (!match) {\n throw new LumenError(\n \"Native host returned an invalid image data URL.\",\n \"NATIVE_CAPTURE_FAILED\",\n );\n }\n const mime = match[1] || \"image/png\";\n const isBase64 = Boolean(match[2]);\n const data = match[3] ?? \"\";\n\n if (!isBase64) {\n return new Blob([decodeURIComponent(data)], { type: mime });\n }\n\n const binary = atob(data);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return new Blob([bytes], { type: mime });\n}\n","/**\n * Soft-keyboard inset bridge.\n *\n * In an iOS WKWebView (`react-native-webview`) `window.visualViewport` does NOT\n * shrink when the keyboard opens, so the widget can't measure the keyboard from\n * inside the page. A native shell can instead push the keyboard height in here;\n * the React SDK's `useKeyboardInset` reads it (and the `--lumen-keyboard-inset`\n * CSS var) and lifts the trigger + modal input above the keyboard.\n *\n * Call from injected JS in your WebView host, e.g. on RN `Keyboard` events:\n * `window.dispatchEvent` is fired for you so the widget updates immediately.\n * `@lumen-stack/expo`'s `LumenWebView` wires this automatically.\n */\nexport const LUMEN_KEYBOARD_EVENT = \"lumen:keyboardchange\";\n\nexport const LUMEN_KEYBOARD_CSS_VAR = \"--lumen-keyboard-inset\";\n\ndeclare global {\n interface Window {\n __lumenKeyboardInset?: number;\n }\n}\n\n/**\n * Set the current soft-keyboard inset (CSS px from the bottom of the viewport)\n * and notify the widget. Pass 0 (or a negative/NaN value) when the keyboard\n * closes. Mirrors the value onto the `--lumen-keyboard-inset` CSS var on\n * `<html>` so CSS-only hosts can read it too.\n */\nexport function setLumenKeyboardInset(insetPx: number): void {\n if (typeof window === \"undefined\") return;\n const px =\n typeof insetPx === \"number\" && Number.isFinite(insetPx) && insetPx > 0\n ? Math.round(insetPx)\n : 0;\n window.__lumenKeyboardInset = px;\n if (typeof document !== \"undefined\") {\n document.documentElement.style.setProperty(\n LUMEN_KEYBOARD_CSS_VAR,\n `${px}px`,\n );\n }\n window.dispatchEvent(new Event(LUMEN_KEYBOARD_EVENT));\n}\n\n/**\n * Read the injected keyboard inset (window global first, then the CSS var).\n * Returns `null` when no host has provided one, so callers can fall back to\n * `visualViewport`. Never negative.\n */\nexport function readLumenKeyboardInset(): number | null {\n if (typeof window === \"undefined\") return null;\n const g = window.__lumenKeyboardInset;\n if (typeof g === \"number\" && Number.isFinite(g) && g >= 0) return g;\n if (typeof document !== \"undefined\" && typeof getComputedStyle === \"function\") {\n const raw = getComputedStyle(document.documentElement)\n .getPropertyValue(LUMEN_KEYBOARD_CSS_VAR)\n .trim();\n if (raw) {\n const n = parseFloat(raw);\n if (Number.isFinite(n) && n >= 0) return n;\n }\n }\n return null;\n}\n","import { LumenError } from \"./errors\";\n\nexport interface AudioRecording {\n blob: Blob;\n durationMs: number;\n mimeType: string;\n}\n\nexport interface RecorderHandle {\n /**\n * Stop recording and resolve with the recorded blob. Safe to call after\n * the max-duration auto-stop already fired — the result promise is shared,\n * so the take is delivered instead of lost.\n */\n stop: () => Promise<AudioRecording>;\n /** Cancel without producing a blob; releases the mic immediately. */\n cancel: () => void;\n /** Stream object (use to render a live waveform in Phase 2). */\n stream: MediaStream;\n}\n\n/**\n * Start a MediaRecorder. Caller is responsible for stopping/canceling.\n * Auto-stops after `maxSeconds` seconds to avoid runaway recordings.\n *\n * Single-funnel design (mirrors record-video.ts): every termination path —\n * consumer `stop()`, the auto-stop timeout, `cancel()` — lands in the one\n * `stop`-event handler registered at creation. That handler settles the\n * shared result promise and releases the mic tracks, so a consumer `stop()`\n * racing the auto-stop can never lose the recording, and the auto-stop can\n * never leave the mic live.\n */\nexport async function recordAudio(\n maxSeconds = 60,\n): Promise<RecorderHandle> {\n if (typeof window === \"undefined\" || !navigator.mediaDevices) {\n throw new LumenError(\n \"Audio recording requires a browser with MediaDevices.\",\n \"INVALID_ENV\",\n );\n }\n\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch {\n throw new LumenError(\n \"Microphone access denied or unavailable.\",\n \"MIC_DENIED\",\n );\n }\n\n // Pick the first MIME type supported by the browser; webm/opus on\n // Chromium, mp4/aac on Safari, ogg on Firefox.\n const candidates = [\n \"audio/webm;codecs=opus\",\n \"audio/webm\",\n \"audio/mp4\",\n \"audio/ogg;codecs=opus\",\n ];\n const mimeType =\n candidates.find((m) => MediaRecorder.isTypeSupported(m)) ?? \"\";\n\n const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);\n const chunks: Blob[] = [];\n const start = performance.now();\n let timeoutId: number | null = null;\n let cancelled = false;\n let settled = false;\n\n let resolveResult!: (recording: AudioRecording) => void;\n let rejectResult!: (reason: unknown) => void;\n const result = new Promise<AudioRecording>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n // A cancel() without a matching stop() leaves the rejection unobserved.\n result.catch(() => {});\n\n recorder.addEventListener(\"dataavailable\", (e) => {\n if (e.data && e.data.size > 0) chunks.push(e.data);\n });\n\n recorder.addEventListener(\"stop\", () => {\n if (timeoutId !== null) window.clearTimeout(timeoutId);\n timeoutId = null;\n for (const track of stream.getTracks()) track.stop();\n if (settled) return;\n settled = true;\n if (cancelled) {\n rejectResult(\n new LumenError(\"Recording cancelled.\", \"RECORDER_STOPPED\"),\n );\n return;\n }\n const durationMs = performance.now() - start;\n const finalType = recorder.mimeType || mimeType || \"audio/webm\";\n const blob = new Blob(chunks, { type: finalType });\n resolveResult({ blob, durationMs, mimeType: finalType });\n });\n\n recorder.start();\n timeoutId = window.setTimeout(() => {\n if (recorder.state !== \"inactive\") recorder.stop();\n }, maxSeconds * 1000);\n\n function requestStop() {\n if (recorder.state === \"inactive\") return;\n try {\n recorder.stop();\n } catch {\n /* ignore — stop on a closing recorder can throw on some engines */\n }\n }\n\n return {\n stream,\n cancel() {\n cancelled = true;\n requestStop();\n // If the recorder already stopped (auto-stop fired), the stop handler\n // has run; make doubly sure nothing keeps the mic indicator alive.\n if (timeoutId !== null) window.clearTimeout(timeoutId);\n timeoutId = null;\n for (const track of stream.getTracks()) track.stop();\n },\n stop(): Promise<AudioRecording> {\n requestStop();\n return result;\n },\n };\n}\n","import { LumenError } from \"./errors\";\n\n/**\n * A finished screen recording. `mimeType` is `video/webm` (or `video/mp4`)\n * from the browser `getDisplayMedia` path, and whatever a custom/native host\n * produces — e.g. `video/mp4` from an iOS ReplayKit host.\n */\nexport interface LumenRecordingResult {\n blob: Blob;\n durationMs: number;\n mimeType: string;\n}\n\n/** Back-compat alias for the original name; identical shape. */\nexport type VideoRecording = LumenRecordingResult;\n\n/**\n * A live recording the widget can stop/cancel and await. Both the built-in\n * browser recorder ({@link VideoRecorderHandle}) and custom {@link\n * LumenRecordProvider}s return this shape. The widget relies ONLY on\n * `result`/`stop`/`cancel`; `stream` is optional (native hosts omit it).\n */\nexport interface LumenRecordingSession {\n /** Resolves with the finished clip; rejects with `LumenError(\"RECORDER_STOPPED\")` when cancelled. */\n result: Promise<LumenRecordingResult>;\n /** Ask the recorder to stop; the clip then arrives via `result`. */\n stop(): void;\n /** Abort and discard the recording. */\n cancel(): void;\n /** Only present for browser getDisplayMedia recordings. Custom providers may omit it. */\n stream?: MediaStream;\n}\n\n/**\n * A factory the host wires into `<LumenProvider record={{ provider }}>` to\n * delegate screen recording to a native/custom recorder (e.g. an iOS WebView\n * host using ReplayKit over its postMessage bridge), mirroring the\n * `capture.provider` extension point for screenshots. Called from the user's\n * tap on the Record button, after the Lumen sheet has been closed.\n */\nexport type LumenRecordProvider = (options: {\n maxDurationSeconds: number;\n}) => Promise<LumenRecordingSession> | LumenRecordingSession;\n\nexport interface VideoRecorderHandle {\n /**\n * Request a stop (idempotent). The recording is delivered via {@link result},\n * NOT a return value — so whoever stops it (your button, the browser's \"Stop\n * sharing\", or the max-duration cap) all funnel through the same place.\n */\n stop: () => void;\n /** Cancel without producing a usable recording; releases the capture. */\n cancel: () => void;\n /** The screen-capture stream (use to render a live preview / poster). */\n stream: MediaStream;\n /**\n * Resolves exactly once when recording stops for ANY reason — your `stop()`,\n * the browser's own \"Stop sharing\" control, or the `maxSeconds` cap. Rejects\n * only if cancelled. Await this to get the blob.\n */\n result: Promise<LumenRecordingResult>;\n}\n\n/**\n * Record the screen via the browser Screen Capture API + MediaRecorder.\n * The user picks a tab / window / screen in the browser's native picker; if\n * they cancel the picker this rejects with `SCREEN_DENIED`.\n *\n * The recording is delivered through {@link VideoRecorderHandle.result}, which\n * resolves no matter how the capture ends — a single funnel for the three stop\n * paths (manual `stop()`, the browser's \"Stop sharing\" bar, and the\n * `maxSeconds` auto-stop). This is the key correctness property: earlier the\n * blob was only delivered if the consumer happened to win the race to call\n * stop(), so a browser-initiated stop or the timeout could drop the take.\n */\nexport async function recordVideo(\n maxSeconds = 60,\n): Promise<VideoRecorderHandle> {\n if (\n typeof window === \"undefined\" ||\n !navigator.mediaDevices ||\n typeof navigator.mediaDevices.getDisplayMedia !== \"function\"\n ) {\n throw new LumenError(\n \"Screen recording requires a browser with getDisplayMedia.\",\n \"INVALID_ENV\",\n );\n }\n\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n // Capture system/tab audio when the user opts in via the picker.\n audio: true,\n });\n } catch {\n throw new LumenError(\n \"Screen capture was denied or cancelled.\",\n \"SCREEN_DENIED\",\n );\n }\n\n // VP9/VP8 webm on Chromium; mp4 on Safari.\n const candidates = [\n \"video/webm;codecs=vp9,opus\",\n \"video/webm;codecs=vp8,opus\",\n \"video/webm\",\n \"video/mp4\",\n ];\n const mimeType =\n candidates.find((m) => MediaRecorder.isTypeSupported(m)) ?? \"\";\n\n const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);\n const chunks: Blob[] = [];\n const start = performance.now();\n let timeoutId: number | null = null;\n let settled = false;\n let cancelled = false;\n\n let resolveResult!: (rec: VideoRecording) => void;\n let rejectResult!: (err: Error) => void;\n const result = new Promise<VideoRecording>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n // Avoid an unhandled-rejection warning if a caller cancels without awaiting.\n result.catch(() => undefined);\n\n function release() {\n if (timeoutId !== null) {\n window.clearTimeout(timeoutId);\n timeoutId = null;\n }\n for (const track of stream.getTracks()) track.stop();\n }\n\n recorder.addEventListener(\"dataavailable\", (e) => {\n if (e.data && e.data.size > 0) chunks.push(e.data);\n });\n\n // Single funnel: whatever stops the recorder ends up here exactly once.\n recorder.addEventListener(\"stop\", () => {\n if (settled) return;\n settled = true;\n release();\n if (cancelled) {\n rejectResult(new LumenError(\"Recording cancelled.\", \"RECORDER_STOPPED\"));\n return;\n }\n const finalType = recorder.mimeType || mimeType || \"video/webm\";\n resolveResult({\n blob: new Blob(chunks, { type: finalType }),\n durationMs: performance.now() - start,\n mimeType: finalType,\n });\n });\n\n function requestStop() {\n if (recorder.state !== \"inactive\") recorder.stop();\n }\n\n recorder.start();\n timeoutId = window.setTimeout(requestStop, maxSeconds * 1000);\n\n // The user can end the share from the browser's own UI — funnel that into\n // the same stop path so the in-flight recording still resolves.\n stream.getVideoTracks()[0]?.addEventListener(\"ended\", requestStop);\n\n return {\n stream,\n result,\n stop: requestStop,\n cancel() {\n cancelled = true;\n if (recorder.state !== \"inactive\") {\n recorder.stop();\n } else if (!settled) {\n settled = true;\n release();\n rejectResult(\n new LumenError(\"Recording cancelled.\", \"RECORDER_STOPPED\"),\n );\n }\n },\n };\n}\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type {\n LumenClient,\n CaptureResult,\n ScreenshotCaptureOptions,\n LumenUser,\n SubmitOptions,\n SubmitPayload,\n SubmitResult,\n} from \"@lumen-stack/core\";\n\n/**\n * Live screen-recording state, surfaced to the floating HUD. The browser path\n * only ever produces `recording`; the `starting`/`processing` phases are used\n * by the custom/native `record.provider` path (consent window before the clip\n * starts, encode/transfer window after Stop).\n */\nexport type VideoRecordingState =\n | { phase: \"starting\" }\n | {\n phase: \"recording\";\n /** Null for native hosts that record without exposing a MediaStream. */\n stream: MediaStream | null;\n /** Epoch ms when recording began (the HUD derives elapsed time from this). */\n startedAt: number;\n maxSeconds: number;\n }\n | { phase: \"processing\" };\n\n/**\n * Live \"Capture exact screen\" (`getDisplayMedia`) state, surfaced to the\n * floating capture HUD while the sheet is hidden. `live` = stream is open and\n * the user is arranging the page; `grabbing` = the frame is being drawn.\n */\nexport type ScreenCaptureState = { phase: \"live\" } | { phase: \"grabbing\" };\n\n/** A finished clip handed to the modal on reopen so it can attach + preview. */\nexport interface PendingVideo {\n blob: Blob;\n durationMs: number;\n poster: Blob | null;\n /**\n * Provider clips arrive without a stream-derived poster; when true and\n * `poster` is null the modal derives a first-frame poster from the blob.\n * Never set on the browser path, so that path's behavior is unchanged.\n */\n deriveBlobPoster?: boolean;\n}\n\nexport interface LumenContextValue {\n client: LumenClient;\n user: LumenUser | undefined;\n\n // ── Video recording session ──────────────────────────────────────────\n // Lifted out of the modal so recording survives the sheet being closed.\n /** Start a screen recording from a user gesture (the Record button).\n * Closes the sheet; a floating HUD takes over until the user stops.\n * Rejects if the picker is denied so the modal can surface it. */\n startVideoSession: () => Promise<void>;\n /** Stop the active recording → reopens the sheet with the clip attached. */\n stopVideoSession: () => void;\n /** Abort the active recording without keeping a clip. */\n cancelVideoSession: () => void;\n /** Non-null while recording (sheet closed). Drives the floating HUD. */\n recording: VideoRecordingState | null;\n /** Consumed once by the modal on (re)open to seed a just-finished clip. */\n consumePendingVideo: () => PendingVideo | null;\n /**\n * Whether the Record tab should be offered, resolving `record.provider` +\n * `record.isAvailable` (probed on open) against browser `getDisplayMedia`.\n */\n canRecordScreen: boolean;\n /**\n * Consume-once error from a failed `record.provider` start. When present on\n * (re)open the modal lands on the Record step and shows it inline.\n */\n consumeRecordStartError: () => string | null;\n\n // ── \"Capture exact screen\" session (getDisplayMedia) ──────────────────\n // Lifted out of the modal so the live stream survives the sheet being\n // hidden, letting the user arrange the page before the frame is grabbed.\n /** Start an exact-screen capture from a user gesture (the button). Opens the\n * surface picker; on success hides the sheet and shows the floating bar. */\n startScreenCaptureSession: () => Promise<void>;\n /** Grab the current frame → reopens the sheet with the screenshot attached. */\n grabScreenCaptureFrame: () => void;\n /** Abort the session without capturing → reopens the sheet unchanged. */\n cancelScreenCaptureSession: () => void;\n /** Non-null while an exact-screen session is live. Drives the capture HUD. */\n screenCapture: ScreenCaptureState | null;\n /** Consumed once by the modal on reopen to seed a just-captured screenshot. */\n consumePendingScreenshot: () => CaptureResult | null;\n\n // v2 surface\n open: (event?: Event) => void;\n close: () => void;\n isOpen: boolean;\n /** Pass-through to client.submit — for headless hosts that build their own payload. */\n submit: (\n payload: SubmitPayload,\n options?: SubmitOptions,\n ) => Promise<SubmitResult>;\n /** Best-effort: true when running inside a native shell (RN WebView, Capacitor, …). */\n isNativeShell: boolean;\n /** Capture options from <LumenProvider>. */\n capture: ScreenshotCaptureOptions | undefined;\n /** Screenshot captured before the wizard mounted, when available. */\n initialCapture: CaptureResult | null;\n /** Error from the pre-open capture; the modal falls back to manual upload. */\n initialCaptureError: Error | null;\n /** True while the trigger has been activated and the pre-open capture is running. */\n isOpening: boolean;\n /** Whether Lumen stops its own pointer/click events from leaking into host overlays. */\n isolateEvents: boolean;\n /** Soft-keyboard inset override (px) from the host, when provided. */\n keyboardInset: number | undefined;\n\n // Back-compat aliases (kept; do not remove).\n openCapture: (event?: Event) => void;\n closeCapture: () => void;\n isSubmitting: boolean;\n error: Error | null;\n}\n\nexport const LumenContext = createContext<LumenContextValue | null>(null);\n\nexport function useLumen(): LumenContextValue {\n const ctx = useContext(LumenContext);\n if (!ctx) {\n throw new Error(\"useLumen() must be used inside <LumenProvider>.\");\n }\n return ctx;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\n/** Default visual-viewport shrink (px) that counts as the keyboard being up. */\nexport const KEYBOARD_THRESHOLD = 100;\n\nexport interface KeyboardStateInput {\n /** Whether an editable element currently holds focus. */\n editableFocused: boolean;\n /** Last \"no keyboard\" visual-viewport height (the calibrated baseline). */\n baseline: number;\n /** Current `visualViewport.height`. */\n vvHeight: number;\n /** Shrink (px) past which the keyboard is considered open. */\n threshold?: number;\n}\n\nexport interface KeyboardState {\n /** True when the keyboard is judged to be covering the viewport. */\n open: boolean;\n /** Baseline to carry into the next measurement. */\n baseline: number;\n}\n\n/**\n * Pure decision for keyboard visibility — framework-free so it can be unit\n * tested without a DOM (mirrors `record-availability.ts`).\n *\n * The keyboard is only reported open when an editable element is focused: iOS\n * never shows the soft keyboard otherwise, so a bare viewport shrink (Chrome\n * iOS collapsing its top/bottom toolbars on scroll) must NOT hide the trigger.\n * While nothing is focused the baseline tracks the current height, which\n * auto-calibrates per browser and survives orientation changes; while an\n * editable element is focused the baseline is frozen so `baseline - vvHeight`\n * measures the keyboard alone.\n */\nexport function nextKeyboardState({\n editableFocused,\n baseline,\n vvHeight,\n threshold = KEYBOARD_THRESHOLD,\n}: KeyboardStateInput): KeyboardState {\n if (!editableFocused) {\n return { open: false, baseline: vvHeight };\n }\n return { open: baseline - vvHeight > threshold, baseline };\n}\n\n/** True when an editable element holds focus, piercing open shadow roots. */\nexport function isEditableElementFocused(): boolean {\n if (typeof document === \"undefined\") return false;\n let el: Element | null = document.activeElement;\n while (el?.shadowRoot?.activeElement) {\n el = el.shadowRoot.activeElement;\n }\n if (!el) return false;\n const tag = el.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") return true;\n return (el as HTMLElement).isContentEditable === true;\n}\n\n/**\n * True when the on-screen keyboard is likely covering the viewport. Touch\n * devices only — desktop never returns true.\n */\nexport function useViewportKeyboard(enabled: boolean): boolean {\n const [open, setOpen] = useState(false);\n const baselineRef = useRef(0);\n\n useEffect(() => {\n if (!enabled) {\n setOpen(false);\n return;\n }\n if (typeof window === \"undefined\") return;\n const vv = window.visualViewport;\n if (!vv) return;\n if (\n typeof window.matchMedia !== \"function\" ||\n !window.matchMedia(\"(pointer: coarse)\").matches\n ) {\n return;\n }\n\n baselineRef.current = vv.height;\n\n let raf = 0;\n const check = () => {\n raf = 0;\n const result = nextKeyboardState({\n editableFocused: isEditableElementFocused(),\n baseline: baselineRef.current,\n vvHeight: vv.height,\n });\n baselineRef.current = result.baseline;\n setOpen(result.open);\n };\n const schedule = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(check);\n };\n\n schedule();\n vv.addEventListener(\"resize\", schedule);\n vv.addEventListener(\"scroll\", schedule);\n document.addEventListener(\"focusin\", schedule);\n document.addEventListener(\"focusout\", schedule);\n return () => {\n if (raf) window.cancelAnimationFrame(raf);\n vv.removeEventListener(\"resize\", schedule);\n vv.removeEventListener(\"scroll\", schedule);\n document.removeEventListener(\"focusin\", schedule);\n document.removeEventListener(\"focusout\", schedule);\n };\n }, [enabled]);\n\n return open;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { LUMEN_KEYBOARD_EVENT, readLumenKeyboardInset } from \"@lumen-stack/core\";\n\nimport {\n KEYBOARD_THRESHOLD,\n isEditableElementFocused,\n} from \"./useViewportKeyboard\";\n\nexport interface KeyboardInsetState {\n /** True when the soft keyboard is judged to be covering the viewport. */\n open: boolean;\n /** Keyboard height (CSS px) to lift UI by. 0 when closed/unknown. */\n inset: number;\n}\n\nconst CLOSED: KeyboardInsetState = { open: false, inset: 0 };\n\nexport interface KeyboardInsetDecisionInput {\n /** Whether an editable element holds focus (iOS only shows the keyboard then). */\n editable: boolean;\n /** Explicit `keyboardInset` prop override, if any. */\n override?: number;\n /** Injected inset (window global / CSS var), or null when absent. */\n injected: number | null;\n /** Last \"no keyboard\" visualViewport height (the calibrated baseline). */\n vvBaseline: number;\n /** Current visualViewport height, or null when unavailable. */\n vvHeight: number | null;\n /** Coarse pointer (touch) — gates the visualViewport fallback path. */\n coarse: boolean;\n}\n\n/**\n * Pure decision for keyboard height — framework-free so it can be unit tested\n * (mirrors `nextKeyboardState` / `record-availability.ts`). Priority:\n * 1. explicit prop override, 2. injected inset (WebView), 3. visualViewport.\n * The keyboard is only \"open\" while an editable element is focused.\n */\nexport function decideKeyboardInset(\n input: KeyboardInsetDecisionInput,\n): KeyboardInsetState {\n const explicit = input.override ?? input.injected;\n if (explicit != null) {\n const open = explicit > 1 && input.editable;\n return open ? { open, inset: Math.round(explicit) } : CLOSED;\n }\n // visualViewport fallback — touch web only (desktop has no soft keyboard, and\n // Chrome-iOS toolbar collapse must not count as the keyboard).\n if (input.vvHeight == null || !input.coarse || !input.editable) return CLOSED;\n const delta = input.vvBaseline - input.vvHeight;\n return delta > KEYBOARD_THRESHOLD\n ? { open: true, inset: Math.round(delta) }\n : CLOSED;\n}\n\n/**\n * Keyboard-awareness that works on web AND inside an iOS WKWebView.\n *\n * `window.visualViewport` does NOT shrink for the keyboard in a WKWebView, so a\n * viewport-only approach silently fails there. This hook merges three sources\n * (see {@link decideKeyboardInset}) and returns both whether the keyboard is\n * open and how tall it is, so callers can lift the trigger / modal input above\n * it rather than just hiding them.\n */\nexport function useKeyboardInset(\n enabled: boolean,\n override?: number,\n): KeyboardInsetState {\n const [state, setState] = useState<KeyboardInsetState>(CLOSED);\n const baselineRef = useRef(0);\n const overrideRef = useRef(override);\n overrideRef.current = override;\n\n useEffect(() => {\n if (!enabled) {\n setState(CLOSED);\n return;\n }\n if (typeof window === \"undefined\") return;\n\n const coarse =\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(pointer: coarse)\").matches;\n\n const recompute = () => {\n const editable = isEditableElementFocused();\n const override = overrideRef.current;\n const injected = readLumenKeyboardInset();\n const vv = window.visualViewport ?? null;\n // Recalibrate the visualViewport baseline while nothing is focused (and no\n // host inset is driving us) so it survives rotation / browser-chrome shifts.\n if (vv && override == null && injected == null && !editable) {\n baselineRef.current = vv.height;\n }\n setState(\n decideKeyboardInset({\n editable,\n override,\n injected,\n vvBaseline: baselineRef.current,\n vvHeight: vv ? vv.height : null,\n coarse,\n }),\n );\n };\n\n let raf = 0;\n const schedule = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(() => {\n raf = 0;\n recompute();\n });\n };\n\n const vv = window.visualViewport;\n if (vv) baselineRef.current = vv.height;\n\n schedule();\n vv?.addEventListener(\"resize\", schedule);\n vv?.addEventListener(\"scroll\", schedule);\n document.addEventListener(\"focusin\", schedule);\n document.addEventListener(\"focusout\", schedule);\n window.addEventListener(LUMEN_KEYBOARD_EVENT, schedule);\n return () => {\n if (raf) window.cancelAnimationFrame(raf);\n vv?.removeEventListener(\"resize\", schedule);\n vv?.removeEventListener(\"scroll\", schedule);\n document.removeEventListener(\"focusin\", schedule);\n document.removeEventListener(\"focusout\", schedule);\n window.removeEventListener(LUMEN_KEYBOARD_EVENT, schedule);\n };\n }, [enabled]);\n\n return state;\n}\n","\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport * as React from \"react\";\n\nexport type AnnotationTool = \"arrow\" | \"rect\" | \"freehand\" | \"comment\";\n\ninterface ArrowAnno {\n kind: \"arrow\";\n from: { x: number; y: number };\n to: { x: number; y: number };\n color: string;\n width: number;\n}\ninterface RectAnno {\n kind: \"rect\";\n from: { x: number; y: number };\n to: { x: number; y: number };\n color: string;\n width: number;\n}\ninterface FreehandAnno {\n kind: \"freehand\";\n points: Array<{ x: number; y: number }>;\n color: string;\n width: number;\n}\ntype Annotation = ArrowAnno | RectAnno | FreehandAnno;\n\n/** A text \"speech bubble\" callout placed directly on the screenshot.\n * Unlike the canvas shapes, comments live as inline-editable DOM nodes\n * (Figma-style: click to place, type in place, multiple allowed) and are\n * baked into the image only at flatten() time. Position is stored as a\n * fraction of the image so it maps to both the rendered box and the\n * full-resolution bitmap. */\ninterface CommentAnno {\n id: number;\n x: number;\n y: number;\n text: string;\n color: string;\n}\n\nconst HISTORY_LIMIT = 50;\nconst BUBBLE_FONT =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, ui-sans-serif, sans-serif';\n\nfunction clamp01(v: number, max = 1): number {\n return Math.max(0, Math.min(max, v));\n}\n\nexport interface AnnotationLayerHandle {\n flatten: () => Promise<Blob>;\n reset: () => void;\n undo: () => void;\n redo: () => void;\n hasAnnotations: () => boolean;\n}\n\nexport interface AnnotationLayerProps {\n screenshot: Blob;\n tool: AnnotationTool;\n /** Stroke color (CSS color). Default red-500. */\n color?: string;\n /** Stroke width in bitmap px. Default 4. */\n strokeWidth?: number;\n /** Called when the user starts/stops drawing — used by the modal to\n * lock its scrollable body during a stroke. */\n onDrawingChange?: (drawing: boolean) => void;\n /** Called whenever the undo/redo history changes (a mark is added, undone,\n * redone, or cleared) so the parent can enable/disable its toolbar buttons. */\n onHistoryChange?: (state: { canUndo: boolean; canRedo: boolean }) => void;\n}\n\n// forwardRef so the parent (CaptureModal) can call flatten() imperatively.\n// React 18 does NOT forward `ref` to plain function components — it must be\n// declared with forwardRef. React 19 deprecated forwardRef but still supports\n// it, so this is safe across both major versions.\nexport const AnnotationLayer = React.forwardRef<\n AnnotationLayerHandle,\n AnnotationLayerProps\n>(function AnnotationLayer({\n screenshot,\n tool,\n color = \"rgb(239, 68, 68)\",\n strokeWidth = 4,\n onDrawingChange,\n onHistoryChange,\n}, ref) {\n const baseCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const overlayCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [imageBitmap, setImageBitmap] = useState<ImageBitmap | null>(null);\n // iOS Safari can throw InvalidStateError from drawImage(ImageBitmap) even for\n // small images. If the base-canvas paint fails we fall back to rendering the\n // screenshot as a plain <img> (which WebKit handles reliably) so the widget\n // degrades gracefully instead of crashing into the error boundary.\n const [baseDrawFailed, setBaseDrawFailed] = useState(false);\n const [fallbackUrl, setFallbackUrl] = useState<string>(\"\");\n const [annotations, setAnnotations] = useState<Annotation[]>([]);\n const draftRef = useRef<Annotation | null>(null);\n const isDrawingRef = useRef(false);\n const lastSampleAtRef = useRef(0);\n const rafPendingRef = useRef(false);\n const [comments, setComments] = useState<CommentAnno[]>([]);\n const seqRef = useRef(0);\n // LIFO of what was added so undo() removes the most recent of either a\n // canvas shape or a comment bubble, in true insertion order.\n const undoStackRef = useRef<Array<\"anno\" | \"comment\">>([]);\n // Items popped by undo(), kept so redo() can re-add them in order. Each\n // entry carries the removed object itself — for comments that means the\n // latest typed text survives an undo→redo round-trip.\n const redoStackRef = useRef<\n Array<{ type: \"anno\"; item: Annotation } | { type: \"comment\"; item: CommentAnno }>\n >([]);\n // Mirror the live state so undo/redo can read the current arrays (and mutate\n // them synchronously) from event handlers without stale-closure or\n // Strict-Mode double-update hazards.\n const annotationsRef = useRef<Annotation[]>(annotations);\n annotationsRef.current = annotations;\n const commentsRef = useRef<CommentAnno[]>(comments);\n commentsRef.current = comments;\n // Set when a bubble is placed so the next render can focus it for typing.\n const pendingFocusRef = useRef<number | null>(null);\n\n // Notify the parent so it can enable/disable its Undo/Redo buttons. Held in a\n // ref so callers don't need it in their dependency arrays.\n const onHistoryChangeRef = useRef(onHistoryChange);\n onHistoryChangeRef.current = onHistoryChange;\n const fireHistory = useCallback(() => {\n onHistoryChangeRef.current?.({\n canUndo: undoStackRef.current.length > 0,\n canRedo: redoStackRef.current.length > 0,\n });\n }, []);\n\n const handleCommentChange = useCallback((id: number, text: string) => {\n setComments((cur) =>\n cur.map((c) => (c.id === id ? { ...c, text } : c)),\n );\n }, []);\n const handleCommentRemove = useCallback(\n (id: number) => {\n setComments((cur) => cur.filter((c) => c.id !== id));\n const i = undoStackRef.current.lastIndexOf(\"comment\");\n if (i >= 0) undoStackRef.current.splice(i, 1);\n // A manual delete is a fresh action — invalidate any redo trail.\n redoStackRef.current = [];\n fireHistory();\n },\n [fireHistory],\n );\n\n // Focus a freshly-placed bubble so the user can type immediately.\n useEffect(() => {\n const id = pendingFocusRef.current;\n if (id == null) return;\n pendingFocusRef.current = null;\n const el = containerRef.current?.querySelector<HTMLElement>(\n `[data-bubble-id=\"${id}\"] .lumen-bubble-text`,\n );\n el?.focus();\n }, [comments]);\n\n // A new screenshot (recapture, exact-screen swap, upload) is a clean slate:\n // drop any marks + history so undo/redo can't act on shapes drawn over a\n // previous shot. Runs harmlessly on first mount (everything already empty).\n useEffect(() => {\n setAnnotations([]);\n setComments([]);\n setBaseDrawFailed(false);\n undoStackRef.current = [];\n redoStackRef.current = [];\n fireHistory();\n }, [screenshot, fireHistory]);\n\n // Decode the screenshot once into a bitmap so we can redraw cheaply.\n // In React Strict Mode the effect runs twice on mount — we must close\n // the second-run bitmap and free both via .close() on unmount so we\n // don't leak GPU memory across repeated capture sessions.\n useEffect(() => {\n let cancelled = false;\n let decoded: ImageBitmap | null = null;\n (async () => {\n try {\n const bm = await createImageBitmap(screenshot);\n if (cancelled) {\n bm.close?.();\n return;\n }\n decoded = bm;\n setImageBitmap(bm);\n } catch {\n // Decoding failure leaves the layer in its loading state; the\n // surrounding modal will surface the error via toast on submit.\n }\n })();\n return () => {\n cancelled = true;\n decoded?.close?.();\n };\n }, [screenshot]);\n\n // Size + paint base canvas exactly once per bitmap. The overlay is always\n // sized to the bitmap so annotation coordinates map even if the base paint\n // fails. The drawImage is guarded: iOS Safari can throw InvalidStateError\n // here, and an unguarded throw in an effect tears the whole widget down via\n // the error boundary — instead we flip to the <img> fallback below.\n useEffect(() => {\n if (!imageBitmap) return;\n const base = baseCanvasRef.current;\n const overlay = overlayCanvasRef.current;\n if (!base || !overlay) return;\n overlay.width = imageBitmap.width;\n overlay.height = imageBitmap.height;\n try {\n base.width = imageBitmap.width;\n base.height = imageBitmap.height;\n const ctx = base.getContext(\"2d\");\n if (!ctx) return;\n ctx.imageSmoothingEnabled = false;\n ctx.drawImage(imageBitmap, 0, 0);\n setBaseDrawFailed(false);\n } catch {\n // WebKit/iOS drawImage failure — show the screenshot as an <img> instead.\n setBaseDrawFailed(true);\n }\n }, [imageBitmap]);\n\n // Object URL for the <img> fallback, created only when the canvas paint\n // failed. Revoked on cleanup so we never leak the blob.\n useEffect(() => {\n if (!baseDrawFailed) {\n setFallbackUrl(\"\");\n return;\n }\n const url = URL.createObjectURL(screenshot);\n setFallbackUrl(url);\n return () => {\n URL.revokeObjectURL(url);\n };\n }, [baseDrawFailed, screenshot]);\n\n // Repaint the OVERLAY only when annotations change. Base canvas is\n // never touched after the initial draw.\n useEffect(() => {\n const overlay = overlayCanvasRef.current;\n if (!overlay) return;\n // Defensive: a failed 2d context op must not tear down the widget.\n try {\n redraw(overlay, annotations, draftRef.current);\n } catch {\n // ignore — overlay just stays as-is\n }\n }, [annotations]);\n\n useImperativeHandle(\n ref,\n (): AnnotationLayerHandle => ({\n hasAnnotations: () =>\n annotations.length > 0 ||\n comments.some((c) => c.text.trim().length > 0),\n reset: () => {\n setAnnotations([]);\n setComments([]);\n annotationsRef.current = [];\n commentsRef.current = [];\n undoStackRef.current = [];\n redoStackRef.current = [];\n fireHistory();\n },\n undo: () => {\n const last = undoStackRef.current[undoStackRef.current.length - 1];\n if (!last) return;\n if (last === \"comment\") {\n const cur = commentsRef.current;\n const removed = cur[cur.length - 1];\n if (!removed) return;\n const next = cur.slice(0, -1);\n commentsRef.current = next;\n redoStackRef.current.push({ type: \"comment\", item: removed });\n setComments(next);\n } else {\n const cur = annotationsRef.current;\n const removed = cur[cur.length - 1];\n if (!removed) return;\n const next = cur.slice(0, -1);\n annotationsRef.current = next;\n redoStackRef.current.push({ type: \"anno\", item: removed });\n setAnnotations(next);\n }\n undoStackRef.current.pop();\n fireHistory();\n },\n redo: () => {\n const entry = redoStackRef.current[redoStackRef.current.length - 1];\n if (!entry) return;\n if (entry.type === \"comment\") {\n const next = [...commentsRef.current, entry.item];\n commentsRef.current = next;\n setComments(next);\n } else {\n const next = [...annotationsRef.current, entry.item];\n annotationsRef.current = next;\n setAnnotations(next);\n }\n undoStackRef.current.push(entry.type);\n redoStackRef.current.pop();\n fireHistory();\n },\n async flatten() {\n // Mid-stroke at submit time: bake the live draft so the user\n // doesn't lose the annotation they were drawing when they clicked\n // Send.\n const draft = draftRef.current;\n const all = draft ? [...annotations, draft] : annotations;\n // Only bake bubbles the user actually typed into.\n const liveComments = comments.filter((c) => c.text.trim().length > 0);\n // No marks at all → no re-encode (a 2MB PNG through canvas.toBlob\n // costs 100-300ms on a phone for zero benefit). CRITICAL: this gate\n // MUST consider comments too — comments live in a separate array, so\n // a strokes-empty check alone would silently drop every bubble from\n // the submitted image.\n if (all.length === 0 && liveComments.length === 0) return screenshot;\n // No usable bitmap (decode failed) or the base paint already failed on\n // this device → can't composite; submit the original screenshot.\n if (!imageBitmap || baseDrawFailed) return screenshot;\n try {\n const out = document.createElement(\"canvas\");\n out.width = imageBitmap.width;\n out.height = imageBitmap.height;\n const ctx = out.getContext(\"2d\");\n if (!ctx) return screenshot;\n ctx.imageSmoothingEnabled = false;\n ctx.drawImage(imageBitmap, 0, 0);\n for (const anno of all) drawAnno(ctx, anno);\n // Bubbles bake at bitmap resolution; scale the on-screen UI font by\n // the bitmap/rendered ratio so baked text matches what the user saw\n // instead of rendering tiny on a hi-dpi screenshot.\n const renderedWidth =\n baseCanvasRef.current?.clientWidth || imageBitmap.width;\n const bubbleScale = imageBitmap.width / Math.max(renderedWidth, 1);\n for (const c of liveComments) {\n drawBubble(ctx, c, imageBitmap.width, imageBitmap.height, bubbleScale);\n }\n // JPEG q=0.85: ~4-10× smaller than PNG for screenshot content,\n // which dominates submit time on slow uplinks. Annotations are\n // simple shapes that survive JPEG without visible artifacts.\n return await new Promise<Blob>((resolve) => {\n out.toBlob(\n (blob) => {\n resolve(blob ?? screenshot);\n },\n \"image/jpeg\",\n 0.85,\n );\n });\n } catch {\n // Compositing failed (e.g. iOS Safari drawImage) — never block\n // submit; fall back to the original screenshot blob.\n return screenshot;\n }\n },\n }),\n [annotations, comments, imageBitmap, screenshot, baseDrawFailed, fireHistory],\n );\n\n function clientToCanvas(\n e: React.PointerEvent<HTMLCanvasElement>,\n ): { x: number; y: number } {\n const c = overlayCanvasRef.current;\n if (!c) return { x: 0, y: 0 };\n const rect = c.getBoundingClientRect();\n const sx = c.width / Math.max(rect.width, 1);\n const sy = c.height / Math.max(rect.height, 1);\n return {\n x: (e.clientX - rect.left) * sx,\n y: (e.clientY - rect.top) * sy,\n };\n }\n\n function scheduleDraftPaint() {\n if (rafPendingRef.current) return;\n rafPendingRef.current = true;\n requestAnimationFrame(() => {\n rafPendingRef.current = false;\n const overlay = overlayCanvasRef.current;\n if (!overlay) return;\n // Read the LIVE committed set, not the render closure: a rAF scheduled\n // during the last pointer-move can fire after pointer-up has committed the\n // stroke, and a stale `annotations` would repaint without it — erasing the\n // just-finished stroke until the next interaction.\n redraw(overlay, annotationsRef.current, draftRef.current);\n });\n }\n\n function onPointerDown(e: React.PointerEvent<HTMLCanvasElement>) {\n if (e.button !== undefined && e.button !== 0) return;\n // Comment tool: place an inline-editable bubble at the tap and bail —\n // no stroke. Clamp so the bubble box stays inside the frame.\n if (tool === \"comment\") {\n const c = overlayCanvasRef.current;\n if (!c) return;\n const rect = c.getBoundingClientRect();\n const fx = clamp01((e.clientX - rect.left) / Math.max(rect.width, 1), 0.72);\n const fy = clamp01((e.clientY - rect.top) / Math.max(rect.height, 1), 0.8);\n const id = ++seqRef.current;\n setComments((cur) => [...cur, { id, x: fx, y: fy, text: \"\", color }]);\n undoStackRef.current.push(\"comment\");\n // A new mark invalidates the redo trail.\n redoStackRef.current = [];\n pendingFocusRef.current = id;\n fireHistory();\n return;\n }\n try {\n e.currentTarget.setPointerCapture(e.pointerId);\n } catch {\n // iOS Safari can throw NotSupportedError if the pointer is already\n // captured by an ancestor (e.g. the sheet grabber's drag handler).\n // Swallow — capture is a nice-to-have for off-canvas tracking; the\n // stroke still works without it.\n }\n isDrawingRef.current = true;\n onDrawingChange?.(true);\n const p = clientToCanvas(e);\n if (tool === \"arrow\") {\n draftRef.current = { kind: \"arrow\", from: p, to: p, color, width: strokeWidth };\n } else if (tool === \"rect\") {\n draftRef.current = { kind: \"rect\", from: p, to: p, color, width: strokeWidth };\n } else {\n draftRef.current = {\n kind: \"freehand\",\n points: [p],\n color,\n width: strokeWidth,\n };\n }\n lastSampleAtRef.current = performance.now();\n scheduleDraftPaint();\n }\n\n function onPointerMove(e: React.PointerEvent<HTMLCanvasElement>) {\n if (!isDrawingRef.current || !draftRef.current) return;\n const p = clientToCanvas(e);\n const draft = draftRef.current;\n if (draft.kind === \"arrow\" || draft.kind === \"rect\") {\n draft.to = p;\n } else {\n const last = draft.points[draft.points.length - 1];\n const dist2 = last\n ? (last.x - p.x) ** 2 + (last.y - p.y) ** 2\n : Infinity;\n const now = performance.now();\n const elapsed = now - lastSampleAtRef.current;\n // Sample if we've moved ≥ 4 bitmap-px OR ≥ 16ms passed (handles\n // very slow strokes where a single point would otherwise stall).\n if (dist2 > 16 || elapsed > 16) {\n draft.points.push(p);\n lastSampleAtRef.current = now;\n }\n }\n scheduleDraftPaint();\n }\n\n function onPointerUp() {\n if (!isDrawingRef.current) return;\n isDrawingRef.current = false;\n onDrawingChange?.(false);\n const draft = draftRef.current;\n draftRef.current = null;\n if (!draft) return;\n if (draft.kind === \"arrow\" || draft.kind === \"rect\") {\n const dx = draft.to.x - draft.from.x;\n const dy = draft.to.y - draft.from.y;\n if (dx * dx + dy * dy < 16) {\n // Tap — discard. Force a clean overlay repaint so the empty\n // draft doesn't linger.\n const overlay = overlayCanvasRef.current;\n if (overlay) redraw(overlay, annotationsRef.current, null);\n return;\n }\n } else if (draft.points.length < 2) {\n const overlay = overlayCanvasRef.current;\n if (overlay) redraw(overlay, annotationsRef.current, null);\n return;\n }\n setAnnotations((cur) => [...cur, draft].slice(-HISTORY_LIMIT));\n undoStackRef.current.push(\"anno\");\n // A new stroke invalidates the redo trail.\n redoStackRef.current = [];\n fireHistory();\n }\n\n return (\n <div\n ref={containerRef}\n className=\"lumen-annotate-frame\"\n data-lumen-tool={tool}\n >\n <canvas ref={baseCanvasRef} />\n {baseDrawFailed && fallbackUrl ? (\n // iOS Safari couldn't paint the bitmap onto the canvas; show the\n // screenshot as a plain <img> so it's never blank. The overlay canvas\n // (rendered after this) still sits on top and takes annotation input.\n <img\n src={fallbackUrl}\n alt=\"\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n objectFit: \"fill\",\n pointerEvents: \"none\",\n }}\n />\n ) : null}\n <canvas\n ref={overlayCanvasRef}\n className=\"lumen-annotate-overlay\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n />\n <div className=\"lumen-bubble-layer\">\n {comments.map((c) => (\n <Bubble\n key={c.id}\n comment={c}\n onChange={handleCommentChange}\n onRemove={handleCommentRemove}\n />\n ))}\n </div>\n </div>\n );\n});\n\n/** A single inline-editable speech-bubble. Uncontrolled contenteditable:\n * the text is seeded once on mount and thereafter owned by the DOM, so the\n * caret never jumps when the parent re-renders. Edits mirror up to state\n * (for flatten/undo) via onInput. */\nfunction Bubble({\n comment,\n onChange,\n onRemove,\n}: {\n comment: CommentAnno;\n onChange: (id: number, text: string) => void;\n onRemove: (id: number) => void;\n}) {\n const elRef = useRef<HTMLDivElement | null>(null);\n useEffect(() => {\n const el = elRef.current;\n if (el && el.textContent !== comment.text) el.textContent = comment.text;\n // Seed once — comment.text is intentionally not a dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return (\n <div\n className=\"lumen-bubble\"\n data-bubble-id={comment.id}\n style={{\n left: `${comment.x * 100}%`,\n top: `${comment.y * 100}%`,\n [\"--lumen-bubble-accent\" as string]: comment.color,\n }}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <span className=\"lumen-bubble-label\">Comment</span>\n <div\n ref={elRef}\n className=\"lumen-bubble-text\"\n contentEditable\n suppressContentEditableWarning\n role=\"textbox\"\n aria-label=\"Comment text\"\n data-placeholder=\"Type a note…\"\n onInput={(e) => onChange(comment.id, e.currentTarget.textContent ?? \"\")}\n />\n <button\n type=\"button\"\n className=\"lumen-bubble-del\"\n aria-label=\"Remove comment\"\n onPointerDown={(e) => e.stopPropagation()}\n onClick={() => onRemove(comment.id)}\n >\n ×\n </button>\n </div>\n );\n}\n\nfunction redraw(\n canvas: HTMLCanvasElement,\n annotations: Annotation[],\n draft: Annotation | null,\n) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const a of annotations) drawAnno(ctx, a);\n if (draft) drawAnno(ctx, draft);\n}\n\nfunction drawAnno(ctx: CanvasRenderingContext2D, anno: Annotation) {\n ctx.save();\n ctx.strokeStyle = anno.color;\n ctx.fillStyle = anno.color;\n ctx.lineWidth = anno.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n if (anno.kind === \"rect\") {\n const x = Math.min(anno.from.x, anno.to.x);\n const y = Math.min(anno.from.y, anno.to.y);\n const w = Math.abs(anno.to.x - anno.from.x);\n const h = Math.abs(anno.to.y - anno.from.y);\n ctx.strokeRect(x, y, w, h);\n } else if (anno.kind === \"freehand\") {\n drawSmoothPath(ctx, anno.points);\n } else {\n const { from, to, width } = anno;\n ctx.beginPath();\n ctx.moveTo(from.x, from.y);\n ctx.lineTo(to.x, to.y);\n ctx.stroke();\n const angle = Math.atan2(to.y - from.y, to.x - from.x);\n const head = Math.max(12, width * 4);\n ctx.beginPath();\n ctx.moveTo(to.x, to.y);\n ctx.lineTo(\n to.x - head * Math.cos(angle - Math.PI / 7),\n to.y - head * Math.sin(angle - Math.PI / 7),\n );\n ctx.lineTo(\n to.x - head * Math.cos(angle + Math.PI / 7),\n to.y - head * Math.sin(angle + Math.PI / 7),\n );\n ctx.closePath();\n ctx.fill();\n }\n\n ctx.restore();\n}\n\n/**\n * Draw a polyline as quadratic curves through midpoints. Each pair of\n * adjacent points contributes one curve where the original point is\n * the control point and the midpoint to the next is the end. This is\n * the standard \"midpoint smoothing\" trick — zero-dep, single pass.\n */\nfunction drawSmoothPath(\n ctx: CanvasRenderingContext2D,\n points: ReadonlyArray<{ x: number; y: number }>,\n) {\n if (points.length === 0) return;\n ctx.beginPath();\n const first = points[0];\n if (!first) return;\n ctx.moveTo(first.x, first.y);\n if (points.length === 1) {\n // Single dot — render a small filled circle so a tap is visible.\n ctx.arc(first.x, first.y, ctx.lineWidth / 2, 0, Math.PI * 2);\n ctx.fill();\n return;\n }\n if (points.length === 2) {\n const second = points[1]!;\n ctx.lineTo(second.x, second.y);\n ctx.stroke();\n return;\n }\n for (let i = 1; i < points.length - 1; i++) {\n const p = points[i]!;\n const next = points[i + 1]!;\n const mx = (p.x + next.x) / 2;\n const my = (p.y + next.y) / 2;\n ctx.quadraticCurveTo(p.x, p.y, mx, my);\n }\n // Final segment to the last point.\n const last = points[points.length - 1]!;\n ctx.lineTo(last.x, last.y);\n ctx.stroke();\n}\n\n/** Bake one comment bubble onto the output canvas at full bitmap resolution.\n * `scale` maps the on-screen UI px sizes to bitmap px so the baked bubble\n * matches what the user saw. Box top-left sits at (c.x, c.y); a small tail\n * hangs from the bottom-left, mirroring the DOM bubble. */\nfunction drawBubble(\n ctx: CanvasRenderingContext2D,\n c: CommentAnno,\n W: number,\n H: number,\n scale: number,\n) {\n const text = c.text.trim();\n if (!text) return;\n const pad = 10 * scale;\n const fontPx = 14 * scale;\n const labelPx = 10 * scale;\n const radius = 12 * scale;\n const lineH = fontPx * 1.35;\n const labelH = labelPx * 1.7;\n\n const x = c.x * W;\n const y = c.y * H;\n const maxBoxW = Math.min(W * 0.6, W - x - 8 * scale);\n\n ctx.save();\n ctx.font = `500 ${fontPx}px ${BUBBLE_FONT}`;\n ctx.textBaseline = \"top\";\n const lines = wrapText(ctx, text, maxBoxW - pad * 2);\n const textW = lines.reduce(\n (m, l) => Math.max(m, ctx.measureText(l).width),\n 0,\n );\n const boxW = Math.min(\n maxBoxW,\n Math.max(textW, 56 * scale) + pad * 2,\n );\n const boxH = pad * 2 + labelH + lines.length * lineH;\n\n // Bubble body.\n roundRect(ctx, x, y, boxW, boxH, radius);\n ctx.fillStyle = \"#ffffff\";\n ctx.fill();\n ctx.lineWidth = Math.max(1, scale);\n ctx.strokeStyle = \"rgba(0,0,0,0.10)\";\n ctx.stroke();\n\n // Tail.\n const tailX = x + 18 * scale;\n const tailY = y + boxH;\n ctx.beginPath();\n ctx.moveTo(tailX, tailY - scale);\n ctx.lineTo(tailX + 13 * scale, tailY - scale);\n ctx.lineTo(tailX + 4 * scale, tailY + 9 * scale);\n ctx.closePath();\n ctx.fillStyle = \"#ffffff\";\n ctx.fill();\n\n // Accent label.\n ctx.fillStyle = c.color || \"rgb(239, 68, 68)\";\n ctx.font = `700 ${labelPx}px ${BUBBLE_FONT}`;\n ctx.fillText(\"COMMENT\", x + pad, y + pad);\n\n // Body text.\n ctx.fillStyle = \"#111318\";\n ctx.font = `500 ${fontPx}px ${BUBBLE_FONT}`;\n let ty = y + pad + labelH;\n for (const line of lines) {\n ctx.fillText(line, x + pad, ty);\n ty += lineH;\n }\n ctx.restore();\n}\n\n/** Greedy word-wrap against a pixel width using the ctx's current font. */\nfunction wrapText(\n ctx: CanvasRenderingContext2D,\n text: string,\n maxWidth: number,\n): string[] {\n const words = text.split(/\\s+/).filter(Boolean);\n const lines: string[] = [];\n let line = \"\";\n for (const w of words) {\n const test = line ? `${line} ${w}` : w;\n if (line && ctx.measureText(test).width > maxWidth) {\n lines.push(line);\n line = w;\n } else {\n line = test;\n }\n }\n if (line) lines.push(line);\n return lines.length ? lines : [text];\n}\n\n/** Trace a rounded-rect path, using native roundRect when present. */\nfunction roundRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): void {\n const radius = Math.min(r, w / 2, h / 2);\n ctx.beginPath();\n const anyCtx = ctx as CanvasRenderingContext2D & {\n roundRect?: (x: number, y: number, w: number, h: number, r: number) => void;\n };\n if (typeof anyCtx.roundRect === \"function\") {\n anyCtx.roundRect(x, y, w, h, radius);\n return;\n }\n ctx.moveTo(x + radius, y);\n ctx.arcTo(x + w, y, x + w, y + h, radius);\n ctx.arcTo(x + w, y + h, x, y + h, radius);\n ctx.arcTo(x, y + h, x, y, radius);\n ctx.arcTo(x, y, x + w, y, radius);\n ctx.closePath();\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * Dependency-free inline SVG icons for the capture methods and annotation\n * tools. The SDK keeps zero icon-library deps (host-provided icons are\n * pass-through ReactNode elsewhere), so these are hand-rolled 24×24 strokes\n * that inherit `currentColor`.\n */\ntype IconProps = React.SVGProps<SVGSVGElement>;\n\nfunction Svg({ children, ...props }: React.PropsWithChildren<IconProps>) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.8}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n {children}\n </svg>\n );\n}\n\nexport function IconScreenshot(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M3 9a2 2 0 0 1 2-2h1.5l1-1.5h5l1 1.5H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\" />\n <circle cx=\"12\" cy=\"13\" r=\"3.2\" />\n </Svg>\n );\n}\n\nexport function IconVideo(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"3\" y=\"6\" width=\"13\" height=\"12\" rx=\"2.5\" />\n <path d=\"m16 10 5-3v10l-5-3\" />\n </Svg>\n );\n}\n\nexport function IconUpload(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M12 16V4m0 0 4 4m-4-4-4 4\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Svg>\n );\n}\n\nexport function IconComment(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M21 11.5a8.38 8.38 0 0 1-8.5 8.5 9.5 9.5 0 0 1-3.5-.7L3 21l1.7-5.5A8.38 8.38 0 0 1 4 11.5 8.5 8.5 0 0 1 12.5 3 8.38 8.38 0 0 1 21 11.5Z\" />\n </Svg>\n );\n}\n\nexport function IconArrow(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M5 19 19 5\" />\n <path d=\"M11 5h8v8\" />\n </Svg>\n );\n}\n\nexport function IconBox(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"4\" y=\"6\" width=\"16\" height=\"12\" rx=\"2\" />\n </Svg>\n );\n}\n\nexport function IconDraw(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M5 19l1.5-5L16 4.5 19.5 8 10 17.5 5 19z\" />\n <path d=\"M14 6.5l3.5 3.5\" />\n </Svg>\n );\n}\n\nexport function IconUndo(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M9 8 4 13l5 5\" />\n <path d=\"M4 13h11a5 5 0 0 1 0 10h-1\" />\n </Svg>\n );\n}\n\nexport function IconRefresh(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M21 12a9 9 0 1 1-3-6.7\" />\n <path d=\"M21 4v4h-4\" />\n </Svg>\n );\n}\n\nexport function IconRedo(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M15 8 20 13l-5 5\" />\n <path d=\"M20 13H9a5 5 0 0 0 0 10h1\" />\n </Svg>\n );\n}\n\nexport function IconTrash(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M4 7h16\" />\n <path d=\"M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\" />\n <path d=\"M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13\" />\n </Svg>\n );\n}\n\nexport function IconChevronLeft(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={2.2}>\n <path d=\"M15 6l-6 6 6 6\" />\n </Svg>\n );\n}\n\nexport function IconSend(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={1.9}>\n <path d=\"M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z\" />\n </Svg>\n );\n}\n\nexport function IconImage(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={1.7}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2.5\" />\n <circle cx=\"8.5\" cy=\"9.5\" r=\"1.6\" />\n <path d=\"m4 17 5-5 5 4 2-2 4 4\" />\n </Svg>\n );\n}\n\nexport function IconFilm(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={1.7}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2.5\" />\n <path d=\"M3 9h18M3 15h18M8 4v16M16 4v16\" />\n </Svg>\n );\n}\n\nexport function IconMonitor(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"13\" rx=\"2\" />\n <path d=\"M8 21h8M12 17v4\" />\n </Svg>\n );\n}\n\nexport function IconMic(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\" />\n <path d=\"M5 11a7 7 0 0 0 14 0M12 18v3\" />\n </Svg>\n );\n}\n\nexport const METHOD_ICONS = {\n shot: IconScreenshot,\n video: IconVideo,\n upload: IconUpload,\n} as const;\n","\"use client\";\n\n/**\n * First-frame poster helpers for the Video and Upload methods. Kept in the\n * React layer (not core) so the published core API surface stays unchanged.\n * A video submission still wants a still image for the `screenshot` field —\n * the thumbnail the dashboard shows — so we grab the first frame.\n */\n\nfunction drawPoster(video: HTMLVideoElement): Promise<Blob | null> {\n const w = video.videoWidth || 1280;\n const h = video.videoHeight || 720;\n const canvas = document.createElement(\"canvas\");\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return Promise.resolve(null);\n ctx.drawImage(video, 0, 0, w, h);\n return new Promise((resolve) =>\n canvas.toBlob((b) => resolve(b), \"image/jpeg\", 0.82),\n );\n}\n\nfunction seek(video: HTMLVideoElement, t: number): Promise<void> {\n if (!Number.isFinite(t) || t <= 0) return Promise.resolve();\n return new Promise<void>((resolve) => {\n video.addEventListener(\"seeked\", () => resolve(), { once: true });\n try {\n video.currentTime = t;\n } catch {\n resolve();\n }\n });\n}\n\n/** Overall deadline for decoding a poster out of a video blob. The decode\n * events this relies on (`loadeddata`, `seeked`) are NOT guaranteed to fire\n * — `preload` quirks and MediaRecorder blobs with broken metadata can leave\n * them pending forever, which previously stranded the reopen flow on an\n * endless \"Capturing…\" phase. Past the deadline callers fall back to the\n * placeholder poster. */\nconst POSTER_DECODE_TIMEOUT_MS = 4000;\n\n/** Poster (first frame) + duration from an uploaded/recorded video blob.\n * Never hangs: resolves with a null poster after the decode deadline. */\nexport async function posterFromVideoBlob(\n blob: Blob,\n): Promise<{ poster: Blob | null; durationMs: number }> {\n if (typeof document === \"undefined\") return { poster: null, durationMs: 0 };\n const url = URL.createObjectURL(blob);\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n // \"auto\", not \"metadata\" — we need a decoded frame, and some browsers\n // never advance past metadata (no `loadeddata`) without it.\n video.preload = \"auto\";\n video.src = url;\n\n const attempt = async (): Promise<{ poster: Blob | null; durationMs: number }> => {\n await new Promise<void>((resolve, reject) => {\n if (video.readyState >= 2) return resolve();\n video.addEventListener(\"loadeddata\", () => resolve(), { once: true });\n video.addEventListener(\n \"error\",\n () => reject(new Error(\"video decode failed\")),\n { once: true },\n );\n });\n // A small seek forces a decoded frame on browsers that leave the poster\n // black at t=0.\n await seek(video, Math.min(0.1, (video.duration || 0) / 2));\n const poster = await drawPoster(video);\n const durationMs = Number.isFinite(video.duration)\n ? video.duration * 1000\n : 0;\n return { poster, durationMs };\n };\n\n let timer: number | undefined;\n const deadline = new Promise<{ poster: Blob | null; durationMs: number }>(\n (resolve) => {\n timer = window.setTimeout(\n () => resolve({ poster: null, durationMs: 0 }),\n POSTER_DECODE_TIMEOUT_MS,\n );\n },\n );\n\n try {\n return await Promise.race([\n attempt().catch(() => ({ poster: null, durationMs: 0 })),\n deadline,\n ]);\n } finally {\n window.clearTimeout(timer);\n video.removeAttribute(\"src\");\n URL.revokeObjectURL(url);\n }\n}\n\n/**\n * Poster (first frame) from a live screen-capture stream — grabbed at record\n * start so we never re-decode the recorded blob (the flaky path). Returns\n * null if a frame can't be read in time; callers fall back to a placeholder.\n */\nexport async function posterFromStream(\n stream: MediaStream,\n): Promise<Blob | null> {\n if (typeof document === \"undefined\") return null;\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n video.srcObject = stream;\n try {\n await video.play().catch(() => undefined);\n await new Promise<void>((resolve) => {\n if (video.readyState >= 2) return resolve();\n video.addEventListener(\"loadeddata\", () => resolve(), { once: true });\n window.setTimeout(resolve, 600);\n });\n return await drawPoster(video);\n } catch {\n return null;\n } finally {\n video.srcObject = null;\n }\n}\n\n/** Neutral fallback poster (dark frame + play glyph) when a real frame can't\n * be grabbed, so the wizard always has a `screenshot` blob to proceed with. */\nexport async function placeholderPoster(): Promise<Blob | null> {\n if (typeof document === \"undefined\") return null;\n const canvas = document.createElement(\"canvas\");\n canvas.width = 1280;\n canvas.height = 720;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n ctx.fillStyle = \"#0e0e12\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = \"#52525b\";\n ctx.beginPath();\n ctx.moveTo(590, 312);\n ctx.lineTo(590, 408);\n ctx.lineTo(694, 360);\n ctx.closePath();\n ctx.fill();\n return new Promise((resolve) =>\n canvas.toBlob((b) => resolve(b), \"image/jpeg\", 0.8),\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\nimport { toast } from \"sonner\";\nimport {\n captureContext,\n captureScreen,\n createManualCaptureResult,\n recordAudio,\n type CaptureResult,\n type FeedbackCategory,\n type FeedbackPriority,\n type FeedbackSource,\n type RecorderHandle,\n type ScreenshotCaptureMode,\n} from \"@lumen-stack/core\";\n\nimport { useLumen } from \"./context\";\nimport { useKeyboardInset } from \"./trigger/useKeyboardInset\";\nimport {\n AnnotationLayer,\n type AnnotationLayerHandle,\n type AnnotationTool,\n} from \"./AnnotationLayer\";\nimport {\n METHOD_ICONS,\n IconMic,\n IconMonitor,\n IconArrow,\n IconBox,\n IconDraw,\n IconComment,\n IconUndo,\n IconRedo,\n IconTrash,\n IconRefresh,\n IconUpload,\n IconChevronLeft,\n IconSend,\n} from \"./icons\";\nimport { posterFromVideoBlob, placeholderPoster } from \"./video-poster\";\n\nconst VOICE_MAX_SECONDS = 60;\n// Mirrors the server's MAX_VIDEO_BYTES cap. Native screen recordings (mp4) can\n// easily exceed this, so warn at attach time rather than letting submit fail\n// with an opaque upload error. Kept local so the published SDK has no workspace\n// dep on the server's constants.\nconst VIDEO_SIZE_WARN_BYTES = 25 * 1024 * 1024;\n\nconst SWATCHES: ReadonlyArray<{ label: string; value: string }> = [\n { label: \"Red\", value: \"rgb(239, 68, 68)\" },\n { label: \"Amber\", value: \"rgb(245, 158, 11)\" },\n { label: \"Blue\", value: \"rgb(59, 130, 246)\" },\n { label: \"Green\", value: \"rgb(34, 197, 94)\" },\n { label: \"Neutral\", value: \"rgb(244, 244, 245)\" },\n];\n\nconst STROKE_SIZES: ReadonlyArray<{ label: string; value: number; dot: number }> = [\n { label: \"Small\", value: 2, dot: 6 },\n { label: \"Medium\", value: 4, dot: 9 },\n { label: \"Large\", value: 6, dot: 12 },\n];\n\nconst CATEGORIES: ReadonlyArray<{ value: FeedbackCategory; label: string }> = [\n { value: \"bug\", label: \"Bug\" },\n { value: \"feature\", label: \"Idea\" },\n { value: \"other\", label: \"Other\" },\n];\n\n// Reporter-set priority, using Linear's naming. \"\" = \"No priority\" (the default\n// — the reporter opts in). Sent to the server and pushed to Linear as-is.\nconst PRIORITIES: ReadonlyArray<{ value: FeedbackPriority | \"\"; label: string }> = [\n { value: \"\", label: \"No priority\" },\n { value: \"urgent\", label: \"Urgent\" },\n { value: \"high\", label: \"High\" },\n { value: \"medium\", label: \"Medium\" },\n { value: \"low\", label: \"Low\" },\n];\n\n// The review detent's editable platform chips. \"custom\" stays under the hood\n// (no chip) — the server still records it — but it can't be picked here.\nconst SOURCE_CHIPS: ReadonlyArray<{ value: FeedbackSource; label: string }> = [\n { value: \"web\", label: \"Web\" },\n { value: \"ios-native\", label: \"iOS native\" },\n { value: \"android-native\", label: \"Android native\" },\n];\n\n// Default platform for the review chips, derived from the capture environment —\n// the native bridge reports ios/android; the browser reports web. Mirrors the\n// server's source derivation so the prefilled chip matches what gets stored.\nfunction deriveSource(cap: CaptureResult): FeedbackSource {\n if (cap.platform === \"ios\") return \"ios-native\";\n if (cap.platform === \"android\") return \"android-native\";\n if (cap.platform === \"custom\") return \"custom\";\n return \"web\";\n}\n\n// Linear-style priority glyph: an urgent square, else 1–3 ascending bars.\nfunction PriorityIcon({ value }: { value: FeedbackPriority }) {\n if (value === \"urgent\") {\n return <span className=\"lumen-pri-ic lumen-pri-urgent\" aria-hidden=\"true\">!</span>;\n }\n const level = value === \"high\" ? 3 : value === \"medium\" ? 2 : 1;\n return (\n <span className=\"lumen-pri-ic lumen-pri-bars\" data-level={level} aria-hidden=\"true\">\n <i />\n <i />\n <i />\n </span>\n );\n}\n\ntype CaptureMethod = \"shot\" | \"video\" | \"upload\";\n\nconst METHODS: ReadonlyArray<{\n value: CaptureMethod;\n label: string;\n hint: string;\n /** Screenshot is the prominent hero card; the rest sit in a row below. */\n primary?: boolean;\n}> = [\n { value: \"shot\", label: \"Screenshot\", hint: \"This page, instantly\", primary: true },\n { value: \"video\", label: \"Video\", hint: \"Record up to 60s\" },\n { value: \"upload\", label: \"Upload\", hint: \"Image or video\" },\n];\n\ntype Step = 1 | 2 | 3;\n\n// Capture sub-state, independent of the wizard step. The annotated artifact\n// lives on `ready`. `idle` = step 1 with nothing captured yet.\ntype Phase =\n | { kind: \"idle\" }\n | { kind: \"capturing\" }\n | { kind: \"manual\"; error?: string }\n | { kind: \"ready\"; capture: CaptureResult };\n\nexport function CaptureModal() {\n const {\n client,\n isOpen,\n closeCapture,\n user,\n capture,\n initialCapture,\n initialCaptureError,\n startVideoSession,\n consumePendingVideo,\n canRecordScreen,\n consumeRecordStartError,\n startScreenCaptureSession,\n consumePendingScreenshot,\n isolateEvents,\n keyboardInset,\n } = useLumen();\n const [step, setStep] = useState<Step>(1);\n const [method, setMethod] = useState<CaptureMethod | null>(null);\n const [phase, setPhase] = useState<Phase>({ kind: \"idle\" });\n const [submitting, setSubmitting] = useState(false);\n const [progress, setProgress] = useState(0);\n // The AnnotationLayer stays mounted on both the markup (1) and review (2)\n // steps, so the annotated shot is flattened lazily in submit() — no need to\n // stash it on Next, and Back never loses the strokes.\n\n const [tool, setTool] = useState<AnnotationTool>(\"arrow\");\n const [strokeColor, setStrokeColor] = useState<string>(SWATCHES[0]!.value);\n const [strokeWidth, setStrokeWidth] = useState<number>(STROKE_SIZES[1]!.value);\n const [text, setText] = useState(\"\");\n const [category, setCategory] = useState<FeedbackCategory>(\"bug\");\n const [priority, setPriority] = useState<FeedbackPriority | \"\">(\"\");\n // Capture source (platform). Defaulted from the capture environment when the\n // review detent opens, then editable via chips (\"auto-detected — change if\n // wrong\"). \"\" until derived.\n const [source, setSource] = useState<FeedbackSource | \"\">(\"\");\n // Fullscreen markup: show/hide the floating tool palette (the prototype's\n // pen-toggle), so the user can clear the view to see the capture.\n const [toolsHidden, setToolsHidden] = useState(false);\n // Fullscreen markup: drag/tap the grabber to minimize the compose sheet and\n // reveal the full capture.\n const [sheetCollapsed, setSheetCollapsed] = useState(false);\n const [recapMenuOpen, setRecapMenuOpen] = useState(false);\n const [colorPickerOpen, setColorPickerOpen] = useState(false);\n const [submitterEmail, setSubmitterEmail] = useState(user?.email ?? \"\");\n const [recorder, setRecorder] = useState<RecorderHandle | null>(null);\n const [audio, setAudio] = useState<{ blob: Blob; durationMs: number } | null>(\n null,\n );\n const [recordSecs, setRecordSecs] = useState(0);\n const [video, setVideo] = useState<{ blob: Blob; durationMs: number } | null>(\n null,\n );\n // Inline error shown on the Record step when a custom/native record provider\n // fails to start (seeded from the provider's consume-once start error).\n const [videoError, setVideoError] = useState<string | null>(null);\n const [drawing, setDrawing] = useState(false);\n // Mirrors AnnotationLayer's undo/redo stacks so the toolbar buttons can\n // disable themselves at each end of the history.\n const [history, setHistory] = useState({ canUndo: false, canRedo: false });\n const annotationRef = useRef<AnnotationLayerHandle>(null);\n // Hidden file input for the Upload method — opened straight from the method\n // pill so there's no empty boxed \"choose a file\" step in between.\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n const modalRef = useRef<HTMLDivElement | null>(null);\n const backdropRef = useRef<HTMLDivElement | null>(null);\n const previouslyFocusedRef = useRef<HTMLElement | null>(null);\n\n // Keyboard-aware while the sheet is open: lifts the sheet above the soft\n // keyboard and keeps the focused input visible — works in an iOS WKWebView\n // (where visualViewport is silent) when the host injects the inset.\n const keyboard = useKeyboardInset(isOpen, keyboardInset);\n\n // Cancellation flag for in-flight captures — survives a Strict-Mode double\n // mount or a fast re-open so a stale capture can't stomp the latest phase.\n const captureCancelledRef = useRef(false);\n // Seed the wizard exactly once per open. Without this, an unstable `capture`\n // prop re-rendering mid-session would re-run the reset effect and wipe a\n // just-recorded clip (consumePendingVideo is already drained).\n const seededRef = useRef(false);\n\n // Reset everything when the modal opens. For web capture the default shot is\n // taken before the wizard mounts (so Lumen chrome is absent); for provider\n // (native/custom) capture it is taken here from the open wizard, where the\n // provider conceals Lumen UI — this keeps host overlays in the shot.\n // Reset the per-open seed guard whenever the sheet closes.\n useEffect(() => {\n if (!isOpen) seededRef.current = false;\n }, [isOpen]);\n\n\n useEffect(() => {\n if (!isOpen) return;\n // Run the seed once per open — immune to spurious re-runs from an\n // unstable `capture` prop while the wizard is already in progress.\n if (seededRef.current) {\n // The cleanup below already flagged cancellation for this re-run,\n // which would strand any in-flight capture/poster derivation in the\n // \"capturing\" phase forever. The wizard is still open — undo it.\n captureCancelledRef.current = false;\n return;\n }\n seededRef.current = true;\n captureCancelledRef.current = false;\n setStep(1);\n setMethod(null);\n setText(\"\");\n setAudio(null);\n setRecordSecs(0);\n setVideo(null);\n setSubmitting(false);\n setProgress(0);\n setSource(\"\");\n setVideoError(null);\n setHistory({ canUndo: false, canRedo: false });\n // A just-grabbed exact-screen shot (sheet reopened by the capture HUD)\n // wins: seed it straight into the annotator, exactly like the default DOM\n // shot, instead of running a fresh capture.\n const pendingShot = consumePendingScreenshot();\n if (pendingShot) {\n setMethod(\"shot\");\n showCaptureWarnings(pendingShot);\n setPhase({ kind: \"ready\", capture: pendingShot });\n return;\n }\n // A just-finished recording (sheet reopened by the HUD's Stop) wins:\n // seed the video method with the clip + its poster instead of capturing\n // a fresh screenshot.\n const pending = consumePendingVideo();\n if (pending) {\n setMethod(\"video\");\n setVideo({ blob: pending.blob, durationMs: pending.durationMs });\n if (pending.blob.size > VIDEO_SIZE_WARN_BYTES) {\n toast.warning(\n \"This recording is large and may be too big to upload. Try a shorter clip if the upload fails.\",\n );\n }\n if (pending.poster) {\n setPhase({\n kind: \"ready\",\n capture: createManualCaptureResult(pending.poster, [\n \"Screen recording; preview is the first frame.\",\n ]),\n });\n } else {\n // No stream-derived poster. Provider clips (deriveBlobPoster) get a\n // first-frame poster decoded from the blob — handles mp4 from native\n // hosts; the browser path keeps its placeholder-only behavior.\n setPhase({ kind: \"capturing\" });\n void (async () => {\n let posterBlob: Blob | null = null;\n if (pending.deriveBlobPoster) {\n try {\n posterBlob = (await posterFromVideoBlob(pending.blob)).poster;\n } catch {\n posterBlob = null;\n }\n }\n posterBlob = posterBlob ?? (await placeholderPoster());\n if (captureCancelledRef.current) return;\n setPhase(\n posterBlob\n ? {\n kind: \"ready\",\n capture: createManualCaptureResult(posterBlob, [\n \"Screen recording; preview is the first frame.\",\n ]),\n }\n : { kind: \"manual\" },\n );\n })();\n }\n } else {\n const startErr = consumeRecordStartError();\n if (startErr) {\n // A custom/native record provider failed to start — land on the Record\n // step and surface it inline (Upload suggested as the fallback).\n setMethod(\"video\");\n setVideoError(startErr);\n setPhase({ kind: \"idle\" });\n } else if (initialCapture) {\n setMethod(\"shot\");\n setPhase({ kind: \"ready\", capture: initialCapture });\n } else if (capture?.mode === \"manual\") {\n setPhase({ kind: \"manual\" });\n } else if (capture?.provider && !initialCaptureError) {\n // Provider mode (native/custom capture) defers the default screenshot\n // to here so host overlays — e.g. native iOS overlays — render into the\n // shot. Capturing pre-open dropped them. The provider conceals Lumen's\n // own UI during the shot, so grabbing it from the open wizard is leak-\n // safe. Falls back to manual via runCapture's catch if the shot fails.\n setMethod(\"shot\");\n void runCapture(capture.mode ?? \"auto\");\n } else {\n setPhase({\n kind: \"manual\",\n error:\n initialCaptureError?.message ??\n \"Automatic screenshot capture was unavailable.\",\n });\n }\n }\n return () => {\n captureCancelledRef.current = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, capture, initialCapture, initialCaptureError]);\n\n // Body scroll-lock + remember/restore focus while the modal is open.\n // Restore is wired through pagehide as well, so a navigation or a host\n // app crash while the modal is open can't leave the page unscrollable.\n useEffect(() => {\n if (!isOpen) return;\n previouslyFocusedRef.current =\n (document.activeElement as HTMLElement | null) ?? null;\n const html = document.documentElement;\n const prevOverflow = html.style.overflow;\n const prevPaddingRight = html.style.paddingRight;\n const scrollbar = window.innerWidth - html.clientWidth;\n html.style.overflow = \"hidden\";\n if (scrollbar > 0) html.style.paddingRight = `${scrollbar}px`;\n let restored = false;\n const restore = () => {\n if (restored) return;\n restored = true;\n html.style.overflow = prevOverflow;\n html.style.paddingRight = prevPaddingRight;\n try {\n previouslyFocusedRef.current?.focus?.();\n } catch {\n // focus() can throw if the prior element was removed from DOM.\n }\n };\n window.addEventListener(\"pagehide\", restore);\n return () => {\n window.removeEventListener(\"pagehide\", restore);\n restore();\n };\n }, [isOpen]);\n\n // ESC to close. Tab/Shift-Tab focus trap.\n useEffect(() => {\n if (!isOpen) return;\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n closeCapture();\n return;\n }\n if (e.key !== \"Tab\") return;\n const root = modalRef.current;\n if (!root) return;\n const focusables = getFocusable(root);\n if (focusables.length === 0) return;\n const first = focusables[0]!;\n const last = focusables[focusables.length - 1]!;\n const active = document.activeElement as HTMLElement | null;\n if (e.shiftKey && (active === first || !root.contains(active))) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [isOpen, closeCapture]);\n\n // Keep a tap on the empty backdrop from leaking into host outside-click\n // handlers (so a host bottom sheet under our opaque backdrop isn't dismissed).\n // Gated to the backdrop itself so the modal's own React handlers are untouched\n // — events from modal content (target !== backdrop) bubble normally. Hosts\n // that need full-subtree isolation should use isLumenEventTarget().\n useEffect(() => {\n if (!isOpen || !isolateEvents) return;\n const el = backdropRef.current;\n if (!el) return;\n const stopOnBackdrop = (event: Event) => {\n if (event.target === el) event.stopPropagation();\n };\n el.addEventListener(\"pointerdown\", stopOnBackdrop);\n el.addEventListener(\"click\", stopOnBackdrop);\n el.addEventListener(\"touchstart\", stopOnBackdrop, { passive: true });\n return () => {\n el.removeEventListener(\"pointerdown\", stopOnBackdrop);\n el.removeEventListener(\"click\", stopOnBackdrop);\n el.removeEventListener(\"touchstart\", stopOnBackdrop);\n };\n }, [isOpen, isolateEvents]);\n\n // When the keyboard opens, scroll the focused field into view so it never\n // sits behind the keyboard (the sheet itself is lifted via CSS var below).\n useEffect(() => {\n if (!isOpen || !keyboard.open) return;\n const root = modalRef.current;\n const active = document.activeElement as HTMLElement | null;\n if (root && active && root.contains(active)) {\n try {\n active.scrollIntoView({ block: \"center\" });\n } catch {\n // scrollIntoView options can throw on very old engines — ignore.\n }\n }\n }, [isOpen, keyboard.open, keyboard.inset]);\n\n // Paste-to-upload while on the manual-capture fallback.\n useEffect(() => {\n if (!isOpen || phase.kind !== \"manual\") return;\n function onPaste(e: ClipboardEvent) {\n const items = Array.from(e.clipboardData?.items ?? []);\n const image = items.find((item) => item.type.startsWith(\"image/\"));\n const file = image?.getAsFile();\n if (!file) return;\n e.preventDefault();\n void acceptUploadedFile(file);\n }\n window.addEventListener(\"paste\", onPaste);\n return () => window.removeEventListener(\"paste\", onPaste);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, phase.kind]);\n\n // Voice record timer.\n useEffect(() => {\n if (!recorder) return;\n const start = Date.now();\n const id = window.setInterval(() => {\n const sec = Math.floor((Date.now() - start) / 1000);\n setRecordSecs(sec);\n if (sec >= VOICE_MAX_SECONDS) finishRecording();\n }, 250);\n return () => window.clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recorder]);\n\n // Never leave the mic live after the sheet goes away: ESC, backdrop,\n // Cancel, and the HUD's record flow all just flip isOpen, so the active\n // recorder must be cancelled here — and again on unmount, in case the\n // host removes the provider while a voice note is running.\n const recorderRef = useRef<RecorderHandle | null>(null);\n recorderRef.current = recorder;\n useEffect(() => {\n if (isOpen) return;\n if (recorderRef.current) {\n recorderRef.current.cancel();\n recorderRef.current = null;\n setRecorder(null);\n setRecordSecs(0);\n }\n }, [isOpen]);\n useEffect(\n () => () => {\n recorderRef.current?.cancel();\n },\n [],\n );\n\n if (!isOpen) return null;\n\n // ── Capture ───────────────────────────────────────────────────────────\n async function runCapture(mode: ScreenshotCaptureMode): Promise<boolean> {\n captureCancelledRef.current = false;\n setPhase({ kind: \"capturing\" });\n try {\n const result = await captureScreen({\n ...capture,\n mode,\n target: capture?.target ?? document.documentElement,\n });\n if (captureCancelledRef.current) return false;\n showCaptureWarnings(result);\n setPhase({ kind: \"ready\", capture: result });\n return true;\n } catch (e) {\n if (captureCancelledRef.current) return false;\n setPhase({\n kind: \"manual\",\n error:\n e instanceof Error\n ? e.message\n : \"Automatic screenshot capture was unavailable.\",\n });\n return false;\n }\n }\n\n async function selectMethod(m: CaptureMethod) {\n setMethod(m);\n setVideoError(null);\n // A fresh capture yields a new screenshot blob, which remounts the\n // AnnotationLayer and clears any prior markup — recapture is explicit.\n if (m !== \"video\") discardVideo();\n if (m === \"shot\") {\n await runCapture(capture?.mode ?? \"auto\");\n } else if (m === \"video\") {\n // Show the Record button; recording only starts on an explicit tap so\n // getDisplayMedia fires from a fresh user gesture (no awaited capture\n // in between to drop the activation).\n setVideo(null);\n setPhase({ kind: \"idle\" });\n } else {\n // Upload: open the native picker right away (within this user gesture),\n // so the user never sees an empty boxed screen. The fullscreen drop zone\n // stays as a fallback if they dismiss the picker. Image → annotatable\n // screenshot slot; video → poster + attachment.\n setPhase({ kind: \"manual\" });\n uploadInputRef.current?.click();\n }\n }\n\n // Upload method: accept an image (→ annotatable screenshot slot) or a\n // video (→ video attachment + an auto-generated first-frame poster that\n // fills the `screenshot` slot the dashboard shows as a thumbnail).\n async function acceptUploadedFile(file: File) {\n if (file.type.startsWith(\"image/\")) {\n discardVideo();\n const result = createManualCaptureResult(file, [\n \"Manual image upload used.\",\n ]);\n setPhase({ kind: \"ready\", capture: result });\n return;\n }\n if (file.type.startsWith(\"video/\")) {\n setPhase({ kind: \"capturing\" });\n try {\n const { poster, durationMs } = await posterFromVideoBlob(file);\n const posterBlob = poster ?? (await placeholderPoster());\n if (!posterBlob) {\n setPhase({ kind: \"manual\", error: \"Could not read that video.\" });\n return;\n }\n const result = createManualCaptureResult(posterBlob, [\n \"Uploaded video; preview is the first frame.\",\n ]);\n setVideo({ blob: file, durationMs });\n setPhase({ kind: \"ready\", capture: result });\n } catch {\n setPhase({ kind: \"manual\", error: \"Could not read that video.\" });\n }\n return;\n }\n toast.error(\"Choose an image (PNG, JPEG, WebP) or a video (MP4, WebM).\");\n }\n\n function showCaptureWarnings(result: CaptureResult) {\n if (result.warnings.length === 0) return;\n toast.warning(\n \"Screenshot captured, but iframe, video, canvas, or cross-origin content may be incomplete.\",\n );\n }\n\n // ── Voice ─────────────────────────────────────────────────────────────\n async function startRecording() {\n try {\n const r = await recordAudio(VOICE_MAX_SECONDS);\n setRecorder(r);\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Microphone unavailable\");\n }\n }\n async function finishRecording() {\n if (!recorder) return;\n try {\n const result = await recorder.stop();\n setAudio({ blob: result.blob, durationMs: result.durationMs });\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Could not stop recording\");\n } finally {\n setRecorder(null);\n }\n }\n function discardRecording() {\n recorder?.cancel();\n setRecorder(null);\n setAudio(null);\n setRecordSecs(0);\n }\n\n // Shared voice control. `capture` is the prominent in-context affordance on\n // the capture screen (record while the bug is still on screen); `describe`\n // is the labelled form row on step 2. Both drive the same `audio` state, so\n // a note taken on the capture step shows up already-attached on step 2.\n function renderVoiceNote(variant: \"capture\" | \"describe\") {\n const controls = (\n <div className=\"lumen-audio-row\">\n {!recorder && !audio ? (\n <button\n type=\"button\"\n onClick={startRecording}\n className={\n variant === \"capture\"\n ? \"lumen-voice-capture-btn\"\n : \"lumen-btn-ghost\"\n }\n >\n <IconMic />\n Record voice note\n </button>\n ) : null}\n {recorder ? (\n <>\n <span className=\"lumen-recording\">\n <span className=\"lumen-rec-dot\" aria-hidden=\"true\" />\n <Waveform stream={recorder.stream} />\n <span className=\"lumen-rec-time\">\n {recordSecs}s / {VOICE_MAX_SECONDS}s\n </span>\n </span>\n <button\n type=\"button\"\n onClick={finishRecording}\n className=\"lumen-btn-ghost\"\n >\n Stop\n </button>\n <button\n type=\"button\"\n onClick={discardRecording}\n className=\"lumen-btn-ghost\"\n >\n Cancel\n </button>\n </>\n ) : null}\n {audio && !recorder ? (\n <>\n <AudioPreview blob={audio.blob} durationMs={audio.durationMs} />\n <button\n type=\"button\"\n onClick={() => setAudio(null)}\n className=\"lumen-btn-ghost\"\n >\n Remove\n </button>\n </>\n ) : null}\n </div>\n );\n\n if (variant === \"capture\") {\n return (\n <div className=\"lumen-voice-capture\">\n {controls}\n {!recorder && !audio ? (\n <p className=\"lumen-voice-capture-hint\">\n Say what went wrong while it’s fresh.\n </p>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className=\"lumen-label\">\n <span>Add a voice note (optional)</span>\n {controls}\n </div>\n );\n }\n\n // ── Screen recording (the session lives in the provider so it survives\n // the sheet closing) ─────────────────────────────────────────────────\n async function beginVideoRecording() {\n setVideoError(null);\n try {\n // Closes the sheet; the floating HUD takes over and the sheet reopens\n // with the clip attached when the user stops. The provider path reports\n // start failures inline via the record-start error (not a throw); the\n // browser path throws SCREEN_DENIED if the picker is dismissed.\n await startVideoSession();\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Screen capture unavailable\");\n }\n }\n function discardVideo() {\n setVideo(null);\n }\n\n // ── Navigation ────────────────────────────────────────────────────────\n const captured = phase.kind === \"ready\";\n async function goNext() {\n // Finalize a still-running voice note before advancing. Clicking \"Next\"\n // while recording should stop+keep the take, not silently drop it\n // (awaited so the blob is in state by the time submit reads it).\n if (recorder) await finishRecording();\n if (step === 1) {\n // Seed the review's platform chip from the capture environment (once);\n // the user can still override it before sending. The AnnotationLayer\n // stays mounted, so we flatten lazily in submit() rather than here.\n if (phase.kind === \"ready\" && !source) setSource(deriveSource(phase.capture));\n // → the review detent (editable priority/platform/description → Send).\n setStep(2);\n } else {\n await submit();\n }\n }\n function goBack() {\n if (step > 1) setStep((s) => (s - 1) as Step);\n }\n\n async function submit() {\n if (phase.kind !== \"ready\") return;\n const trimmed = text.trim();\n const { capture: captureResult } = phase;\n setSubmitting(true);\n setProgress(0);\n try {\n // Flatten the (still-mounted) annotation layer now, at send time.\n const flat = await annotationRef.current?.flatten();\n const flatScreenshot = flat ?? captureResult.blob;\n const result = await client.submit(\n {\n rawText: trimmed.length > 0 ? trimmed : undefined,\n category,\n priority: priority || undefined,\n source: source || undefined,\n submitterEmail: submitterEmail.trim() || undefined,\n screenshot: flatScreenshot,\n audio: audio?.blob,\n audioDurationMs: audio?.durationMs,\n video: video?.blob,\n videoDurationMs: video?.durationMs,\n context: captureContext(captureResult),\n },\n {\n onUploadProgress: (fraction) => setProgress(Math.min(0.95, fraction)),\n },\n );\n setProgress(1);\n toast.success(\"Feedback sent — thank you.\");\n void result.id;\n closeCapture();\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Could not submit feedback\");\n setSubmitting(false);\n }\n }\n\n function onBackdropMouseDown(e: React.MouseEvent<HTMLDivElement>) {\n if (e.target === e.currentTarget && !submitting) closeCapture();\n }\n\n const uploadingPct = Math.round(progress * 100);\n const isVideoMethod = method === \"video\";\n // Web-only upgrade: the default screenshot is a DOM rasterization (a\n // reconstruction of the page). Offer a one-tap swap to a pixel-perfect\n // getDisplayMedia capture. Hidden on the native shell — a custom provider\n // already returns a real screenshot there, and iOS has no getDisplayMedia.\n const trueScreenAvailable =\n typeof navigator !== \"undefined\" &&\n !!navigator.mediaDevices?.getDisplayMedia;\n const showExactCapture =\n method === \"shot\" &&\n !capture?.provider &&\n capture?.allowTrueScreen !== false &&\n trueScreenAvailable;\n const nextDisabled =\n (step === 1 && !captured) || submitting;\n const nextLabel =\n step < 3\n ? \"Next\"\n : submitting\n ? uploadingPct < 95\n ? `Uploading ${uploadingPct}%…`\n : \"Almost done…\"\n : \"Send feedback\";\n\n // Stage 2a: once a capture is ready, the capture step renders as a fullscreen\n // markup surface — the screen large + dark surround + floating glass chrome,\n // instead of the boxed sheet view. Other steps keep the normal sheet.\n // Fullscreen surround applies for the entire capture step — the method\n // picker (fallback when auto-capture is unavailable), record prompt, upload\n // picker and \"capturing…\" all share the same dark surround + floating chrome\n // instead of the old boxed wizard.\n const captureFullscreen = step === 1;\n // The review detent (step 2) is also a fullscreen surface — the dimmed,\n // annotated capture sits behind the raised panel — so it reuses the same\n // chrome-hiding `data-lumen-fs` styling.\n const reviewFullscreen = step === 2 && phase.kind === \"ready\";\n const fsMode = captureFullscreen || reviewFullscreen;\n\n return (\n <div\n ref={backdropRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Send feedback\"\n className=\"lumen-modal-backdrop\"\n data-lumen-capture-ignore=\"true\"\n style={\n keyboard.inset\n ? ({\n \"--lumen-keyboard-inset\": `${keyboard.inset}px`,\n } as CSSProperties)\n : undefined\n }\n onMouseDown={onBackdropMouseDown}\n >\n <div\n ref={modalRef}\n className=\"lumen-modal\"\n data-lumen-drawing={drawing ? \"true\" : undefined}\n data-lumen-fs={fsMode ? \"true\" : undefined}\n data-lumen-review={reviewFullscreen ? \"true\" : undefined}\n data-lumen-sheet={\n captureFullscreen && sheetCollapsed ? \"down\" : undefined\n }\n >\n <SheetGrabber onDismiss={closeCapture} />\n\n <header className=\"lumen-modal-header\">\n <h2 className=\"lumen-modal-title\">\n <span className=\"lumen-modal-title-dot\" aria-hidden=\"true\" />\n Send feedback\n </h2>\n <button\n type=\"button\"\n onClick={closeCapture}\n className=\"lumen-icon-btn\"\n aria-label=\"Close\"\n >\n ×\n </button>\n </header>\n\n <Stepper step={step} />\n\n {/* Always-mounted picker the Upload method opens directly (no boxed\n intermediate). Image → annotatable; video → poster + attachment. */}\n <input\n ref={uploadInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/webp,video/mp4,video/webm,video/quicktime\"\n style={{ display: \"none\" }}\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n if (file) void acceptUploadedFile(file);\n e.currentTarget.value = \"\";\n }}\n />\n\n <div className=\"lumen-modal-body\">\n {/* ── STEP 1 Capture + STEP 2 Review share one pane so the\n AnnotationLayer stays mounted across Next/Back — going back never\n recaptures or loses the markup (recapture is explicit only). ── */}\n {step === 1 || step === 2 ? (\n <div className=\"lumen-pane\">\n {method === null ? (\n <>\n <div className=\"lumen-fs-top\">\n <div className=\"lumen-fs-toprow lumen-fs-row-corners\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip lumen-fs-x\"\n onClick={closeCapture}\n aria-label=\"Close\"\n >\n ✕\n </button>\n </div>\n </div>\n <div className=\"lumen-fs-center lumen-fs-picker\">\n <div className=\"lumen-fs-picker-head\">\n <div className=\"lumen-fs-picker-title\">\n How do you want to capture?\n </div>\n <div className=\"lumen-fs-picker-sub\">\n Pick a method to report this.\n </div>\n </div>\n <div\n className=\"lumen-method\"\n role=\"group\"\n aria-label=\"Capture method\"\n >\n {METHODS.map((m) => {\n const Icon = METHOD_ICONS[m.value];\n return (\n <button\n key={m.value}\n type=\"button\"\n className={\n \"lumen-method-btn\" +\n (m.primary ? \" lumen-method-primary\" : \"\")\n }\n onClick={() => selectMethod(m.value)}\n disabled={phase.kind === \"capturing\"}\n >\n <span className=\"lumen-method-ico\">\n <Icon />\n </span>\n {m.primary ? (\n <>\n <span className=\"lumen-method-text\">\n <span className=\"lumen-method-label\">\n {m.label}\n </span>\n <span className=\"lumen-method-hint\">\n {m.hint}\n </span>\n </span>\n <span className=\"lumen-method-badge\">Fastest</span>\n </>\n ) : (\n <>\n <span className=\"lumen-method-label\">\n {m.label}\n </span>\n <span className=\"lumen-method-hint\">{m.hint}</span>\n </>\n )}\n </button>\n );\n })}\n </div>\n </div>\n </>\n ) : (\n <>\n {/* Pre-capture states (record prompt · upload picker ·\n capturing) live inside the same fullscreen surround:\n floating ✕ + method pill on top, prompt centered below. */}\n {phase.kind !== \"ready\" ? (\n <>\n <div className=\"lumen-fs-top\">\n <div className=\"lumen-fs-toprow lumen-fs-row-corners\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip lumen-fs-x\"\n onClick={closeCapture}\n aria-label=\"Close\"\n >\n ✕\n </button>\n </div>\n <div className=\"lumen-fs-toprow lumen-fs-row-pill\">\n <div\n className=\"lumen-fs-pill\"\n role=\"group\"\n aria-label=\"Capture method\"\n >\n {METHODS.map((m) => {\n const Icon = METHOD_ICONS[m.value];\n return (\n <button\n key={m.value}\n type=\"button\"\n className=\"lumen-fs-pill-btn\"\n aria-pressed={method === m.value}\n aria-label={m.label}\n onClick={() => selectMethod(m.value)}\n disabled={phase.kind === \"capturing\"}\n >\n <Icon />\n </button>\n );\n })}\n </div>\n </div>\n </div>\n\n <div className=\"lumen-fs-center\">\n {method === \"video\" && phase.kind === \"idle\" ? (\n <RecordPrompt\n canRecord={canRecordScreen}\n onRecord={beginVideoRecording}\n onUpload={() => selectMethod(\"upload\")}\n error={videoError}\n />\n ) : null}\n\n {phase.kind === \"capturing\" ? (\n <p className=\"lumen-status\">\n <span className=\"lumen-spinner\" aria-hidden=\"true\" />\n Capturing…\n </p>\n ) : null}\n\n {phase.kind === \"manual\" ? (\n <div className=\"lumen-manual-capture\">\n <p className=\"lumen-status\">\n {method === \"upload\"\n ? \"Choose an image or video to attach — or paste an image.\"\n : phase.error\n ? \"Automatic capture was unavailable. Upload or paste an image to continue.\"\n : \"Upload or paste an image to continue.\"}\n </p>\n <label className=\"lumen-manual-drop\">\n <span>\n {method === \"upload\"\n ? \"Choose a file — image or video\"\n : \"Choose or paste an image\"}\n </span>\n <input\n type=\"file\"\n accept={\n method === \"upload\"\n ? \"image/png,image/jpeg,image/webp,video/mp4,video/webm,video/quicktime\"\n : \"image/png,image/jpeg,image/webp\"\n }\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n if (file) void acceptUploadedFile(file);\n e.currentTarget.value = \"\";\n }}\n />\n </label>\n </div>\n ) : null}\n </div>\n </>\n ) : null}\n\n {phase.kind === \"ready\" ? (\n <>\n {/* markup-only chrome (hidden once we're on the review step) */}\n {step === 1 ? (\n <>\n <div className=\"lumen-fs-top\">\n <div className=\"lumen-fs-toprow lumen-fs-row-corners\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip lumen-fs-x\"\n onClick={closeCapture}\n aria-label=\"Close\"\n >\n ✕\n </button>\n <div className=\"lumen-fs-recap\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip\"\n onClick={() => setRecapMenuOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={recapMenuOpen}\n >\n <IconRefresh /> Recapture\n <svg\n width=\"11\"\n height=\"11\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ opacity: 0.6 }}\n aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </button>\n {recapMenuOpen ? (\n <>\n <div\n className=\"lumen-fs-recap-overlay\"\n onClick={() => setRecapMenuOpen(false)}\n />\n <div className=\"lumen-fs-recap-menu\" role=\"menu\">\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => {\n setRecapMenuOpen(false);\n if (method) selectMethod(method);\n }}\n >\n <span className=\"lumen-fs-mi-ic\">\n <IconRefresh />\n </span>\n <span>\n <b>Re-snap this view</b>\n <small>Instant · masks sensitive fields</small>\n </span>\n </button>\n {showExactCapture ? (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => {\n setRecapMenuOpen(false);\n void startScreenCaptureSession();\n }}\n >\n <span className=\"lumen-fs-mi-ic\">\n <IconMonitor />\n </span>\n <span>\n <b>Capture exact pixels</b>\n <small>\n Real screen — canvas, video & charts\n </small>\n </span>\n </button>\n ) : null}\n </div>\n </>\n ) : null}\n </div>\n </div>\n <div className=\"lumen-fs-toprow lumen-fs-row-pill\">\n <div\n className=\"lumen-fs-pill\"\n role=\"group\"\n aria-label=\"Tools and capture method\"\n >\n {!isVideoMethod ? (\n <>\n <button\n type=\"button\"\n className=\"lumen-fs-pill-btn lumen-fs-pentog\"\n data-on={!toolsHidden}\n onClick={() => setToolsHidden((h) => !h)}\n aria-label=\"Toggle markup tools\"\n title=\"Toggle markup tools\"\n >\n <IconDraw />\n </button>\n <span className=\"lumen-fs-pill-sep\" />\n </>\n ) : null}\n {METHODS.map((m) => {\n const Icon = METHOD_ICONS[m.value];\n return (\n <button\n key={m.value}\n type=\"button\"\n className=\"lumen-fs-pill-btn\"\n aria-pressed={method === m.value}\n aria-label={m.label}\n onClick={() => selectMethod(m.value)}\n >\n <Icon />\n </button>\n );\n })}\n </div>\n </div>\n </div>\n {!isVideoMethod && !toolsHidden ? (\n <div className=\"lumen-toolbar\">\n <div\n className=\"lumen-segmented\"\n role=\"group\"\n aria-label=\"Annotation tool\"\n >\n <ToolButton\n label=\"Arrow\"\n icon={<IconArrow />}\n active={tool === \"arrow\"}\n onClick={() => setTool(\"arrow\")}\n />\n <ToolButton\n label=\"Box\"\n icon={<IconBox />}\n active={tool === \"rect\"}\n onClick={() => setTool(\"rect\")}\n />\n <ToolButton\n label=\"Draw\"\n icon={<IconDraw />}\n active={tool === \"freehand\"}\n onClick={() => setTool(\"freehand\")}\n />\n <ToolButton\n label=\"Comment\"\n icon={<IconComment />}\n active={tool === \"comment\"}\n onClick={() => setTool(\"comment\")}\n />\n </div>\n <span className=\"lumen-toolbar-sep\" />\n <div className=\"lumen-fs-color\">\n <button\n type=\"button\"\n className=\"lumen-fs-color-btn\"\n style={{ background: strokeColor }}\n aria-label=\"Pick colour\"\n aria-haspopup=\"true\"\n aria-expanded={colorPickerOpen}\n onClick={() => setColorPickerOpen((o) => !o)}\n />\n {colorPickerOpen ? (\n <>\n <div\n className=\"lumen-fs-color-overlay\"\n onClick={() => setColorPickerOpen(false)}\n />\n <div\n className=\"lumen-fs-color-pop\"\n role=\"group\"\n aria-label=\"Colour\"\n >\n {SWATCHES.map((s) => (\n <button\n key={s.value}\n type=\"button\"\n className=\"lumen-swatch\"\n style={{ background: s.value }}\n aria-label={s.label}\n aria-pressed={strokeColor === s.value}\n onClick={() => {\n setStrokeColor(s.value);\n setColorPickerOpen(false);\n }}\n />\n ))}\n </div>\n </>\n ) : null}\n </div>\n {!captureFullscreen ? (\n <div\n className=\"lumen-stroke-sizes\"\n role=\"group\"\n aria-label=\"Stroke width\"\n >\n {STROKE_SIZES.map((s) => (\n <button\n key={s.value}\n type=\"button\"\n className=\"lumen-stroke-size\"\n aria-label={s.label}\n aria-pressed={strokeWidth === s.value}\n onClick={() => setStrokeWidth(s.value)}\n >\n <span\n className=\"lumen-stroke-size-dot\"\n style={{ width: s.dot, height: s.dot }}\n />\n </button>\n ))}\n </div>\n ) : null}\n {!captureFullscreen ? (\n <span className=\"lumen-toolbar-spacer\" />\n ) : null}\n <button\n type=\"button\"\n className=\"lumen-tool\"\n onClick={() => annotationRef.current?.undo()}\n disabled={!history.canUndo}\n aria-label=\"Undo\"\n title=\"Undo\"\n >\n <IconUndo />\n </button>\n <button\n type=\"button\"\n className=\"lumen-tool\"\n onClick={() => annotationRef.current?.redo()}\n disabled={!history.canRedo}\n aria-label=\"Redo\"\n title=\"Redo\"\n >\n <IconRedo />\n </button>\n <button\n type=\"button\"\n className=\"lumen-tool\"\n onClick={() => annotationRef.current?.reset()}\n disabled={!history.canUndo}\n aria-label=\"Clear\"\n title=\"Clear\"\n >\n <IconTrash />\n </button>\n </div>\n ) : null}\n </>\n ) : null}\n\n <div className=\"lumen-annotate\">\n <AnnotationLayer\n ref={annotationRef}\n screenshot={phase.capture.blob}\n tool={tool}\n color={strokeColor}\n strokeWidth={strokeWidth}\n onDrawingChange={setDrawing}\n onHistoryChange={setHistory}\n />\n </div>\n\n {step === 1 ? (\n <>\n <div className=\"lumen-cap-actions\">\n <button\n type=\"button\"\n className=\"lumen-btn-ghost\"\n onClick={() => method && selectMethod(method)}\n >\n {isVideoMethod ? \"↻ Re-record\" : \"↻ Recapture\"}\n </button>\n {showExactCapture ? (\n <button\n type=\"button\"\n className=\"lumen-btn-ghost lumen-exact-btn\"\n onClick={() => void startScreenCaptureSession()}\n title=\"Capture the real screen pixels — your browser will ask which tab or window to share, then you arrange the page and press Capture.\"\n >\n <IconMonitor /> Capture exact screen\n </button>\n ) : null}\n {isVideoMethod ? (\n video ? (\n <span className=\"lumen-cap-note\">\n ✓ {Math.round(video.durationMs / 1000)}s recorded\n </span>\n ) : null\n ) : (\n <span className=\"lumen-cap-note\">\n {phase.capture.method === \"web-display-media\"\n ? \"Exact screen captured\"\n : `${captureLabel(method)} captured · switch method above anytime`}\n </span>\n )}\n </div>\n\n <div className=\"lumen-fs-compose\">\n <button\n type=\"button\"\n className=\"lumen-fs-grab\"\n onClick={() => setSheetCollapsed((c) => !c)}\n aria-label={\n sheetCollapsed ? \"Expand sheet\" : \"Minimize sheet\"\n }\n />\n <div className=\"lumen-fs-field\">\n <input\n className=\"lumen-input lumen-fs-desc\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"Describe what's wrong — or use voice\"\n />\n <button\n type=\"button\"\n className=\"lumen-fs-mic\"\n onClick={startRecording}\n aria-label=\"Record voice note\"\n >\n <IconMic />\n </button>\n </div>\n {renderVoiceNote(\"capture\")}\n <button\n type=\"button\"\n className=\"lumen-btn-primary lumen-fs-next\"\n onClick={goNext}\n disabled={nextDisabled}\n >\n Next\n </button>\n </div>\n </>\n ) : null}\n </>\n ) : null}\n </>\n )}\n </div>\n ) : null}\n\n {/* ── STEP 2 — Review & send (detent over the dimmed capture) ── */}\n {step === 2 ? (\n <div className=\"lumen-pane lumen-rv-pane\">\n {/* the dimmed capture behind is the still-mounted AnnotationLayer\n from the shared pane — showing live strokes, not a snapshot */}\n <div className=\"lumen-rv-scrim\" aria-hidden=\"true\" />\n\n <div className=\"lumen-rv\">\n <div className=\"lumen-rv-head\">\n <button\n type=\"button\"\n className=\"lumen-rv-back\"\n onClick={goBack}\n >\n <IconChevronLeft />\n Back\n </button>\n <span className=\"lumen-rv-title\">Review & send</span>\n <span className=\"lumen-rv-spacer\" aria-hidden=\"true\" />\n </div>\n\n <div className=\"lumen-rv-rows\">\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">\n Description{\" \"}\n <span className=\"lumen-rv-muted\">· tap to edit</span>\n </span>\n <textarea\n className=\"lumen-input lumen-rv-desc\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n rows={2}\n placeholder=\"Describe what's wrong…\"\n />\n </div>\n\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">Type</span>\n <div\n className=\"lumen-rv-chips\"\n role=\"group\"\n aria-label=\"Type\"\n >\n {CATEGORIES.map((c) => (\n <button\n key={c.value}\n type=\"button\"\n className=\"lumen-rv-chip\"\n aria-pressed={category === c.value}\n onClick={() => setCategory(c.value)}\n >\n {c.label}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">Priority</span>\n <div\n className=\"lumen-rv-prio\"\n role=\"group\"\n aria-label=\"Priority\"\n >\n {PRIORITIES.filter(\n (p): p is { value: FeedbackPriority; label: string } =>\n p.value !== \"\",\n ).map((p) => (\n <button\n key={p.value}\n type=\"button\"\n className=\"lumen-rv-prio-opt\"\n aria-pressed={priority === p.value}\n onClick={() =>\n setPriority(priority === p.value ? \"\" : p.value)\n }\n >\n <PriorityIcon value={p.value} />\n {p.label}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">\n Platform{\" \"}\n <span className=\"lumen-rv-muted\">\n · auto-detected — change if wrong\n </span>\n </span>\n <div\n className=\"lumen-rv-chips\"\n role=\"group\"\n aria-label=\"Platform\"\n >\n {SOURCE_CHIPS.map((s) => (\n <button\n key={s.value}\n type=\"button\"\n className=\"lumen-rv-chip\"\n aria-pressed={source === s.value}\n onClick={() => setSource(s.value)}\n >\n {s.label}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"lumen-rv-row\">\n <span className=\"lumen-rv-rk\">Capture</span>\n <span className=\"lumen-rv-rv\">\n {captureLabel(method)}\n {history.canUndo ? \" · annotated\" : \"\"}\n <button\n type=\"button\"\n className=\"lumen-edit\"\n onClick={() => setStep(1)}\n >\n edit\n </button>\n </span>\n </div>\n\n {renderVoiceNote(\"describe\")}\n\n <div className=\"lumen-rv-attachrow\">\n {video ? (\n <span className=\"lumen-attach\">\n ▶ Video {Math.round(video.durationMs / 1000)}s\n <button\n type=\"button\"\n className=\"lumen-att-x\"\n aria-label=\"Remove video\"\n onClick={discardVideo}\n >\n ×\n </button>\n </span>\n ) : (\n <label className=\"lumen-rv-attach\">\n <IconUpload />\n Attach a video\n <input\n type=\"file\"\n accept=\"video/mp4,video/webm,video/quicktime\"\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n if (file)\n setVideo({ blob: file, durationMs: 0 });\n e.currentTarget.value = \"\";\n }}\n />\n </label>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n className=\"lumen-btn-primary lumen-rv-send\"\n onClick={submit}\n disabled={submitting}\n >\n {submitting ? (\n uploadingPct < 95 ? (\n `Uploading ${uploadingPct}%…`\n ) : (\n \"Almost done…\"\n )\n ) : (\n <>\n <IconSend />\n Send feedback\n </>\n )}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n\n <footer className=\"lumen-modal-footer\">\n {submitting ? (\n <div\n className=\"lumen-progress\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={uploadingPct}\n >\n <div\n className=\"lumen-progress-fill\"\n style={{ width: `${uploadingPct}%` }}\n />\n </div>\n ) : null}\n <div className=\"lumen-modal-actions\">\n <button\n type=\"button\"\n onClick={step === 1 ? closeCapture : goBack}\n className=\"lumen-btn-ghost\"\n disabled={submitting}\n >\n {step === 1 ? \"Cancel\" : \"Back\"}\n </button>\n <button\n type=\"button\"\n onClick={goNext}\n className=\"lumen-btn-primary\"\n disabled={nextDisabled}\n >\n {nextLabel}\n </button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n\nfunction captureLabel(method: CaptureMethod | null): string {\n if (method === \"video\") return \"Screen recording\";\n if (method === \"upload\") return \"Upload\";\n return \"Screenshot\";\n}\n\nfunction Stepper({ step }: { step: Step }) {\n const steps = [\n { n: 1, label: \"Capture\" },\n { n: 2, label: \"Describe\" },\n { n: 3, label: \"Review\" },\n ] as const;\n return (\n <div className=\"lumen-stepper\" aria-hidden=\"true\">\n {steps.map((s, i) => (\n <div\n key={s.n}\n className={\n \"lumen-step\" +\n (step === s.n ? \" lumen-step-active\" : \"\") +\n (step > s.n ? \" lumen-step-done\" : \"\")\n }\n >\n <span className=\"lumen-step-num\">{s.n}</span>\n <span className=\"lumen-step-lbl\">{s.label}</span>\n {i < steps.length - 1 ? <span className=\"lumen-step-bar\" /> : null}\n </div>\n ))}\n </div>\n );\n}\n\nfunction RecordPrompt({\n canRecord,\n onRecord,\n onUpload,\n error,\n}: {\n canRecord: boolean;\n onRecord: () => void;\n onUpload: () => void;\n error?: string | null;\n}) {\n if (!canRecord) {\n return (\n <div className=\"lumen-record-prompt\">\n <p className=\"lumen-record-unavailable\">\n {isIOSBrowser() ? (\n <>\n Screen recording isn’t available on iOS browsers. Record with\n Control Center’s screen recorder, then attach the clip below.\n </>\n ) : (\n <>\n Screen recording isn’t available in this browser. Upload a video\n to attach one instead.\n </>\n )}\n </p>\n <button\n type=\"button\"\n className=\"lumen-btn-primary lumen-record-upload\"\n onClick={onUpload}\n >\n Upload a video\n </button>\n </div>\n );\n }\n return (\n <div className=\"lumen-record-prompt\">\n {error ? (\n <p className=\"lumen-record-unavailable\" role=\"alert\">\n {error} Try again, or switch to <strong>Upload</strong> to attach a\n video instead.\n </p>\n ) : null}\n <button\n type=\"button\"\n className=\"lumen-record-btn\"\n aria-label=\"Start screen recording\"\n onClick={onRecord}\n />\n <div className=\"lumen-record-copy\">\n <div className=\"lumen-record-title\">Record your screen</div>\n <div className=\"lumen-record-sub\">\n Tap to start. The sheet closes so you can record freely — a Stop\n button stays on screen, then the sheet returns with your clip. Max\n 60s.\n </div>\n </div>\n </div>\n );\n}\n\n/** Best-effort iOS detection for the actionable \"no screen recording\" copy.\n * Covers iPhone/iPad (incl. iPadOS reporting as Macintosh with touch). */\nfunction isIOSBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n const ua = navigator.userAgent || \"\";\n if (/iPad|iPhone|iPod/.test(ua)) return true;\n return (\n /Macintosh/.test(ua) &&\n typeof document !== \"undefined\" &&\n \"ontouchend\" in document\n );\n}\n\nfunction ToolButton({\n label,\n active,\n onClick,\n icon,\n}: {\n label: string;\n active: boolean;\n onClick: () => void;\n icon?: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"lumen-tool\"\n aria-pressed={active}\n aria-label={icon ? label : undefined}\n title={label}\n >\n {icon ?? label}\n </button>\n );\n}\n\n/** Mobile sheet drag-to-dismiss handle. Hidden on ≥ 640px via CSS. */\nfunction SheetGrabber({ onDismiss }: { onDismiss: () => void }) {\n const startYRef = useRef<number | null>(null);\n const startTimeRef = useRef<number>(0);\n const targetRef = useRef<HTMLElement | null>(null);\n\n function onPointerDown(e: React.PointerEvent<HTMLDivElement>) {\n e.currentTarget.setPointerCapture(e.pointerId);\n startYRef.current = e.clientY;\n startTimeRef.current = performance.now();\n targetRef.current = e.currentTarget.parentElement;\n }\n function onPointerMove(e: React.PointerEvent<HTMLDivElement>) {\n if (startYRef.current == null || !targetRef.current) return;\n const dy = Math.max(0, e.clientY - startYRef.current);\n targetRef.current.style.transform = `translateY(${dy}px)`;\n }\n function onPointerUp(e: React.PointerEvent<HTMLDivElement>) {\n if (startYRef.current == null || !targetRef.current) return;\n const dy = Math.max(0, e.clientY - startYRef.current);\n const dt = Math.max(1, performance.now() - startTimeRef.current);\n const velocity = dy / dt;\n targetRef.current.style.transform = \"\";\n targetRef.current.style.transition = \"\";\n startYRef.current = null;\n if (dy > 80 || velocity > 0.6) onDismiss();\n }\n\n return (\n <div\n className=\"lumen-modal-grabber\"\n aria-hidden=\"true\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n />\n );\n}\n\n/** Live mic level visualisation. Reads time-domain samples from the\n * recorder stream and renders a centred series of rounded bars that\n * ease toward each new amplitude. AudioContext + AnalyserNode are torn\n * down on unmount so the mic isn't held open by a stale graph. */\nfunction Waveform({ stream }: { stream: MediaStream }) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n const cssWidth = canvas.clientWidth || 88;\n const cssHeight = canvas.clientHeight || 22;\n canvas.width = Math.round(cssWidth * dpr);\n canvas.height = Math.round(cssHeight * dpr);\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.scale(dpr, dpr);\n\n const AudioCtor: typeof AudioContext | undefined =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext?: typeof AudioContext })\n .webkitAudioContext;\n if (!AudioCtor) return;\n const audioCtx = new AudioCtor();\n const source = audioCtx.createMediaStreamSource(stream);\n const analyser = audioCtx.createAnalyser();\n analyser.fftSize = 1024;\n analyser.smoothingTimeConstant = 0.6;\n source.connect(analyser);\n const data = new Uint8Array(analyser.fftSize);\n\n const BARS = 18;\n const GAP = 3;\n const MIN_H = 3;\n const barW = Math.max(2, (cssWidth - GAP * (BARS - 1)) / BARS);\n const radius = Math.min(barW / 2, 3);\n const levels = new Array<number>(BARS).fill(0);\n\n let raf = 0;\n let cancelled = false;\n function frame() {\n if (cancelled) return;\n analyser.getByteTimeDomainData(data);\n const bucketSize = Math.floor(data.length / BARS);\n ctx!.clearRect(0, 0, cssWidth, cssHeight);\n ctx!.fillStyle = getCssVar(\"--lumen-danger\") || \"rgb(239,68,68)\";\n for (let i = 0; i < BARS; i++) {\n let peak = 0;\n for (let j = 0; j < bucketSize; j++) {\n const v = Math.abs((data[i * bucketSize + j] ?? 128) - 128);\n if (v > peak) peak = v;\n }\n const target = Math.min(1, (peak / 128) * 1.8);\n const cur = levels[i] ?? 0;\n levels[i] = target > cur ? target : cur + (target - cur) * 0.35;\n const h = Math.max(MIN_H, levels[i]! * cssHeight);\n const x = i * (barW + GAP);\n const y = (cssHeight - h) / 2;\n roundRectPath(ctx!, x, y, barW, h, radius);\n ctx!.fill();\n }\n raf = requestAnimationFrame(frame);\n }\n raf = requestAnimationFrame(frame);\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(raf);\n try {\n source.disconnect();\n } catch {\n /* ignore */\n }\n void audioCtx.close();\n };\n }, [stream]);\n\n return <canvas ref={canvasRef} className=\"lumen-waveform\" aria-hidden=\"true\" />;\n}\n\n/** Trace a rounded-rect path. Uses native `roundRect` when present and\n * falls back to manual arcs for older Safari/Firefox. */\nfunction roundRectPath(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): void {\n const radius = Math.min(r, w / 2, h / 2);\n ctx.beginPath();\n const anyCtx = ctx as CanvasRenderingContext2D & {\n roundRect?: (x: number, y: number, w: number, h: number, r: number) => void;\n };\n if (typeof anyCtx.roundRect === \"function\") {\n anyCtx.roundRect(x, y, w, h, radius);\n return;\n }\n ctx.moveTo(x + radius, y);\n ctx.arcTo(x + w, y, x + w, y + h, radius);\n ctx.arcTo(x + w, y + h, x, y + h, radius);\n ctx.arcTo(x, y + h, x, y, radius);\n ctx.arcTo(x, y, x + w, y, radius);\n ctx.closePath();\n}\n\n/** Preview the recorded clip with a native <audio> element. ObjectURL is\n * revoked on unmount/swap to avoid leaking the blob into memory. */\nfunction AudioPreview({ blob, durationMs }: { blob: Blob; durationMs: number }) {\n const [url, setUrl] = useState<string>(\"\");\n useEffect(() => {\n const u = URL.createObjectURL(blob);\n setUrl(u);\n return () => {\n URL.revokeObjectURL(u);\n };\n }, [blob]);\n return (\n <div className=\"lumen-audio-preview\">\n <audio controls preload=\"metadata\" src={url} className=\"lumen-audio-el\" />\n <span className=\"lumen-audio-meta\">{Math.round(durationMs / 1000)}s</span>\n </div>\n );\n}\n\nfunction getCssVar(name: string): string {\n if (typeof window === \"undefined\") return \"\";\n return getComputedStyle(document.documentElement)\n .getPropertyValue(name)\n .trim();\n}\n\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(\n root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((el) => !el.hasAttribute(\"disabled\") && el.offsetParent !== null);\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\n\ninterface LumenErrorBoundaryProps {\n /**\n * Called once after the boundary catches an error. The provider uses this to\n * return to a clean, reopenable state (close the sheet + remount this\n * boundary via a fresh key) so a single crash never strands the widget.\n */\n onReset: () => void;\n /**\n * Best-effort crash telemetry. Called with the caught error + React\n * component stack so the provider can beacon it to the dashboard — this is\n * how we learn WHY the widget \"hit a snag\" in production. Purely additive;\n * recovery does not depend on it.\n */\n onError?: (report: {\n message: string;\n name: string;\n stack?: string;\n componentStack?: string;\n }) => void;\n children: React.ReactNode;\n}\n\ninterface LumenErrorBoundaryState {\n hasError: boolean;\n}\n\n/**\n * Wraps Lumen's own UI (triggers, capture sheet, recording HUD) so a render or\n * commit error inside the widget can never unmount the HOST app's React tree —\n * which is exactly what produced the iOS \"white screen\": an uncaught throw from\n * the capture path (e.g. an out-of-memory failure when html2canvas runs twice\n * in quick succession) bubbling past Lumen into the host with no boundary to\n * stop it.\n *\n * On catch it renders nothing, runs the cleanup the now-unmounted sheet can no\n * longer do (release the body scroll-lock + `data-lumen-open` flag), surfaces an\n * apology toast, and asks the provider to reset so the user can try again.\n */\nexport class LumenErrorBoundary extends React.Component<\n LumenErrorBoundaryProps,\n LumenErrorBoundaryState\n> {\n override state: LumenErrorBoundaryState = { hasError: false };\n\n static getDerivedStateFromError(): LumenErrorBoundaryState {\n return { hasError: true };\n }\n\n override componentDidCatch(error: unknown, info: React.ErrorInfo): void {\n // The CaptureModal sets these on document.documentElement / body while open\n // and restores them in effect cleanups. When the modal unmounts via a throw,\n // those cleanups still run — but if the error came from elsewhere in the\n // subtree we clear them defensively so the page can never be left\n // unscrollable or flagged open.\n if (typeof document !== \"undefined\") {\n const html = document.documentElement;\n html.style.overflow = \"\";\n html.style.paddingRight = \"\";\n document.body.removeAttribute(\"data-lumen-open\");\n }\n\n // eslint-disable-next-line no-console\n console.error(\"[lumen] recovered from a widget error:\", error);\n toast.error(\"Feedback widget hit a snag and was reset. Please try again.\");\n\n // Best-effort telemetry: report the real exception + component stack so we\n // can see (not guess) why the widget crashes in production. Wrapped so a\n // telemetry hiccup can never break the recovery below.\n try {\n const err = error instanceof Error ? error : null;\n this.props.onError?.({\n message: err?.message ?? String(error),\n name: err?.name ?? \"Error\",\n stack: err?.stack,\n componentStack: info?.componentStack ?? undefined,\n });\n } catch {\n // ignore\n }\n\n // Reset on a microtask so this commit-phase handler finishes first; the\n // provider closes the sheet and remounts this boundary with a fresh key.\n Promise.resolve().then(() => this.props.onReset());\n }\n\n override render(): React.ReactNode {\n if (this.state.hasError) return null;\n return this.props.children;\n }\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { VideoRecordingState } from \"./context\";\n\n/**\n * Floating recording control that persists while the sheet is closed during a\n * screen recording. Portaled to the body (outside the sheet) so it survives\n * the modal being unmounted. Stop returns the sheet with the clip attached;\n * the timer counts toward the max-duration cap.\n *\n * Note: on web, getDisplayMedia records the visible screen/tab, so this HUD\n * may appear in the recording when the user shares the same tab. That's an\n * inherent browser limitation — the alternative is the browser's own \"Stop\n * sharing\" bar, which also funnels through to reopen the sheet.\n *\n * The `starting`/`processing` phases only occur on the custom/native\n * `record.provider` path (consent window before the clip starts; encode +\n * transfer window after Stop). The browser path only ever renders `recording`.\n */\nexport function RecordingHud({\n state,\n portalTarget,\n onStop,\n onCancel,\n}: {\n state: VideoRecordingState;\n portalTarget?: HTMLElement;\n onStop: () => void;\n onCancel: () => void;\n}) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (!mounted || typeof document === \"undefined\") return null;\n\n const target = portalTarget ?? document.body;\n\n if (state.phase === \"recording\") {\n return createPortal(\n <RecordingControl\n startedAt={state.startedAt}\n maxSeconds={state.maxSeconds}\n onStop={onStop}\n onCancel={onCancel}\n />,\n target,\n );\n }\n\n // Provider-only transient phases: a compact status pill with no timer. During\n // `starting` the native consent dialog is on screen; during `processing` the\n // clip is encoding/transferring. Discard stays available so the user is never\n // trapped if a native step hangs.\n return createPortal(\n <div\n className=\"lumen-rec-hud lumen-rec-hud-pending\"\n role=\"status\"\n aria-live=\"polite\"\n data-lumen-root=\"true\"\n data-lumen-capture-ignore=\"true\"\n >\n <span className=\"lumen-rec-hud-spinner\" aria-hidden=\"true\" />\n <span className=\"lumen-rec-hud-time\">\n {state.phase === \"starting\" ? \"Starting…\" : \"Processing…\"}\n </span>\n <button\n type=\"button\"\n className=\"lumen-rec-hud-cancel\"\n onClick={onCancel}\n aria-label=\"Discard recording\"\n >\n Discard\n </button>\n </div>,\n target,\n );\n}\n\n/** The live-recording control — markup unchanged from the original HUD so the\n * browser recording experience is byte-identical. */\nfunction RecordingControl({\n startedAt,\n maxSeconds,\n onStop,\n onCancel,\n}: {\n startedAt: number;\n maxSeconds: number;\n onStop: () => void;\n onCancel: () => void;\n}) {\n const [elapsed, setElapsed] = useState(0);\n\n useEffect(() => {\n const tick = () =>\n setElapsed(\n Math.min(maxSeconds, Math.max(0, Math.floor((Date.now() - startedAt) / 1000))),\n );\n tick();\n const id = window.setInterval(tick, 250);\n return () => window.clearInterval(id);\n }, [startedAt, maxSeconds]);\n\n const fmt = (s: number) =>\n `${Math.floor(s / 60)}:${String(s % 60).padStart(2, \"0\")}`;\n\n return (\n <div\n className=\"lumen-rec-hud\"\n role=\"status\"\n aria-live=\"polite\"\n data-lumen-root=\"true\"\n data-lumen-capture-ignore=\"true\"\n >\n <span className=\"lumen-rec-hud-dot\" aria-hidden=\"true\" />\n <span className=\"lumen-rec-hud-time\">\n {fmt(elapsed)} <span className=\"lumen-rec-hud-max\">/ {fmt(maxSeconds)}</span>\n </span>\n <button\n type=\"button\"\n className=\"lumen-rec-hud-cancel\"\n onClick={onCancel}\n aria-label=\"Discard recording\"\n >\n Discard\n </button>\n <button\n type=\"button\"\n className=\"lumen-rec-hud-stop\"\n onClick={onStop}\n aria-label=\"Stop recording and return to feedback\"\n >\n <span className=\"lumen-rec-hud-square\" aria-hidden=\"true\" />\n Stop\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { ScreenCaptureState } from \"./context\";\nimport { IconMonitor } from \"./icons\";\n\n/**\n * Floating control for \"Capture exact screen\". After the browser surface picker\n * resolves, the Send-feedback sheet hides and this bar takes over: the user can\n * scroll/arrange the live page, then press Capture to grab the exact pixels.\n *\n * Portaled to the body (outside the sheet) and tagged `data-lumen-root` +\n * `data-lumen-capture-ignore` so the core capture conceals it — along with the\n * rest of Lumen's chrome — at the moment the frame is drawn. That's why the bar\n * itself never ends up in the screenshot, even though the grab records real\n * screen pixels (which the DOM ignore-attribute alone can't exclude).\n */\nexport function ScreenCaptureHud({\n state,\n portalTarget,\n onCapture,\n onCancel,\n}: {\n state: ScreenCaptureState;\n portalTarget?: HTMLElement;\n onCapture: () => void;\n onCancel: () => void;\n}) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (!mounted || typeof document === \"undefined\") return null;\n\n const target = portalTarget ?? document.body;\n const grabbing = state.phase === \"grabbing\";\n\n return createPortal(\n <div\n className=\"lumen-cap-hud\"\n role=\"status\"\n aria-live=\"polite\"\n data-lumen-root=\"true\"\n data-lumen-capture-ignore=\"true\"\n >\n {grabbing ? (\n <span className=\"lumen-cap-hud-spinner\" aria-hidden=\"true\" />\n ) : (\n <span className=\"lumen-cap-hud-ico\" aria-hidden=\"true\">\n <IconMonitor />\n </span>\n )}\n <span className=\"lumen-cap-hud-text\">\n {grabbing ? \"Capturing…\" : \"Arrange the screen, then capture\"}\n </span>\n <button\n type=\"button\"\n className=\"lumen-cap-hud-cancel\"\n onClick={onCancel}\n disabled={grabbing}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"lumen-cap-hud-capture\"\n onClick={onCapture}\n disabled={grabbing}\n aria-label=\"Capture this screen and return to feedback\"\n >\n Capture\n </button>\n </div>,\n target,\n );\n}\n","/**\n * Pure capability resolution for the Record tab. Kept framework-free so it can\n * be unit-tested without a DOM. Mirrors the precedence rules in the SDK spec:\n *\n * - The Record tab is usable when\n * (a record provider is set AND its `isAvailable()` did not return false)\n * OR `getDisplayMedia` exists.\n * - A set, available provider takes precedence over `getDisplayMedia`.\n * - `isAvailable` defaults to \"available\" when omitted, so a not-yet-probed\n * provider (`providerAvailable === null`) is treated as available.\n */\nexport interface RecordCapabilityInput {\n /** Whether a `record.provider` was supplied to <LumenProvider>. */\n hasProvider: boolean;\n /**\n * Result of `record.isAvailable?.()`. `null` means \"not probed / omitted\" —\n * which defaults to available when a provider is set.\n */\n providerAvailable: boolean | null;\n /** Whether `navigator.mediaDevices.getDisplayMedia` exists. */\n hasGetDisplayMedia: boolean;\n}\n\nexport interface RecordCapability {\n /** Whether the Record tab should be offered at all. */\n canRecord: boolean;\n /**\n * Which path a record attempt should take. `true` → call `record.provider`;\n * `false` → use the browser `getDisplayMedia` recorder.\n */\n usingProvider: boolean;\n}\n\nexport function resolveRecordCapability(\n input: RecordCapabilityInput,\n): RecordCapability {\n const providerUsable = input.hasProvider && input.providerAvailable !== false;\n return {\n canRecord: providerUsable || input.hasGetDisplayMedia,\n usingProvider: providerUsable,\n };\n}\n","import {\n type LumenRecordProvider,\n type LumenRecordingResult,\n type LumenRecordingSession,\n} from \"@lumen-stack/core\";\n\n/**\n * Framework-free orchestrator for a custom/native record provider. All of the\n * lifecycle branching lives here (start window, cancel-during-start, manual\n * stop vs. provider auto-stop, RECORDER_STOPPED swallowing) so the React glue\n * can be nothing but `setState`, and so the behavior is unit-testable without a\n * DOM.\n *\n * Lifecycle → callback mapping:\n * onStarting — provider invoked, awaiting the session (native consent window)\n * onActive — session is live (stream may be null for native hosts)\n * onProcessing— manual stop requested, awaiting the encoded clip\n * onResult — clip arrived (manual stop OR provider auto-stop at the cap)\n * onCancelled — cancelled at start or mid-recording (RECORDER_STOPPED swallowed)\n * onError — provider failed to start, or the clip failed to arrive\n *\n * Exactly one terminal callback (onResult | onCancelled | onError) fires.\n */\nexport interface RecordSessionCallbacks {\n onStarting(): void;\n onActive(session: LumenRecordingSession): void;\n onProcessing(): void;\n onResult(result: LumenRecordingResult): void;\n onCancelled(): void;\n onError(error: Error): void;\n}\n\nexport interface RecordSessionControl {\n /** Stop and keep the clip; it arrives via onResult after onProcessing. */\n stop(): void;\n /** Abort and discard; resolves to onCancelled. */\n cancel(): void;\n}\n\nfunction isRecorderStopped(err: unknown): boolean {\n return (\n typeof err === \"object\" &&\n err !== null &&\n (err as { code?: unknown }).code === \"RECORDER_STOPPED\"\n );\n}\n\nfunction asError(err: unknown): Error {\n return err instanceof Error ? err : new Error(String(err));\n}\n\nexport function driveRecordSession(\n provider: LumenRecordProvider,\n options: { maxDurationSeconds: number },\n cb: RecordSessionCallbacks,\n): RecordSessionControl {\n let cancelled = false;\n let settled = false; // a terminal callback has fired\n let stopRequested = false;\n let session: LumenRecordingSession | null = null;\n\n function finishCancelled() {\n if (settled) return;\n settled = true;\n cb.onCancelled();\n }\n function finishResult(result: LumenRecordingResult) {\n if (settled) return;\n settled = true;\n cb.onResult(result);\n }\n function finishError(error: Error) {\n if (settled) return;\n settled = true;\n cb.onError(error);\n }\n\n cb.onStarting();\n\n Promise.resolve()\n .then(() => provider(options))\n .then((s) => {\n session = s;\n if (cancelled) {\n // Cancelled during the start window — abort the freshly-made session.\n try {\n s.cancel();\n } catch {\n /* ignore */\n }\n finishCancelled();\n return;\n }\n cb.onActive(s);\n // Honor a stop that landed before the session resolved (rare).\n if (stopRequested) {\n cb.onProcessing();\n try {\n s.stop();\n } catch {\n /* ignore */\n }\n }\n // Single funnel: manual stop, provider auto-stop at the cap, and cancel\n // all arrive here. A RECORDER_STOPPED rejection is a cancel, not an error.\n Promise.resolve(s.result)\n .then((result) => {\n if (cancelled) finishCancelled();\n else finishResult(result);\n })\n .catch((err) => {\n if (cancelled || isRecorderStopped(err)) finishCancelled();\n else finishError(asError(err));\n });\n })\n .catch((err) => {\n // Provider threw/rejected at start.\n if (cancelled || isRecorderStopped(err)) finishCancelled();\n else finishError(asError(err));\n });\n\n return {\n stop() {\n if (settled || cancelled || stopRequested) return;\n stopRequested = true;\n if (session) {\n cb.onProcessing();\n try {\n session.stop();\n } catch {\n /* ignore */\n }\n }\n // If still starting, the start funnel applies stopRequested on resolve.\n },\n cancel() {\n if (settled && cancelled) return;\n cancelled = true;\n if (session) {\n try {\n session.cancel();\n } catch {\n /* ignore */\n }\n }\n // Idempotent via `settled`; the session.result rejection that follows a\n // provider cancel() is a no-op once we've already finished here.\n finishCancelled();\n },\n };\n}\n","/**\n * Heuristic floor detector. Returns the height (px) of the tallest\n * full-width fixed element anchored near the bottom of the viewport\n * (e.g. a tab bar). 0 if nothing matches.\n *\n * Cheap by design: probes `elementsFromPoint` at three x positions,\n * walks up parents, dedupes. O(small constant) — the spec's literal\n * `querySelectorAll('*')` would be O(DOM) per measurement.\n */\nexport function detectBottomFloor(): number {\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n return 0;\n }\n const w = window.innerWidth;\n const h = window.innerHeight;\n if (w === 0 || h === 0) return 0;\n\n const probeY = h - 4;\n const probeXs = [Math.round(w * 0.1), Math.round(w * 0.5), Math.round(w * 0.9)];\n const seen = new Set<Element>();\n let tallest = 0;\n\n for (const x of probeXs) {\n const stack = document.elementsFromPoint(x, probeY);\n for (const el of stack) {\n if (seen.has(el)) continue;\n seen.add(el);\n const cs = window.getComputedStyle(el);\n if (cs.position !== \"fixed\" && cs.position !== \"sticky\") continue;\n const rect = el.getBoundingClientRect();\n // Anchored at bottom: rect.bottom is within ~8px of viewport bottom.\n if (rect.bottom < h - 8) continue;\n if (rect.bottom > h + 8) continue;\n // Full-width-ish: at least 60% of the viewport.\n if (rect.width < w * 0.6) continue;\n if (rect.height > tallest) tallest = rect.height;\n }\n }\n return tallest;\n}\n\n/**\n * Measure the bottom-overlap of every node matching the given selectors.\n * Returns the tallest overlap.\n */\nexport function measureExplicitAvoid(selectors: string[]): number {\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n return 0;\n }\n const h = window.innerHeight;\n let tallest = 0;\n for (const selector of selectors) {\n let nodes: NodeListOf<Element>;\n try {\n nodes = document.querySelectorAll(selector);\n } catch {\n continue;\n }\n for (const node of Array.from(nodes)) {\n const rect = node.getBoundingClientRect();\n if (rect.height === 0 || rect.width === 0) continue;\n // Bottom-overlap = how far the node extends above the bottom edge,\n // assuming it's anchored to the bottom (rect.bottom near h).\n if (rect.bottom < h - 8) continue;\n const overlap = Math.max(0, h - rect.top);\n if (overlap > tallest) tallest = overlap;\n }\n }\n return tallest;\n}\n\n/**\n * Same idea as measureExplicitAvoid but for any of the four edges.\n * Returns inset to add for the given side.\n */\nexport function measureExplicitAvoidForSide(\n selectors: string[],\n side: \"top\" | \"bottom\" | \"left\" | \"right\",\n): number {\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n return 0;\n }\n const w = window.innerWidth;\n const h = window.innerHeight;\n let tallest = 0;\n for (const selector of selectors) {\n let nodes: NodeListOf<Element>;\n try {\n nodes = document.querySelectorAll(selector);\n } catch {\n continue;\n }\n for (const node of Array.from(nodes)) {\n const rect = node.getBoundingClientRect();\n if (rect.height === 0 || rect.width === 0) continue;\n let overlap = 0;\n switch (side) {\n case \"bottom\":\n if (rect.bottom < h - 8) break;\n overlap = Math.max(0, h - rect.top);\n break;\n case \"top\":\n if (rect.top > 8) break;\n overlap = Math.max(0, rect.bottom);\n break;\n case \"left\":\n if (rect.left > 8) break;\n overlap = Math.max(0, rect.right);\n break;\n case \"right\":\n if (rect.right < w - 8) break;\n overlap = Math.max(0, w - rect.left);\n break;\n }\n if (overlap > tallest) tallest = overlap;\n }\n }\n return tallest;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport {\n detectBottomFloor,\n measureExplicitAvoidForSide,\n} from \"./autoDetectAvoid\";\nimport type { ResolvedFloatingConfig } from \"./types\";\n\nexport interface CollisionInsets {\n bottom: number;\n right: number;\n left: number;\n top: number;\n}\n\n/**\n * Computes the inset (px, before safe-area) the floating trigger needs\n * for its anchored corner. Subscribes to:\n * - ResizeObserver on documentElement\n * - MutationObserver on document.body (childList/attributes)\n * - visualViewport resize/scroll\n *\n * All callbacks coalesce into a single rAF measure to avoid feedback\n * loops where our CSS-var write triggers the next observer fire.\n */\nexport function useCollisionInsets(\n config: ResolvedFloatingConfig,\n): CollisionInsets {\n const [insets, setInsets] = useState<CollisionInsets>(() => ({\n bottom: config.offset.y,\n right: config.offset.x,\n left: config.offset.x,\n top: config.offset.y,\n }));\n\n // Hold the latest insets in a ref so the rAF body can compare without\n // capturing stale state.\n const lastRef = useRef(insets);\n\n // Stable identifier for the avoid array so the effect doesn't re-run\n // every render when callers pass an inline array.\n const avoidKey = avoidToKey(config.avoid);\n const placement = config.placement;\n const offsetX = config.offset.x;\n const offsetY = config.offset.y;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n let raf = 0;\n let cancelled = false;\n\n const measure = () => {\n raf = 0;\n if (cancelled) return;\n\n const side = placement[0] === \"b\" ? \"bottom\" : \"top\";\n const xSide = placement[1] === \"r\" ? \"right\" : \"left\";\n\n let yExtra = 0;\n let xExtra = 0;\n if (config.avoid === \"auto\" && side === \"bottom\") {\n yExtra = detectBottomFloor();\n } else if (Array.isArray(config.avoid)) {\n yExtra = measureExplicitAvoidForSide(config.avoid, side);\n xExtra = measureExplicitAvoidForSide(config.avoid, xSide);\n }\n\n const next: CollisionInsets = {\n bottom: side === \"bottom\" ? offsetY + yExtra : 0,\n top: side === \"top\" ? offsetY + yExtra : 0,\n right: xSide === \"right\" ? offsetX + xExtra : 0,\n left: xSide === \"left\" ? offsetX + xExtra : 0,\n };\n const prev = lastRef.current;\n if (\n next.bottom !== prev.bottom ||\n next.top !== prev.top ||\n next.right !== prev.right ||\n next.left !== prev.left\n ) {\n lastRef.current = next;\n setInsets(next);\n }\n };\n\n const schedule = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(measure);\n };\n\n schedule();\n\n const ro =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(schedule)\n : null;\n ro?.observe(document.documentElement);\n\n const mo =\n typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(schedule)\n : null;\n mo?.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\"],\n });\n\n window.addEventListener(\"resize\", schedule);\n const vv = window.visualViewport;\n vv?.addEventListener(\"resize\", schedule);\n vv?.addEventListener(\"scroll\", schedule);\n\n return () => {\n cancelled = true;\n if (raf) window.cancelAnimationFrame(raf);\n ro?.disconnect();\n mo?.disconnect();\n window.removeEventListener(\"resize\", schedule);\n vv?.removeEventListener(\"resize\", schedule);\n vv?.removeEventListener(\"scroll\", schedule);\n };\n // `config.avoid` is captured via avoidKey; safe to ignore in deps.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [placement, offsetX, offsetY, avoidKey]);\n\n return insets;\n}\n\nfunction avoidToKey(avoid: string[] | false | \"auto\"): string {\n if (avoid === false) return \"false\";\n if (avoid === \"auto\") return \"auto\";\n return avoid.join(\"|\");\n}\n","\"use client\";\n\nimport { useCallback, useRef } from \"react\";\n\nexport interface TriggerActivationOptions {\n /** Pointer-down on the trigger (Lumen uses it to pre-warm the open flow). */\n onPointerDown?: (event: PointerEvent) => void;\n /** Activation (tap / Enter / Space) — opens the sheet. */\n onClick: (event: MouseEvent) => void;\n /**\n * Stop the trigger's own pointer/click events from bubbling into host\n * outside-click handlers (Silk/Vaul/Radix) so a host bottom sheet stays open\n * when the user taps the trigger. Default `true`.\n */\n isolate?: boolean;\n}\n\n/** Stop-only on these so a host's outside-click layer never sees the tap. */\nconst STOP_ONLY_EVENTS = [\"mousedown\", \"touchstart\"] as const;\n\n/**\n * Drive a trigger button's activation from NATIVE DOM listeners instead of\n * React synthetic handlers, and (by default) stop those events at the button.\n *\n * Why native: React 18 delegates events at the tree root, so calling\n * `stopPropagation()` from a synthetic handler runs *after* the host's\n * document-level dismiss listener already fired. Binding on the button itself\n * means our listener runs first and the event never reaches the host — which is\n * what keeps an open host bottom sheet from dismissing on a Lumen tap. It's also\n * strictly more robust than synthetic delegation for a portaled button.\n *\n * Returns a ref callback to put on the button. The callback identity is stable,\n * so listeners attach once; the latest handlers are read through refs.\n */\nexport function useTriggerActivation(\n options: TriggerActivationOptions,\n): (el: HTMLElement | null) => void {\n const pdRef = useRef(options.onPointerDown);\n pdRef.current = options.onPointerDown;\n const clickRef = useRef(options.onClick);\n clickRef.current = options.onClick;\n const isolateRef = useRef(options.isolate ?? true);\n isolateRef.current = options.isolate ?? true;\n const cleanupRef = useRef<(() => void) | null>(null);\n\n return useCallback((el: HTMLElement | null) => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n if (!el) return;\n\n const onPointerDown = (event: PointerEvent) => {\n if (isolateRef.current) event.stopPropagation();\n pdRef.current?.(event);\n };\n const onClick = (event: MouseEvent) => {\n if (isolateRef.current) event.stopPropagation();\n clickRef.current(event);\n };\n const stopOnly = (event: Event) => {\n if (isolateRef.current) event.stopPropagation();\n };\n\n el.addEventListener(\"pointerdown\", onPointerDown);\n el.addEventListener(\"click\", onClick);\n for (const type of STOP_ONLY_EVENTS) {\n el.addEventListener(\n type,\n stopOnly,\n type === \"touchstart\" ? { passive: true } : undefined,\n );\n }\n\n cleanupRef.current = () => {\n el.removeEventListener(\"pointerdown\", onPointerDown);\n el.removeEventListener(\"click\", onClick);\n for (const type of STOP_ONLY_EVENTS) {\n el.removeEventListener(type, stopOnly);\n }\n };\n }, []);\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport * as React from \"react\";\n\nimport { useCollisionInsets } from \"./useCollisionInsets\";\nimport { useKeyboardInset } from \"./useKeyboardInset\";\nimport { useTriggerActivation } from \"./useTriggerActivation\";\nimport type { ResolvedFloatingConfig } from \"./types\";\n\nexport interface FloatingTriggerProps {\n config: ResolvedFloatingConfig;\n portalTarget?: HTMLElement;\n hidden: boolean;\n onPointerDown?: (event: PointerEvent) => void;\n onClick: (event: MouseEvent) => void;\n /** Stop trigger taps from leaking into host outside-click handlers. */\n isolateEvents?: boolean;\n /** Explicit keyboard inset override (px) for same-process WebView hosts. */\n keyboardInset?: number;\n}\n\nexport function FloatingTrigger({\n config,\n portalTarget,\n hidden,\n onPointerDown,\n onClick,\n isolateEvents = true,\n keyboardInset,\n}: FloatingTriggerProps) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const insets = useCollisionInsets(config);\n const keyboard = useKeyboardInset(config.keyboard !== \"off\", keyboardInset);\n\n const activate = useTriggerActivation({\n onPointerDown,\n onClick,\n isolate: isolateEvents,\n });\n const setButton = useCallback(\n (el: HTMLButtonElement | null) => {\n buttonRef.current = el;\n activate(el);\n },\n [activate],\n );\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n setTarget(portalTarget ?? document.body);\n }, [portalTarget]);\n\n const placement = config.placement;\n const sideY = placement[0] === \"b\" ? \"bottom\" : \"top\";\n const sideX = placement[1] === \"r\" ? \"right\" : \"left\";\n const placementBottom = sideY === \"bottom\";\n\n // Lift the trigger above the keyboard when we know how tall it is (incl.\n // WebView hosts that inject the inset); only a bottom-anchored trigger is\n // ever covered. Fall back to fading it out when the height is unknown or\n // \"hide\" was requested.\n const liftPx =\n keyboard.open &&\n placementBottom &&\n (config.keyboard === \"lift\" ||\n (config.keyboard === \"auto\" && keyboard.inset > 0))\n ? keyboard.inset\n : 0;\n const hideForKeyboard =\n keyboard.open &&\n (config.keyboard === \"hide\" ||\n (config.keyboard === \"auto\" && placementBottom && keyboard.inset <= 0));\n\n useOcclusionWarning(buttonRef, !hidden && !hideForKeyboard);\n\n if (!target) return null;\n\n const yPx = sideY === \"bottom\" ? insets.bottom : insets.top;\n const xPx = sideX === \"right\" ? insets.right : insets.left;\n const concealed = hidden || hideForKeyboard;\n\n const style: React.CSSProperties = {\n position: \"fixed\",\n [sideY]: config.safeArea\n ? `calc(${yPx}px + env(safe-area-inset-${sideY}, 0px))`\n : `${yPx}px`,\n [sideX]: config.safeArea\n ? `calc(${xPx}px + env(safe-area-inset-${sideX}, 0px))`\n : `${xPx}px`,\n zIndex: config.zIndex,\n transform: liftPx ? `translateY(-${liftPx}px)` : undefined,\n opacity: concealed ? 0 : 1,\n pointerEvents: concealed ? \"none\" : \"auto\",\n transition:\n \"opacity 160ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1)\",\n };\n\n return createPortal(\n <button\n ref={setButton}\n type=\"button\"\n className=\"lumen-btn lumen-btn-primary lumen-btn-floating\"\n style={style}\n aria-label={config.label}\n aria-hidden={concealed ? true : undefined}\n tabIndex={concealed ? -1 : 0}\n data-lumen-trigger=\"\"\n data-lumen-capture-ignore=\"true\"\n >\n {config.icon}\n <span>{config.label}</span>\n </button>,\n target,\n );\n}\n\n/**\n * Dev-only: after the first stable measurement, sample the trigger's\n * center point and warn once if a higher-z-index element overlaps it.\n */\nfunction useOcclusionWarning(\n ref: React.RefObject<HTMLButtonElement | null>,\n active: boolean,\n) {\n const warnedRef = useRef(false);\n\n useEffect(() => {\n if (process.env.NODE_ENV === \"production\") return;\n if (!active) return;\n if (warnedRef.current) return;\n if (typeof window === \"undefined\") return;\n\n const t = window.setTimeout(() => {\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return;\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n const stack = document.elementsFromPoint(cx, cy);\n const ourZ = parseZ(window.getComputedStyle(el).zIndex);\n for (const candidate of stack) {\n if (candidate === el || el.contains(candidate)) continue;\n const cz = parseZ(window.getComputedStyle(candidate).zIndex);\n if (cz > ourZ) {\n warnedRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\"[lumen] trigger is occluded by\", candidate);\n break;\n }\n }\n }, 250);\n return () => window.clearTimeout(t);\n }, [active, ref]);\n}\n\nfunction parseZ(z: string): number {\n const n = parseInt(z, 10);\n return Number.isNaN(n) ? 0 : n;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { ReactNode, RefObject } from \"react\";\n\nimport { useTriggerActivation } from \"./useTriggerActivation\";\n\nexport interface InlineTriggerProps {\n mount: HTMLElement | RefObject<HTMLElement | null>;\n label: string;\n icon?: ReactNode;\n onPointerDown?: (event: PointerEvent) => void;\n onClick: (event: MouseEvent) => void;\n /** Stop trigger taps from leaking into host outside-click handlers. */\n isolateEvents?: boolean;\n}\n\nexport function InlineTrigger({\n mount,\n label,\n icon,\n onPointerDown,\n onClick,\n isolateEvents = true,\n}: InlineTriggerProps) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n const setButton = useTriggerActivation({\n onPointerDown,\n onClick,\n isolate: isolateEvents,\n });\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const el =\n mount instanceof HTMLElement ? mount : (mount.current ?? null);\n setTarget(el);\n }, [mount]);\n\n if (!target) return null;\n\n return createPortal(\n <button\n ref={setButton}\n type=\"button\"\n className=\"lumen-btn lumen-btn-primary\"\n aria-label={label}\n data-lumen-trigger=\"\"\n data-lumen-capture-ignore=\"true\"\n >\n {icon}\n <span>{label}</span>\n </button>,\n target,\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { useTriggerActivation } from \"./useTriggerActivation\";\nimport type { ResolvedNotchConfig } from \"./types\";\n\nexport interface NotchTriggerProps {\n config: ResolvedNotchConfig;\n portalTarget?: HTMLElement;\n hidden: boolean;\n onPointerDown?: (event: PointerEvent) => void;\n onClick: (event: MouseEvent | PointerEvent) => void;\n /** Stop trigger taps from leaking into host outside-click handlers. */\n isolateEvents?: boolean;\n}\n\n/**\n * Edge-anchored notch. The resting state is a small tab on a screen\n * edge; on hover/tap it expands and opens the capture modal. A short\n * drag away from the edge (>16px) also opens, mimicking the iOS\n * Dynamic-Island pull gesture.\n *\n * Top edge → drag down. Right edge → drag left. Etc.\n */\nexport function NotchTrigger({\n config,\n portalTarget,\n hidden,\n onPointerDown: onActivatePointerDown,\n onClick,\n isolateEvents = true,\n}: NotchTriggerProps) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n const [expanded, setExpanded] = useState(false);\n const dragStartRef = useRef<{ x: number; y: number } | null>(null);\n\n // pointerdown + click run natively so the tap can be stopped from leaking\n // into host outside-click handlers; pointer-move/up stay React-synthetic for\n // the drag-open gesture.\n const setButton = useTriggerActivation({\n onPointerDown: (event) => {\n onActivatePointerDown?.(event);\n dragStartRef.current = { x: event.clientX, y: event.clientY };\n setExpanded(true);\n const el = event.currentTarget as HTMLElement | null;\n try {\n el?.setPointerCapture?.(event.pointerId);\n } catch {\n // setPointerCapture can throw if the pointer is already released.\n }\n },\n onClick,\n isolate: isolateEvents,\n });\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n setTarget(portalTarget ?? document.body);\n }, [portalTarget]);\n\n if (!target) return null;\n\n const className = `lumen-notch lumen-notch-${config.edge}${\n expanded ? \" lumen-notch-expanded\" : \"\"\n }`;\n\n function onPointerMove(e: React.PointerEvent<HTMLButtonElement>) {\n const start = dragStartRef.current;\n if (!start) return;\n const dx = e.clientX - start.x;\n const dy = e.clientY - start.y;\n const triggered =\n (config.edge === \"top\" && dy > 16) ||\n (config.edge === \"bottom\" && dy < -16) ||\n (config.edge === \"right\" && dx < -16) ||\n (config.edge === \"left\" && dx > 16);\n if (triggered) {\n dragStartRef.current = null;\n onClick(e.nativeEvent);\n }\n }\n function onPointerUp() {\n dragStartRef.current = null;\n setExpanded(false);\n }\n function onPointerCancel() {\n dragStartRef.current = null;\n setExpanded(false);\n }\n\n return createPortal(\n <button\n ref={setButton}\n type=\"button\"\n className={className}\n style={{\n zIndex: config.zIndex,\n opacity: hidden ? 0 : 1,\n pointerEvents: hidden ? \"none\" : \"auto\",\n }}\n aria-label={config.label}\n aria-hidden={hidden ? true : undefined}\n tabIndex={hidden ? -1 : 0}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerCancel}\n onMouseEnter={() => setExpanded(true)}\n onMouseLeave={() => setExpanded(false)}\n data-lumen-trigger=\"\"\n data-lumen-capture-ignore=\"true\"\n >\n <span className=\"lumen-notch-handle\" aria-hidden=\"true\" />\n <span className=\"lumen-notch-label\">{config.icon}{config.label}</span>\n </button>,\n target,\n );\n}\n","import type { ReactNode, RefObject } from \"react\";\n\nexport type LumenTriggerPlacement = \"br\" | \"bl\" | \"tr\" | \"tl\";\n\nexport interface FloatingTriggerConfig {\n kind: \"floating\";\n placement?: LumenTriggerPlacement;\n offset?: { x?: number; y?: number };\n safeArea?: boolean;\n /** Selectors to clear; pass `false` to disable auto-detect entirely. */\n avoid?: string | string[] | false;\n /**\n * What the floating trigger does when the soft keyboard opens:\n * - `\"auto\"` (default) — lift the trigger above the keyboard when its height\n * is known (incl. WebView hosts that inject it), else hide it.\n * - `\"lift\"` — always lift by the keyboard inset.\n * - `\"hide\"` — fade out (the pre-0.10 behavior).\n * Booleans are accepted for back-compat: `true` → `\"hide\"`, `false` → off.\n */\n hideOnKeyboard?: boolean | \"auto\" | \"lift\" | \"hide\";\n zIndex?: number;\n label?: string;\n icon?: ReactNode;\n}\n\nexport type NotchEdge = \"top\" | \"right\" | \"bottom\" | \"left\";\n\nexport interface NotchTriggerConfig {\n kind: \"notch\";\n edge?: NotchEdge;\n label?: string;\n icon?: ReactNode;\n /** z-index for the notch tab. Default 2147483600. */\n zIndex?: number;\n}\n\nexport interface ResolvedNotchConfig {\n kind: \"notch\";\n edge: NotchEdge;\n label: string;\n icon: ReactNode | undefined;\n zIndex: number;\n}\n\nexport function resolveNotchConfig(\n cfg: NotchTriggerConfig,\n): ResolvedNotchConfig {\n return {\n kind: \"notch\",\n edge: cfg.edge ?? \"top\",\n label: cfg.label ?? \"Feedback\",\n icon: cfg.icon,\n zIndex: cfg.zIndex ?? 2147483600,\n };\n}\n\nexport interface HeadlessTriggerConfig {\n kind: \"headless\";\n}\n\nexport interface InlineTriggerConfig {\n kind: \"inline\";\n mount: HTMLElement | RefObject<HTMLElement | null>;\n label?: string;\n icon?: ReactNode;\n}\n\nexport type LumenTrigger =\n | FloatingTriggerConfig\n | NotchTriggerConfig\n | HeadlessTriggerConfig\n | InlineTriggerConfig;\n\nexport type LumenTheme =\n | \"auto\"\n | \"light\"\n | \"dark\"\n | {\n background?: string;\n foreground?: string;\n accent?: string;\n radius?: string;\n /**\n * Force a colour scheme alongside the custom tokens. Lets a project set\n * a brand accent *and* pin light/dark at once (e.g. from the dashboard\n * brand config). Omit / \"auto\" to follow the host's prefers-color-scheme.\n */\n scheme?: \"auto\" | \"light\" | \"dark\";\n };\n\n/** Resolved keyboard behavior for the floating trigger. */\nexport type KeyboardBehavior = \"auto\" | \"lift\" | \"hide\" | \"off\";\n\nexport interface ResolvedFloatingConfig {\n kind: \"floating\";\n placement: LumenTriggerPlacement;\n offset: { x: number; y: number };\n safeArea: boolean;\n avoid: string[] | false | \"auto\";\n keyboard: KeyboardBehavior;\n zIndex: number;\n label: string;\n icon: ReactNode | undefined;\n}\n\n/** Map the (back-compat) `hideOnKeyboard` prop to a resolved behavior. */\nexport function resolveKeyboardBehavior(\n value: FloatingTriggerConfig[\"hideOnKeyboard\"],\n): KeyboardBehavior {\n if (value === false) return \"off\";\n if (value === true) return \"hide\"; // back-compat: explicit `true` kept hide\n if (value === \"auto\" || value === \"lift\" || value === \"hide\") return value;\n return \"auto\"; // new default: lift above the keyboard when its height is known\n}\n\nexport function resolveFloatingConfig(\n cfg: FloatingTriggerConfig,\n): ResolvedFloatingConfig {\n return {\n kind: \"floating\",\n placement: cfg.placement ?? \"br\",\n offset: { x: cfg.offset?.x ?? 16, y: cfg.offset?.y ?? 16 },\n safeArea: cfg.safeArea ?? true,\n avoid:\n cfg.avoid === false\n ? false\n : cfg.avoid == null\n ? \"auto\"\n : Array.isArray(cfg.avoid)\n ? cfg.avoid\n : [cfg.avoid],\n keyboard: resolveKeyboardBehavior(cfg.hideOnKeyboard),\n zIndex: cfg.zIndex ?? 2147483600,\n label: cfg.label ?? \"Feedback\",\n icon: cfg.icon,\n };\n}\n","\"use client\";\n\nimport { useEffect, useId } from \"react\";\nimport type { LumenTheme } from \"./types\";\n\nconst VAR_MAP: Record<string, keyof Extract<LumenTheme, object>> = {\n \"--lumen-bg\": \"background\",\n \"--lumen-fg\": \"foreground\",\n \"--lumen-radius\": \"radius\",\n};\n\n/**\n * Applies the theme by writing CSS variables to <html> (so they reach\n * the portaled CaptureModal) and toggling a data attribute for explicit\n * light/dark. Cleanup restores prior values on unmount.\n *\n * The instance id scopes attribute cleanup so two providers don't\n * stomp each other.\n */\nexport function useApplyTheme(theme: LumenTheme | undefined): void {\n const instanceId = useId();\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n const attr = `data-lumen-theme-${slug(instanceId)}`;\n const previous: Record<string, string | null> = {};\n\n const setVar = (cssVar: string, value: string) => {\n previous[cssVar] = root.style.getPropertyValue(cssVar) || null;\n root.style.setProperty(cssVar, value);\n };\n\n if (theme === \"auto\" || theme == null) {\n // Default: rely on prefers-color-scheme already in styles.css.\n root.removeAttribute(\"data-lumen-theme\");\n } else if (theme === \"light\" || theme === \"dark\") {\n previous[\"data-lumen-theme\"] = root.getAttribute(\"data-lumen-theme\");\n root.setAttribute(\"data-lumen-theme\", theme);\n } else {\n for (const [cssVar, key] of Object.entries(VAR_MAP)) {\n const v = theme[key as keyof typeof theme];\n if (typeof v === \"string\" && v.length > 0) {\n setVar(cssVar, v);\n }\n }\n // Accent drives the button/focus/stepper, which read --lumen-accent\n // (--lumen-primary is only a back-compat alias). Set both, and pin a\n // legible on-accent foreground — dashboard accents are saturated, so\n // white reads correctly; advanced hosts can still override via CSS.\n if (typeof theme.accent === \"string\" && theme.accent.length > 0) {\n setVar(\"--lumen-accent\", theme.accent);\n setVar(\"--lumen-primary\", theme.accent);\n setVar(\"--lumen-accent-fg\", \"#ffffff\");\n }\n // Optional forced scheme alongside the custom tokens.\n if (theme.scheme === \"light\" || theme.scheme === \"dark\") {\n previous[\"data-lumen-theme\"] = root.getAttribute(\"data-lumen-theme\");\n root.setAttribute(\"data-lumen-theme\", theme.scheme);\n }\n }\n root.setAttribute(attr, \"\");\n\n return () => {\n root.removeAttribute(attr);\n for (const [k, v] of Object.entries(previous)) {\n if (k.startsWith(\"--\")) {\n if (v) root.style.setProperty(k, v);\n else root.style.removeProperty(k);\n } else if (v == null) {\n root.removeAttribute(k);\n } else {\n root.setAttribute(k, v);\n }\n }\n };\n }, [theme, instanceId]);\n}\n\nfunction slug(s: string): string {\n return s.replace(/[^a-zA-Z0-9]/g, \"\");\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst PATCH_FLAG = Symbol.for(\"lumen.history.patched\");\nconst EVENT_NAME = \"lumen:locationchange\";\n\ninterface PatchedWindow extends Window {\n [PATCH_FLAG]?: true;\n}\n\n/**\n * Idempotent global patch: monkey-patches pushState/replaceState exactly\n * once per window so any number of LumenProvider instances (and React\n * StrictMode double-mounts) can subscribe without stacking patches.\n */\nfunction ensureHistoryPatch(): void {\n if (typeof window === \"undefined\") return;\n const w = window as PatchedWindow;\n if (w[PATCH_FLAG]) return;\n w[PATCH_FLAG] = true;\n\n const dispatch = () => window.dispatchEvent(new Event(EVENT_NAME));\n\n const origPush = history.pushState;\n history.pushState = function (...args: Parameters<History[\"pushState\"]>) {\n const r = origPush.apply(this, args);\n dispatch();\n return r;\n };\n const origReplace = history.replaceState;\n history.replaceState = function (\n ...args: Parameters<History[\"replaceState\"]>\n ) {\n const r = origReplace.apply(this, args);\n dispatch();\n return r;\n };\n window.addEventListener(\"popstate\", dispatch);\n}\n\n/**\n * Returns true when `predicate(location)` returns true for the current\n * location. Re-evaluates on history changes.\n */\nexport function useHideOn(\n predicate: ((location: { pathname: string }) => boolean) | undefined,\n): boolean {\n const [hidden, setHidden] = useState(false);\n\n useEffect(() => {\n if (!predicate) {\n setHidden(false);\n return;\n }\n if (typeof window === \"undefined\") return;\n ensureHistoryPatch();\n\n const evaluate = () => {\n try {\n setHidden(!!predicate({ pathname: window.location.pathname }));\n } catch {\n setHidden(false);\n }\n };\n evaluate();\n window.addEventListener(EVENT_NAME, evaluate);\n window.addEventListener(\"popstate\", evaluate);\n return () => {\n window.removeEventListener(EVENT_NAME, evaluate);\n window.removeEventListener(\"popstate\", evaluate);\n };\n }, [predicate]);\n\n return hidden;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst NATIVE_UA_TOKENS = [\n \"wv\", // generic Android WebView\n \"Capacitor\",\n \"Cordova\",\n \"Expo\",\n \"FBAN\",\n \"FBAV\",\n \"Instagram\",\n \"Line/\",\n \"Twitter\",\n];\n\n/**\n * Best-effort detection of a native shell (RN WebView, Capacitor,\n * Cordova, social-app webviews). Reported via context so hosts can\n * branch their own UI; we never auto-hide based on it.\n */\nexport function useNativeShell(): boolean {\n const [native, setNative] = useState(false);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const w = window as unknown as Record<string, unknown>;\n if (w.ReactNativeWebView) {\n setNative(true);\n return;\n }\n const wk = w.webkit as { messageHandlers?: unknown } | undefined;\n if (wk && wk.messageHandlers) {\n setNative(true);\n return;\n }\n const ua = navigator.userAgent || \"\";\n if (NATIVE_UA_TOKENS.some((t) => ua.includes(t))) {\n setNative(true);\n }\n }, []);\n\n return native;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport type { LumenTrigger, NotchEdge, LumenTriggerPlacement } from \"./types\";\n\nconst STORAGE_PREFIX = \"lumen.config.v1.\";\nconst STORAGE_TTL_MS = 60 * 60 * 1000; // 1h\n\n/**\n * Brand/appearance from the dashboard (`projects.brandConfig`). Mirrors\n * `brandConfigSchema` in @lumen/shared but typed locally so the SDK keeps\n * zero workspace deps. Applied via `useApplyTheme` in LumenProvider.\n */\nexport interface RemoteBrand {\n /** 6-digit hex accent colour, e.g. \"#3a2fe6\". */\n accent: string;\n /** Forced colour scheme, or \"auto\" to follow the host. */\n mode: \"auto\" | \"light\" | \"dark\";\n /** Corner radius in px. */\n radius: number;\n}\n\ninterface CachedEntry {\n fetchedAt: number;\n trigger: LumenTrigger;\n shake: boolean;\n brand: RemoteBrand | null;\n}\n\nexport interface RemoteConfigState {\n /** Trigger from the remote config; null while loading and no cache. */\n trigger: LumenTrigger | null;\n /** Whether the SDK should render any trigger at all. */\n enabled: boolean;\n /**\n * Shake-to-open toggle from the dashboard. Independent of `enabled` so a\n * project can keep the visible widget hidden but still open on shake.\n */\n shakeToOpen: boolean;\n /**\n * Brand/appearance from the dashboard; null when absent or malformed (the\n * caller then leaves the widget's built-in theme in place).\n */\n brand: RemoteBrand | null;\n /** True until either localStorage or the network has answered. */\n loading: boolean;\n}\n\n/**\n * Fetches `/api/v1/sdk/config?apiKey=…` and caches the result in\n * localStorage so the trigger can render instantly on subsequent loads.\n *\n * Returns immediately from the cache, then revalidates in the\n * background. Falls back to `null` (caller will use its built-in\n * default) on every error path so a flaky config endpoint can never\n * break the host page.\n */\nexport function useRemoteConfig(\n apiKey: string,\n apiUrl: string,\n): RemoteConfigState {\n const [state, setState] = useState<RemoteConfigState>(() => ({\n trigger: null,\n enabled: true,\n shakeToOpen: false,\n brand: null,\n loading: true,\n }));\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const cached = readCache(apiKey);\n if (cached) {\n setState({\n trigger: cached.trigger,\n enabled: triggerEnabled(cached.trigger),\n shakeToOpen: cached.shake,\n brand: cached.brand,\n loading: false,\n });\n }\n\n const controller = new AbortController();\n // Hard timeout: the SDK can't hold its loading state hostage to a\n // slow or hung /sdk/config endpoint. After 5s we abort and resolve\n // to a sensible default so the host page never sees a broken widget.\n const timeoutId = window.setTimeout(() => controller.abort(), 5000);\n const url = `${apiUrl.replace(/\\/$/, \"\")}/api/v1/sdk/config?apiKey=${encodeURIComponent(apiKey)}`;\n fetch(url, {\n method: \"GET\",\n mode: \"cors\",\n credentials: \"omit\",\n signal: controller.signal,\n })\n .then(async (res) => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {\n trigger?: unknown;\n brand?: unknown;\n };\n const trigger = parseTrigger(body.trigger);\n if (!trigger) throw new Error(\"Malformed config response\");\n const shake = parseShake(body.trigger);\n const brand = parseBrand(body.brand);\n writeCache(apiKey, trigger, shake, brand);\n setState({\n trigger,\n enabled: triggerEnabled(trigger),\n shakeToOpen: shake,\n brand,\n loading: false,\n });\n })\n .catch(() => {\n // Network/parse errors fall through to defaults — never block.\n setState((prev) =>\n prev.loading\n ? {\n trigger: null,\n enabled: true,\n shakeToOpen: false,\n brand: null,\n loading: false,\n }\n : prev,\n );\n })\n .finally(() => window.clearTimeout(timeoutId));\n\n return () => {\n window.clearTimeout(timeoutId);\n controller.abort();\n };\n }, [apiKey, apiUrl]);\n\n return state;\n}\n\nfunction triggerEnabled(t: LumenTrigger): boolean {\n // The SDK type doesn't carry `enabled` directly because hosts that\n // build a trigger inline would never need it; the *remote* type does\n // ship it as the on/off toggle and we encode that here as the\n // headless variant.\n return t.kind !== \"headless\";\n}\n\nconst VALID_PLACEMENTS: readonly LumenTriggerPlacement[] = [\n \"br\",\n \"bl\",\n \"tr\",\n \"tl\",\n];\nconst VALID_EDGES: readonly NotchEdge[] = [\"top\", \"right\", \"bottom\", \"left\"];\n\n/**\n * Defensive parser for the remote config payload. Exported for tests;\n * the hook uses it internally. Returns null when the shape is bad so\n * the caller can fall back to defaults instead of rendering garbage.\n */\nexport function parseTrigger(raw: unknown): LumenTrigger | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n\n // The dashboard ships `enabled` as the on/off toggle — when off,\n // collapse to a headless trigger so the SDK renders nothing.\n if (r.enabled === false) return { kind: \"headless\" };\n\n const label = typeof r.label === \"string\" ? r.label : \"Feedback\";\n\n if (r.kind === \"floating\") {\n const placement =\n VALID_PLACEMENTS.find((p) => p === r.placement) ?? \"br\";\n return { kind: \"floating\", placement, label };\n }\n if (r.kind === \"notch\") {\n const edge = VALID_EDGES.find((e) => e === r.edge) ?? \"top\";\n return { kind: \"notch\", edge, label };\n }\n return null;\n}\n\n/**\n * Read the dashboard's `shake` toggle off the raw config payload. Kept\n * separate from `parseTrigger` because that collapses a disabled widget to\n * `headless` (dropping every field) — but shake must survive an off widget.\n */\nexport function parseShake(raw: unknown): boolean {\n if (!raw || typeof raw !== \"object\") return false;\n return (raw as Record<string, unknown>).shake === true;\n}\n\nconst HEX6 = /^#[0-9a-fA-F]{6}$/;\nconst VALID_MODES: readonly RemoteBrand[\"mode\"][] = [\"auto\", \"light\", \"dark\"];\n\n/**\n * Defensive parser for the `brand` block. Returns null when absent or\n * malformed so the SDK keeps its built-in theme rather than applying a\n * half-valid one. Exported for tests.\n */\nexport function parseBrand(raw: unknown): RemoteBrand | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n const accent =\n typeof r.accent === \"string\" && HEX6.test(r.accent) ? r.accent : null;\n if (!accent) return null;\n const mode = VALID_MODES.find((m) => m === r.mode) ?? \"auto\";\n const radius =\n typeof r.radius === \"number\" && Number.isFinite(r.radius)\n ? Math.min(20, Math.max(0, Math.round(r.radius)))\n : 10;\n return { accent, mode, radius };\n}\n\nfunction readCache(apiKey: string): CachedEntry | null {\n try {\n const raw = window.localStorage.getItem(STORAGE_PREFIX + apiKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as CachedEntry;\n if (\n typeof parsed?.fetchedAt !== \"number\" ||\n Date.now() - parsed.fetchedAt > STORAGE_TTL_MS\n ) {\n return null;\n }\n const trigger = parseTrigger(parsed.trigger);\n return trigger\n ? {\n fetchedAt: parsed.fetchedAt,\n trigger,\n shake: parsed.shake === true,\n brand: parseBrand(parsed.brand),\n }\n : null;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(\n apiKey: string,\n trigger: LumenTrigger,\n shake: boolean,\n brand: RemoteBrand | null,\n): void {\n try {\n window.localStorage.setItem(\n STORAGE_PREFIX + apiKey,\n JSON.stringify({ fetchedAt: Date.now(), trigger, shake, brand }),\n );\n } catch {\n // Quota / private mode — fail silent.\n }\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { LUMEN_SHAKE_MESSAGE } from \"@lumen-stack/core\";\n\n/**\n * True when a bridge message (`window.postMessage` data) is a Lumen shake\n * event. Accepts both a parsed object and the JSON string react-native-webview\n * delivers. Exported for tests.\n */\nexport function isShakeMessage(data: unknown): boolean {\n if (data && typeof data === \"object\") {\n return (data as { type?: unknown }).type === LUMEN_SHAKE_MESSAGE;\n }\n if (typeof data === \"string\") {\n try {\n return (JSON.parse(data) as { type?: unknown }).type === LUMEN_SHAKE_MESSAGE;\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport interface MotionShakeOptions {\n /** Jerk (sum of |Δx|+|Δy|+|Δz|) above which a sample counts as a jolt. */\n threshold?: number;\n /** Distinct jolts needed within `windowMs` to call it a shake. */\n neededHits?: number;\n /** Sliding window the jolts must fall inside. */\n windowMs?: number;\n /** Minimum gap between processed samples (throttle). */\n throttleMs?: number;\n}\n\nexport interface MotionShakeDetector {\n /** Feed one accelerometer sample; returns true when a shake completes. */\n push: (x: number, y: number, z: number, now: number) => boolean;\n}\n\n/**\n * Pure accelerometer shake detector. A shake is several large jerks in a\n * short window; the first sample only primes the baseline. Framework-free so\n * it can be unit-tested without a DOM. Exported for tests.\n */\nexport function createMotionShakeDetector(\n options: MotionShakeOptions = {},\n): MotionShakeDetector {\n const threshold = options.threshold ?? 18;\n const neededHits = options.neededHits ?? 3;\n const windowMs = options.windowMs ?? 700;\n const throttleMs = options.throttleMs ?? 60;\n\n let last: { x: number; y: number; z: number; t: number } | null = null;\n let hits: number[] = [];\n\n return {\n push(x, y, z, now) {\n if (!last) {\n last = { x, y, z, t: now };\n return false;\n }\n if (now - last.t < throttleMs) return false;\n const delta =\n Math.abs(x - last.x) + Math.abs(y - last.y) + Math.abs(z - last.z);\n last = { x, y, z, t: now };\n if (delta < threshold) return false;\n hits = hits.filter((t) => now - t < windowMs);\n hits.push(now);\n if (hits.length >= neededHits) {\n hits = [];\n return true;\n }\n return false;\n },\n };\n}\n\n/**\n * Open the Lumen sheet when the user shakes their device.\n *\n * Two independent sources, both gated by `enabled`:\n *\n * 1. **Native bridge (primary).** A native Expo / react-native-webview host\n * detects the shake (e.g. `expo-sensors`, iOS `motionEnded`, Android\n * sensor) and posts a `{ \"type\": \"lumen:shake\" }` message into the WebView.\n * This is the reliable path on real devices.\n *\n * 2. **Web DeviceMotion (best-effort fallback).** For mobile web / PWAs the\n * SDK listens to `devicemotion` directly. This works on Android Chrome and\n * any context where motion permission is already granted; iOS Safari needs\n * `DeviceMotionEvent.requestPermission()` from a user gesture, which the\n * SDK can't trigger on its own — so on iOS the native bridge is required.\n *\n * A cooldown stops a single shake (many motion samples) from opening the\n * sheet more than once, and `onShake` is skipped while already open.\n */\nexport function useShakeToOpen(\n enabled: boolean,\n onShake: () => void,\n isOpen: boolean,\n): void {\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n\n let lastFire = 0;\n const COOLDOWN_MS = 1500;\n\n function fire() {\n const now = Date.now();\n if (isOpen || now - lastFire < COOLDOWN_MS) return;\n lastFire = now;\n onShake();\n }\n\n // ── Source 1: native bridge message ──────────────────────────────────\n const onMessage = (event: MessageEvent) => {\n if (isShakeMessage(event.data)) fire();\n };\n window.addEventListener(\"message\", onMessage);\n // react-native-webview delivers postMessage on `document` on Android.\n document.addEventListener(\"message\", onMessage as EventListener);\n\n // ── Source 2: web DeviceMotion shake detection ───────────────────────\n const detector = createMotionShakeDetector();\n const onMotion = (e: DeviceMotionEvent) => {\n const a = e.accelerationIncludingGravity ?? e.acceleration;\n if (!a || a.x == null || a.y == null || a.z == null) return;\n if (detector.push(a.x, a.y, a.z, Date.now())) fire();\n };\n // Don't auto-attach where an explicit permission gate exists (iOS): the\n // listener would never fire and just burns a slot. The native bridge\n // covers iOS instead.\n const hasMotion =\n typeof window.DeviceMotionEvent !== \"undefined\" &&\n typeof (\n window.DeviceMotionEvent as unknown as { requestPermission?: unknown }\n ).requestPermission !== \"function\";\n if (hasMotion) window.addEventListener(\"devicemotion\", onMotion);\n\n return () => {\n window.removeEventListener(\"message\", onMessage);\n document.removeEventListener(\"message\", onMessage as EventListener);\n if (hasMotion) window.removeEventListener(\"devicemotion\", onMotion);\n };\n }, [enabled, onShake, isOpen]);\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport * as React from \"react\";\nimport { Toaster, toast } from \"sonner\";\nimport {\n installRuntimeCapture,\n LumenClient,\n recordVideo,\n startDisplayMediaCapture,\n type AmplitudeIdentity,\n type CaptureResult,\n type DisplayMediaCaptureSession,\n type LumenRecordProvider,\n type LumenUser,\n type ScreenshotCaptureOptions,\n} from \"@lumen-stack/core\";\nimport { captureScreen } from \"@lumen-stack/core\";\n\nimport {\n LumenContext,\n type LumenContextValue,\n type PendingVideo,\n type ScreenCaptureState,\n type VideoRecordingState,\n} from \"./context\";\nimport { CaptureModal } from \"./CaptureModal\";\nimport { LumenErrorBoundary } from \"./LumenErrorBoundary\";\nimport { RecordingHud } from \"./RecordingHud\";\nimport { ScreenCaptureHud } from \"./ScreenCaptureHud\";\nimport { posterFromStream } from \"./video-poster\";\nimport { resolveRecordCapability } from \"./record-availability\";\nimport {\n driveRecordSession,\n type RecordSessionControl,\n} from \"./record-session\";\nimport { FloatingTrigger } from \"./trigger/FloatingTrigger\";\nimport { InlineTrigger } from \"./trigger/InlineTrigger\";\nimport { NotchTrigger } from \"./trigger/NotchTrigger\";\nimport {\n resolveFloatingConfig,\n resolveNotchConfig,\n type LumenTheme,\n type LumenTrigger,\n} from \"./trigger/types\";\nimport { useApplyTheme } from \"./trigger/theme\";\nimport { useHideOn } from \"./trigger/useHideOn\";\nimport { useNativeShell } from \"./trigger/useNativeShell\";\nimport {\n useRemoteConfig,\n type RemoteBrand,\n} from \"./trigger/useRemoteConfig\";\nimport { useShakeToOpen } from \"./trigger/useShakeToOpen\";\n\nconst DEFAULT_API_URL = \"https://shakebugs.vercel.app\";\nconst VIDEO_MAX_SECONDS = 60;\n\nfunction hasGetDisplayMedia(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n !!navigator.mediaDevices &&\n typeof navigator.mediaDevices.getDisplayMedia === \"function\"\n );\n}\n\nexport interface LumenProviderProps {\n apiKey: string;\n /** Override the dashboard origin. Defaults to https://shakebugs.vercel.app. */\n apiUrl?: string;\n user?: LumenUser;\n /**\n * Amplitude analytics identity for the current user. When set and the\n * project has the Amplitude integration enabled, Lumen pulls this user's\n * recent event timeline at enrichment time so the AI triage understands\n * what they did before reporting. Pass what your Amplitude instance holds:\n * `amplitude={{ userId: amp.getUserId(), deviceId: amp.getDeviceId(), sessionId: String(amp.getSessionId()) }}`.\n */\n amplitude?: AmplitudeIdentity;\n /**\n * @deprecated Use `trigger` instead. `floatingButton={false}` is\n * equivalent to `trigger={{ kind: \"headless\" }}`.\n */\n floatingButton?: boolean;\n /**\n * Trigger configuration. When omitted the SDK fetches the dashboard's\n * widget config from `/api/v1/sdk/config` and renders that. Pass a\n * value here to override the dashboard config locally.\n */\n trigger?: LumenTrigger;\n /** Hide the trigger on certain routes. Modal stays open if already open. */\n hideOn?: (location: { pathname: string }) => boolean;\n theme?: LumenTheme;\n /** Where to portal the floating trigger. Defaults to document.body. */\n portalTarget?: HTMLElement;\n /** Screenshot capture behavior and optional native/custom provider. */\n capture?: ScreenshotCaptureOptions;\n /**\n * Screen-recording behavior. By default the Record tab uses the browser\n * `getDisplayMedia` recorder (unavailable on iOS). Set `provider` to delegate\n * recording to a native/custom recorder — e.g. an iOS WebView host using\n * ReplayKit over its postMessage bridge — mirroring `capture.provider`.\n */\n record?: {\n /** When set (and available), the Record tab delegates to this factory instead of getDisplayMedia. */\n provider?: LumenRecordProvider;\n /** Optional availability probe, evaluated when the sheet opens. Defaults to true when provider is set. */\n isAvailable?: () => boolean | Promise<boolean>;\n };\n /**\n * Open the feedback sheet when the user shakes their device. When omitted\n * the SDK uses the dashboard's shake setting from `/api/v1/sdk/config`;\n * pass a boolean to force it on/off locally. Works via the native bridge\n * (a `lumen:shake` postMessage from an Expo/WebView host) and a best-effort\n * web DeviceMotion fallback.\n */\n shakeToOpen?: boolean;\n /**\n * Called exactly once whenever the Lumen sheet opens (`true`) or closes\n * (`false`). Never fires on the initial mount. Correct across all trigger\n * types. No spurious `false` during the 3-step capture wizard — `isOpen`\n * stays `true` throughout.\n *\n * Use this to hide/show native UI in a WebView host. Two complementary\n * approaches work together:\n *\n * **Option A — React prop (same-process host):**\n * ```tsx\n * <LumenProvider\n * onOpenChange={(open) => tabBarRef.current?.setVisible(!open)}\n * >\n * ```\n *\n * **Option B — MutationObserver (injected JS from native shell):**\n * While Lumen is open, `document.body` carries `data-lumen-open=\"true\"`.\n * Observe it from React Native / Capacitor / Electron:\n * ```tsx\n * // React Native (App.tsx)\n * <WebView\n * injectedJavaScript={`\n * const obs = new MutationObserver(() => {\n * const open = document.body.hasAttribute('data-lumen-open');\n * window.ReactNativeWebView.postMessage(\n * JSON.stringify({ type: 'lumen:openChange', open })\n * );\n * });\n * obs.observe(document.body, {\n * attributes: true,\n * attributeFilter: ['data-lumen-open'],\n * });\n * `}\n * onMessage={(e) => {\n * const { type, open } = JSON.parse(e.nativeEvent.data);\n * if (type === 'lumen:openChange') setTabBarVisible(!open);\n * }}\n * />\n * ```\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called before Lumen starts its capture/open flow. Hosts can use this to\n * suppress outside-click dismissal in their own overlay stack.\n */\n beforeOpen?: (event?: Event) => void | Promise<void>;\n /**\n * Alias for hosts that want trigger-specific coordination.\n * Runs after `beforeOpen` and before the pre-open screenshot.\n */\n onTriggerActivate?: (event?: Event) => void | Promise<void>;\n /**\n * Stop the trigger's own pointer/click events from bubbling into host\n * outside-click handlers (Silk/Vaul/Radix), so a host bottom sheet/dialog\n * stays open when the user taps the Lumen trigger. Default `true`. Hosts that\n * listen in the capture phase should still guard with `isLumenEventTarget`.\n */\n isolateEvents?: boolean;\n /**\n * Soft-keyboard height (CSS px) for WebView hosts where\n * `window.visualViewport` does NOT shrink (iOS WKWebView). When set, the\n * trigger lifts above the keyboard and the modal keeps its focused input\n * visible. Prefer `setLumenKeyboardInset()` from injected JS for a native\n * shell; this prop is for same-process hosts that already track the height.\n */\n keyboardInset?: number;\n /**\n * Hide the floating/notch trigger while a host overlay owns the screen (the\n * host's own modal, a full-screen route, etc.). The sheet stays openable\n * programmatically via `useLumen().open()`. Default `false`.\n */\n suppressTrigger?: boolean;\n children: React.ReactNode;\n}\n\nexport function LumenProvider({\n apiKey,\n apiUrl,\n user,\n amplitude,\n floatingButton = true,\n trigger,\n hideOn,\n theme,\n portalTarget,\n capture,\n record,\n shakeToOpen,\n onOpenChange,\n beforeOpen,\n onTriggerActivate,\n isolateEvents = true,\n keyboardInset,\n suppressTrigger = false,\n children,\n}: LumenProviderProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [isOpening, setIsOpening] = useState(false);\n const [initialCapture, setInitialCapture] = useState<CaptureResult | null>(\n null,\n );\n const [initialCaptureError, setInitialCaptureError] =\n useState<Error | null>(null);\n const [isSubmitting] = useState(false);\n const [error] = useState<Error | null>(null);\n const openingRef = useRef(false);\n const triggerPreparedRef = useRef(false);\n const triggerPreparePromiseRef = useRef<Promise<void> | null>(null);\n\n const client = useMemo(\n () => new LumenClient({ apiKey, apiUrl, user, amplitude }),\n [\n apiKey,\n apiUrl,\n user?.id,\n user?.email,\n user?.name,\n amplitude?.userId,\n amplitude?.deviceId,\n amplitude?.sessionId,\n ],\n );\n\n // Patches console + fetch + XHR on mount. Idempotent — safe under\n // Strict Mode double-invocation, and a no-op on the server.\n useEffect(() => {\n installRuntimeCapture({\n ignoreUrlPrefix: (apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, \"\"),\n });\n }, [apiUrl]);\n\n // ── onOpenChange + data-lumen-open DOM attribute ─────────────────────────\n // Kept in two separate effects so the DOM attribute (which needs a cleanup\n // to survive Strict-Mode's fake-unmount cycle) and the callback (which must\n // fire exactly once per transition) stay independent.\n\n // Stable ref so inline callbacks never cause stale-closure problems.\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n // DOM attribute — readable by MutationObserver from injected WebView JS.\n // cleanup runs on Strict-Mode teardown AND real unmount, so the attribute\n // is always removed when this effect version is discarded.\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n if (isOpen) {\n document.body.setAttribute(\"data-lumen-open\", \"true\");\n } else {\n document.body.removeAttribute(\"data-lumen-open\");\n }\n return () => {\n document.body.removeAttribute(\"data-lumen-open\");\n };\n }, [isOpen]);\n\n // Callback — fires exactly once per real open/close transition.\n // prevIsOpenRef starts as null so the initial false on mount is skipped.\n // The `=== isOpen` guard prevents double-fire under Strict-Mode re-runs.\n const prevIsOpenRef = useRef<boolean | null>(null);\n useEffect(() => {\n if (prevIsOpenRef.current === isOpen) return;\n const prev = prevIsOpenRef.current;\n prevIsOpenRef.current = isOpen;\n if (prev === null) return; // initial mount — no transition yet\n onOpenChangeRef.current?.(isOpen);\n }, [isOpen]);\n // ─────────────────────────────────────────────────────────────────────────\n\n const beforeOpenRef = useRef(beforeOpen);\n beforeOpenRef.current = beforeOpen;\n const onTriggerActivateRef = useRef(onTriggerActivate);\n onTriggerActivateRef.current = onTriggerActivate;\n\n const prepareTriggerOpen = useCallback((event: Event) => {\n triggerPreparedRef.current = true;\n triggerPreparePromiseRef.current = Promise.resolve()\n .then(() => beforeOpenRef.current?.(event))\n .then(() => onTriggerActivateRef.current?.(event))\n .then(() => undefined);\n }, []);\n\n const open = useCallback(\n (event?: Event) => {\n // Ignore trigger-initiated opens while a recording is in progress —\n // the sheet only comes back via the HUD's Stop (which avoids a fresh\n // capture clobbering the clip). Covers the provider start/encode windows\n // too, not just the browser recorder.\n if (\n openingRef.current ||\n isOpen ||\n recordingBusyRef.current ||\n screenCaptureBusyRef.current\n )\n return;\n openingRef.current = true;\n setIsOpening(true);\n setInitialCapture(null);\n setInitialCaptureError(null);\n\n void (async () => {\n try {\n if (triggerPreparedRef.current) {\n await triggerPreparePromiseRef.current;\n } else {\n await beforeOpenRef.current?.(event);\n await onTriggerActivateRef.current?.(event);\n }\n\n if (capture?.mode === \"manual\") {\n setInitialCapture(null);\n setInitialCaptureError(null);\n } else if (capture?.provider) {\n // Native/custom providers conceal Lumen's own UI during capture\n // (see createNativeCaptureProvider's concealSelector). They do NOT\n // need the pre-open shot to keep chrome out — and capturing before\n // the wizard mounts was dropping host overlays (e.g. native iOS\n // overlays) from the screenshot. Defer to the wizard, which grabs\n // the shot from a settled frame with Lumen UI concealed.\n setInitialCapture(null);\n setInitialCaptureError(null);\n } else {\n const result = await captureScreen({\n ...capture,\n mode: capture?.mode ?? \"auto\",\n target: capture?.target ?? document.documentElement,\n });\n setInitialCapture(result);\n }\n } catch (e) {\n setInitialCaptureError(\n e instanceof Error ? e : new Error(String(e)),\n );\n } finally {\n triggerPreparedRef.current = false;\n triggerPreparePromiseRef.current = null;\n openingRef.current = false;\n setIsOpening(false);\n setIsOpen(true);\n }\n })();\n },\n [capture, isOpen],\n );\n const close = useCallback(() => {\n setIsOpen(false);\n // Drop the prior screenshot so its PNG Blob/canvas isn't retained across\n // the closed window into the next open — every open captures fresh.\n setInitialCapture(null);\n setInitialCaptureError(null);\n }, []);\n const submit = useCallback(client.submit.bind(client), [client]);\n\n // Bumped when the error boundary catches a widget crash, so the Lumen UI\n // subtree remounts clean and the user can reopen. Closing the sheet here too\n // means the remounted subtree lands on a fresh, non-throwing state.\n const [boundaryKey, setBoundaryKey] = useState(0);\n const resetAfterCrash = useCallback(() => {\n openingRef.current = false;\n setIsOpening(false);\n setIsOpen(false);\n setInitialCapture(null);\n setInitialCaptureError(null);\n setBoundaryKey((k) => k + 1);\n }, []);\n\n // ── Video recording session ──────────────────────────────────────────\n // The recorder (browser MediaRecorder + stream, or a custom provider's\n // session) is a plain JS object that keeps running after the modal unmounts;\n // lifting the session here lets recording survive the sheet being closed and\n // reopened.\n const [recording, setRecording] = useState<VideoRecordingState | null>(null);\n // Probed from `record.isAvailable` when the sheet opens. null = not yet known\n // (treated as available when a provider is set — the spec's default-true).\n const [providerAvailable, setProviderAvailable] = useState<boolean | null>(\n null,\n );\n const activeRecorderRef = useRef<import(\"@lumen-stack/core\").VideoRecorderHandle | null>(\n null,\n ); // browser path\n const providerControlRef = useRef<RecordSessionControl | null>(null); // provider path\n // True across the whole record lifecycle (provider start window included), on\n // either path. Gates trigger re-opens while a recording is busy.\n const recordingBusyRef = useRef(false);\n const posterRef = useRef<Blob | null>(null);\n const pendingVideoRef = useRef<PendingVideo | null>(null);\n // Consume-once error from a failed provider start; surfaced on the Record\n // step when the sheet reopens.\n const recordStartErrorRef = useRef<string | null>(null);\n\n const finalizeVideo = useCallback(\n (rec: { blob: Blob; durationMs: number } | null, fromProvider = false) => {\n activeRecorderRef.current = null;\n providerControlRef.current = null;\n recordingBusyRef.current = false;\n setRecording(null);\n if (!rec) {\n posterRef.current = null;\n return;\n }\n pendingVideoRef.current = {\n blob: rec.blob,\n durationMs: rec.durationMs,\n poster: posterRef.current,\n // Provider clips have no stream-derived poster; let the modal derive\n // one from the blob. Never set on the browser path → unchanged there.\n deriveBlobPoster: fromProvider,\n };\n posterRef.current = null;\n // Reopen the sheet directly — NOT via open(), which runs a fresh\n // screenshot capture and would clobber the just-recorded clip.\n setIsOpen(true);\n },\n [],\n );\n\n // Probe provider availability when the sheet opens. Depends on the stable\n // provider/isAvailable identities (not the `record` object literal, which the\n // host typically re-creates each render).\n useEffect(() => {\n if (!isOpen) return;\n if (!record?.provider) {\n setProviderAvailable(null);\n return;\n }\n const probe = record.isAvailable;\n if (!probe) {\n setProviderAvailable(true);\n return;\n }\n let cancelled = false;\n Promise.resolve()\n .then(() => probe())\n .then((ok) => {\n if (!cancelled) setProviderAvailable(ok);\n })\n .catch(() => {\n if (!cancelled) setProviderAvailable(false);\n });\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, record?.provider, record?.isAvailable]);\n\n const canRecordScreen = resolveRecordCapability({\n hasProvider: !!record?.provider,\n providerAvailable,\n hasGetDisplayMedia: hasGetDisplayMedia(),\n }).canRecord;\n\n const startVideoSession = useCallback(async () => {\n if (recordingBusyRef.current) return;\n recordStartErrorRef.current = null;\n\n const usingProvider = resolveRecordCapability({\n hasProvider: !!record?.provider,\n providerAvailable,\n hasGetDisplayMedia: hasGetDisplayMedia(),\n }).usingProvider;\n\n if (usingProvider && record?.provider) {\n // Provider path: close the sheet FIRST (a native host must not capture\n // the Lumen sheet, and the consent dialog appears over the app), then\n // start. All lifecycle branching lives in driveRecordSession; these\n // callbacks are pure setState.\n recordingBusyRef.current = true;\n posterRef.current = null;\n setIsOpen(false);\n providerControlRef.current = driveRecordSession(\n record.provider,\n { maxDurationSeconds: VIDEO_MAX_SECONDS },\n {\n onStarting: () => setRecording({ phase: \"starting\" }),\n onActive: (session) => {\n setRecording({\n phase: \"recording\",\n stream: session.stream ?? null,\n startedAt: Date.now(),\n maxSeconds: VIDEO_MAX_SECONDS,\n });\n // Live poster only when a stream is exposed (native hosts omit it).\n if (session.stream) {\n void posterFromStream(session.stream)\n .then((p) => {\n posterRef.current = p;\n })\n .catch(() => undefined);\n }\n },\n onProcessing: () => setRecording({ phase: \"processing\" }),\n onResult: (result) =>\n finalizeVideo(\n { blob: result.blob, durationMs: result.durationMs },\n true,\n ),\n onCancelled: () => {\n providerControlRef.current = null;\n recordingBusyRef.current = false;\n posterRef.current = null;\n setRecording(null);\n // Return to the sheet at the method picker, no clip.\n setInitialCapture(null);\n setInitialCaptureError(null);\n setIsOpen(true);\n },\n onError: (err) => {\n providerControlRef.current = null;\n recordingBusyRef.current = false;\n posterRef.current = null;\n setRecording(null);\n recordStartErrorRef.current =\n err.message || \"Screen recording could not start.\";\n setIsOpen(true);\n },\n },\n );\n return;\n }\n\n // Browser path — behavior unchanged from before the provider extension.\n if (activeRecorderRef.current) return;\n // recordVideo() must run from the click's user activation; it throws\n // SCREEN_DENIED if the picker is dismissed (the modal surfaces it).\n const handle = await recordVideo(VIDEO_MAX_SECONDS);\n activeRecorderRef.current = handle;\n recordingBusyRef.current = true;\n posterRef.current = null;\n setRecording({\n phase: \"recording\",\n stream: handle.stream,\n startedAt: Date.now(),\n maxSeconds: VIDEO_MAX_SECONDS,\n });\n setIsOpen(false);\n // Poster from the live first frame (best-effort), grabbed off the hot\n // path so the sheet closes immediately.\n void posterFromStream(handle.stream)\n .then((p) => {\n posterRef.current = p;\n })\n .catch(() => undefined);\n // Single funnel: resolves on manual stop, the browser's \"Stop sharing\",\n // or the 60s cap — all reopen the sheet with the clip.\n handle.result.then((rec) => finalizeVideo(rec)).catch(() => finalizeVideo(null));\n }, [finalizeVideo, record?.provider, providerAvailable]);\n\n const stopVideoSession = useCallback(() => {\n if (providerControlRef.current) providerControlRef.current.stop();\n else activeRecorderRef.current?.stop();\n }, []);\n\n const cancelVideoSession = useCallback(() => {\n if (providerControlRef.current) {\n // The drive's onCancelled callback resets state and reopens the sheet.\n providerControlRef.current.cancel();\n return;\n }\n // Browser path — behavior unchanged.\n const handle = activeRecorderRef.current;\n activeRecorderRef.current = null;\n recordingBusyRef.current = false;\n posterRef.current = null;\n setRecording(null);\n handle?.cancel();\n // Reopen the sheet so Discard returns the user to the picker rather than\n // dumping them out of the flow. Clear any stale pre-open screenshot so\n // the modal lands on the method picker (method === null).\n setInitialCapture(null);\n setInitialCaptureError(null);\n setIsOpen(true);\n }, []);\n\n const consumePendingVideo = useCallback((): PendingVideo | null => {\n const p = pendingVideoRef.current;\n pendingVideoRef.current = null;\n return p;\n }, []);\n\n const consumeRecordStartError = useCallback((): string | null => {\n const e = recordStartErrorRef.current;\n recordStartErrorRef.current = null;\n return e;\n }, []);\n\n // Clear any unconsumed provider-start error when the sheet closes, so a later\n // trigger-open never lands on a stale Record-step error.\n useEffect(() => {\n if (!isOpen) recordStartErrorRef.current = null;\n }, [isOpen]);\n\n // ── \"Capture exact screen\" session (getDisplayMedia) ──────────────────\n // The live stream is held here (not in the modal) so the sheet can hide and\n // the user can scroll/arrange the page before the frame is grabbed — and so\n // the Lumen UI is never in the real-pixel shot.\n const [screenCapture, setScreenCapture] =\n useState<ScreenCaptureState | null>(null);\n const screenSessionRef = useRef<DisplayMediaCaptureSession | null>(null);\n const pendingScreenshotRef = useRef<CaptureResult | null>(null);\n // Gates trigger re-opens while a screen-capture session is live (mirrors\n // recordingBusyRef), so a stray trigger tap can't run a fresh capture.\n const screenCaptureBusyRef = useRef(false);\n\n const cancelScreenCaptureSession = useCallback(() => {\n const session = screenSessionRef.current;\n screenSessionRef.current = null;\n screenCaptureBusyRef.current = false;\n session?.stop();\n setScreenCapture(null);\n // Return to the sheet unchanged (the prior DOM shot is still seeded).\n setIsOpen(true);\n }, []);\n\n const grabScreenCaptureFrame = useCallback(() => {\n const session = screenSessionRef.current;\n if (!session) return;\n setScreenCapture({ phase: \"grabbing\" });\n void (async () => {\n try {\n const result = await session.grab();\n // If the session was torn down mid-grab (e.g. the user hit the\n // browser's \"Stop sharing\", which already reopened the sheet), drop\n // the frame so it can't surface as a stale screenshot on next open.\n if (screenSessionRef.current !== session) return;\n pendingScreenshotRef.current = result;\n screenSessionRef.current = null;\n screenCaptureBusyRef.current = false;\n session.stop();\n setScreenCapture(null);\n // Reopen directly — NOT via open(), which would run a fresh capture\n // and clobber the just-grabbed exact-screen shot.\n setIsOpen(true);\n } catch {\n if (screenSessionRef.current !== session) return;\n screenSessionRef.current = null;\n screenCaptureBusyRef.current = false;\n session.stop();\n setScreenCapture(null);\n toast.error(\"Could not capture the screen. Please try again.\");\n setIsOpen(true);\n }\n })();\n }, []);\n\n const startScreenCaptureSession = useCallback(async () => {\n if (screenCaptureBusyRef.current) return;\n // getDisplayMedia must run from the click's user activation; it rejects if\n // the surface picker is dismissed — in which case we simply stay on the\n // open sheet with the existing DOM screenshot (no session, no error).\n let session: DisplayMediaCaptureSession;\n try {\n session = await startDisplayMediaCapture({ ...capture });\n } catch {\n return;\n }\n screenSessionRef.current = session;\n screenCaptureBusyRef.current = true;\n session.onEnded(() => cancelScreenCaptureSession());\n setScreenCapture({ phase: \"live\" });\n // Hide the sheet so the page is fully usable while the user arranges it.\n setIsOpen(false);\n }, [capture, cancelScreenCaptureSession]);\n\n const consumePendingScreenshot = useCallback((): CaptureResult | null => {\n const r = pendingScreenshotRef.current;\n pendingScreenshotRef.current = null;\n return r;\n }, []);\n\n // Never leave a screen-capture stream live if the provider unmounts mid-\n // session (e.g. the host tears down Lumen while the picker bar is up).\n useEffect(\n () => () => {\n screenSessionRef.current?.stop();\n screenSessionRef.current = null;\n },\n [],\n );\n\n const isNativeShell = useNativeShell();\n const hideTrigger = useHideOn(hideOn);\n\n // Remote config: only fetched when the host hasn't pinned a trigger.\n // Passing the same apiUrl the LumenClient resolves to keeps the two\n // calls in lockstep.\n const remote = useRemoteConfig(\n trigger ? \"\" : apiKey,\n apiUrl ?? DEFAULT_API_URL,\n );\n\n // Theme precedence: an explicit `theme` prop in host code always wins;\n // otherwise apply the dashboard brand config; otherwise \"auto\" (follow the\n // host's prefers-color-scheme via styles.css).\n useApplyTheme(theme ?? brandToTheme(remote.brand));\n\n // Shake-to-open: explicit prop wins; otherwise honor the dashboard setting.\n // `open` is stable (useCallback), so the listener isn't re-bound per render.\n const effectiveShake = shakeToOpen ?? remote.shakeToOpen;\n useShakeToOpen(effectiveShake, open, isOpen);\n\n const value = useMemo<LumenContextValue>(\n () => ({\n client,\n user,\n isOpen,\n isSubmitting,\n error,\n open,\n close,\n openCapture: open,\n closeCapture: close,\n submit,\n isNativeShell,\n capture,\n initialCapture,\n initialCaptureError,\n isOpening,\n startVideoSession,\n stopVideoSession,\n cancelVideoSession,\n recording,\n consumePendingVideo,\n canRecordScreen,\n consumeRecordStartError,\n startScreenCaptureSession,\n grabScreenCaptureFrame,\n cancelScreenCaptureSession,\n screenCapture,\n consumePendingScreenshot,\n isolateEvents,\n keyboardInset,\n }),\n [\n client,\n user,\n isOpen,\n isSubmitting,\n error,\n open,\n close,\n submit,\n isNativeShell,\n capture,\n initialCapture,\n initialCaptureError,\n startVideoSession,\n stopVideoSession,\n cancelVideoSession,\n recording,\n consumePendingVideo,\n canRecordScreen,\n consumeRecordStartError,\n startScreenCaptureSession,\n grabScreenCaptureFrame,\n cancelScreenCaptureSession,\n screenCapture,\n consumePendingScreenshot,\n isOpening,\n isolateEvents,\n keyboardInset,\n ],\n );\n\n const effectiveTrigger = resolveEffectiveTrigger({\n explicit: trigger,\n remote: remote.trigger,\n remoteLoading: remote.loading,\n floatingButton,\n });\n\n return (\n <LumenContext.Provider value={value}>\n {children}\n {/* Lumen's own UI is isolated behind an error boundary so a widget crash\n (e.g. an iOS out-of-memory throw from capture) can never take down the\n host app's tree. `key` remounts it clean after a recovered crash. */}\n <LumenErrorBoundary\n key={boundaryKey}\n onReset={resetAfterCrash}\n onError={(report) =>\n client.reportClientError({\n ...report,\n // Provider-level state at crash time — tells us whether a capture\n // was in flight and at what method/scale (the OOM-theory signal).\n context: {\n open: isOpen,\n opening: isOpening,\n screenCapturePhase: screenCapture?.phase,\n recordingPhase: recording?.phase,\n initialCaptureMethod: initialCapture?.method,\n initialCapturePixelRatio: initialCapture?.pixelRatio,\n initialCaptureViewport: initialCapture?.viewport,\n hadInitialCaptureError: initialCaptureError != null,\n },\n })\n }\n >\n {effectiveTrigger?.kind === \"floating\" ? (\n <FloatingTrigger\n config={resolveFloatingConfig(effectiveTrigger)}\n portalTarget={portalTarget}\n hidden={\n hideTrigger ||\n suppressTrigger ||\n isOpening ||\n recording != null ||\n screenCapture != null\n }\n onPointerDown={prepareTriggerOpen}\n onClick={(event) => open(event)}\n isolateEvents={isolateEvents}\n keyboardInset={keyboardInset}\n />\n ) : null}\n {effectiveTrigger?.kind === \"notch\" ? (\n <NotchTrigger\n config={resolveNotchConfig(effectiveTrigger)}\n portalTarget={portalTarget}\n hidden={\n hideTrigger ||\n suppressTrigger ||\n isOpening ||\n recording != null ||\n screenCapture != null\n }\n onPointerDown={prepareTriggerOpen}\n onClick={(event) => open(event)}\n isolateEvents={isolateEvents}\n />\n ) : null}\n {effectiveTrigger?.kind === \"inline\" ? (\n <InlineTrigger\n mount={effectiveTrigger.mount}\n label={effectiveTrigger.label ?? \"Feedback\"}\n icon={effectiveTrigger.icon}\n onPointerDown={prepareTriggerOpen}\n onClick={(event) => open(event)}\n isolateEvents={isolateEvents}\n />\n ) : null}\n {screenCapture ? (\n <ScreenCaptureHud\n state={screenCapture}\n portalTarget={portalTarget}\n onCapture={grabScreenCaptureFrame}\n onCancel={cancelScreenCaptureSession}\n />\n ) : null}\n {recording ? (\n <RecordingHud\n state={recording}\n portalTarget={portalTarget}\n onStop={stopVideoSession}\n onCancel={cancelVideoSession}\n />\n ) : null}\n <CaptureModal />\n </LumenErrorBoundary>\n <SdkToaster />\n </LumenContext.Provider>\n );\n}\n\n/**\n * The SDK reports every user-facing error (submit failure, mic denied,\n * file rejected, capture warnings) via sonner's `toast()`, which renders\n * nothing unless a `<Toaster />` is mounted somewhere. Hosts can't be\n * expected to mount one, so the provider brings its own — but skips it\n * when the host app already renders a sonner Toaster, since every mounted\n * Toaster displays every toast and we'd duplicate them.\n */\nfunction SdkToaster() {\n const [shouldRender, setShouldRender] = useState(false);\n useEffect(() => {\n // Deferred to an effect so the host's own Toaster (anywhere in its\n // tree) has committed to the DOM before we look for it. The decision\n // is made once — re-checking on later renders would find *our*\n // Toaster and unmount it.\n setShouldRender(!document.querySelector(\"[data-sonner-toaster]\"));\n }, []);\n if (!shouldRender) return null;\n // Above the capture sheet (z-index 2147483647); later-in-DOM wins ties.\n return <Toaster position=\"top-center\" style={{ zIndex: 2147483647 }} />;\n}\n\n/**\n * Trigger resolution precedence:\n * 1. Explicit `trigger` prop wins (host opt-out from remote).\n * 2. `floatingButton={false}` → headless (legacy escape hatch).\n * 3. Remote config from /api/v1/sdk/config.\n * 4. While remote is still loading without a cached value, render\n * nothing (avoids a flash of the default in the wrong place).\n * 5. If remote ultimately fails, fall back to the floating default\n * so the host always has *something*.\n */\nfunction resolveEffectiveTrigger(args: {\n explicit: LumenTrigger | undefined;\n remote: LumenTrigger | null;\n remoteLoading: boolean;\n floatingButton: boolean;\n}): LumenTrigger | null {\n if (args.explicit) return args.explicit;\n if (args.floatingButton === false) return { kind: \"headless\" };\n if (args.remote) return args.remote;\n if (args.remoteLoading) return null;\n return { kind: \"floating\" };\n}\n\n/**\n * Map the dashboard brand config to a custom LumenTheme object. Returns\n * undefined when there's no brand (so useApplyTheme falls back to \"auto\").\n * Background/foreground are intentionally left out — they stay host-adaptive.\n */\nfunction brandToTheme(brand: RemoteBrand | null): LumenTheme | undefined {\n if (!brand) return undefined;\n return {\n accent: brand.accent,\n radius: `${brand.radius}px`,\n scheme: brand.mode,\n };\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useLumen } from \"./context\";\n\nexport interface FeedbackButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"default\" | \"ghost\" | \"outline\";\n /** Render fixed in the bottom-right corner. */\n floating?: boolean;\n}\n\nexport function FeedbackButton({\n variant = \"default\",\n floating = false,\n className,\n children = \"Feedback\",\n onClick,\n ...rest\n}: FeedbackButtonProps) {\n const { openCapture } = useLumen();\n const cls = [\n \"lumen-btn\",\n variant === \"default\" ? \"lumen-btn-primary\" : null,\n variant === \"ghost\" ? \"lumen-btn-ghost\" : null,\n variant === \"outline\" ? \"lumen-btn-outline\" : null,\n floating ? \"lumen-btn-floating\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n type=\"button\"\n className={cls}\n data-lumen-trigger=\"\"\n onClick={(e) => {\n onClick?.(e);\n if (!e.defaultPrevented) openCapture(e.nativeEvent);\n }}\n {...rest}\n >\n {children}\n </button>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../core/src/errors.ts","../../core/src/client.ts","../../core/src/conceal.ts","../../core/src/capture-screenshot.ts","../../core/src/redact.ts","../../core/src/capture-runtime.ts","../../core/src/capture-context.ts","../../core/src/dom-contract.ts","../../core/src/native-bridge.ts","../../core/src/keyboard-inset.ts","../../core/src/record-audio.ts","../../core/src/record-video.ts","../src/context.ts","../src/trigger/useViewportKeyboard.ts","../src/trigger/useKeyboardInset.ts","../src/AnnotationLayer.tsx","../src/icons.tsx","../src/video-poster.ts","../src/CaptureModal.tsx","../src/LumenErrorBoundary.tsx","../src/RecordingHud.tsx","../src/ScreenCaptureHud.tsx","../src/record-availability.ts","../src/record-session.ts","../src/trigger/autoDetectAvoid.ts","../src/trigger/useCollisionInsets.ts","../src/trigger/useTriggerActivation.ts","../src/trigger/FloatingTrigger.tsx","../src/trigger/InlineTrigger.tsx","../src/trigger/NotchTrigger.tsx","../src/trigger/types.ts","../src/trigger/theme.ts","../src/trigger/useHideOn.ts","../src/trigger/useNativeShell.ts","../src/trigger/useRemoteConfig.ts","../src/trigger/useShakeToOpen.ts","../src/LumenProvider.tsx","../src/FeedbackButton.tsx"],"names":["LumenError","message","code","status","LumenOriginError","LumenRateLimitError","retryAfter","LumenNetworkError","DEFAULT_API_URL","SUBMIT_PATH","ERROR_PATH","LUMEN_SDK_VERSION","MAX_CLIENT_ERROR_REPORTS","RETRYABLE_STATUSES","LumenClient","#errorReportKeys","#errorReportCount","config","payload","options","url","body","#buildFormData","lastError","attempt","wait","#sendOnce","e","input","firstFrame","key","nav","mem","u","fd","amplitude","context","screenshotFilename","resolve","reject","xhr","onUploadProgress","signal","onAbort","parseError","parsed","blob","ms","r","text","obj","DEFAULT_CONCEAL","concealLumenChrome","selector","hidden","el","prev","DEFAULT_MAX_SCALE","SMALL_VIEWPORT_MAX_SCALE","SMALL_VIEWPORT_MAX_WIDTH","MAX_CANVAS_MEGAPIXELS","MAX_SCREENSHOT_BYTES","captureScreen","assertBrowser","mode","normalizeProviderResult","captureDisplayMedia","captureDom","domError","canUseDisplayMedia","result","uniq","createManualCaptureResult","warnings","viewport","currentViewport","domCaptureTail","run","doCaptureDom","html2canvas","loadHtml2Canvas","target","layout","layoutViewport","visual","originX","originY","scale","resolveScale","collectDomWarnings","isReactNativeWebView","inputSnapshots","snapshotInputs","waitForAnimationsToSettle","DEFAULT_AWAIT_ANIMATIONS_MS","nextFramePause","canvas","clonedDoc","clonedRef","applyInputSnapshots","maskSensitiveFields","encodeCanvas","MASK_SELECTOR","doc","field","SYNC_EXCLUDE_SELECTOR","collectSyncInputs","root","type","snapshots","inputs","i","snap","startDisplayMediaCapture","stream","video","waitForVideoFrame","track","liveVideo","stopped","endedCbs","cb","grabOptions","shouldConceal","restore","waitForFreshFrames","ctx","session","normalized","crossOriginImages","img","src","canvasToBlob","working","ratio","next","quality","cropWidth","cropHeight","dpr","max","isSmallTouchViewport","budgetScale","touch","layoutW","maxMs","animations","pending","a","timing","settled","cap","done","fail","start","MAX_WAIT_MS","minFrames","rvfc","seen","tick","values","SENSITIVE_PARAM","KNOWN_SECRET_PATTERNS","isLuhnValid","raw","digits","sum","double","d","redactText","s","re","whole","quote","value","m","redactUrl","k","out","stripUrlToPath","MAX_ENTRIES","MAX_STRING","consoleBuf","networkBuf","installed","ignoreUrlPrefix","installRuntimeCapture","patchConsole","patchFetch","patchXhr","readRuntimeCapture","pushBounded","buf","entry","safeStringify","args","arg","replacer","joined","_key","levels","level","original","isIgnored","originalFetch","init","method","started","res","sanitizeUrl","OriginalXHR","originalOpen","originalSend","rest","meta","onDone","truncate","captureContext","capture","toCaptureMetadata","runtime","snapshotDevice","device","LUMEN_ROOT_SELECTOR","LUMEN_MARKER_SELECTOR","isLumenEventTarget","event","path","isLumenNode","ISOLATED_EVENT_TYPES","isolateLumenEvents","stop","LUMEN_SHAKE_MESSAGE","DEFAULT_TIMEOUT_MS","DEFAULT_CAPTURE_SETTLE_MS","createNativeCaptureProvider","registry","ensureRegistry","send","defaultSend","timeoutMs","captureSettleMs","awaitAnimationsMs","id","newRequestId","settleAfterConceal","response","timer","dataUrlToBlob","platform","detectPlatform","request","rn","dataUrl","pixelRatio","error","onMessage","data","parseMessage","nextAnimationFrame","ua","match","mime","isBase64","binary","bytes","LUMEN_KEYBOARD_EVENT","LUMEN_KEYBOARD_CSS_VAR","setLumenKeyboardInset","insetPx","px","readLumenKeyboardInset","g","recordAudio","maxSeconds","mimeType","recorder","chunks","timeoutId","cancelled","resolveResult","rejectResult","durationMs","finalType","requestStop","recordVideo","release","LumenContext","createContext","useLumen","useContext","KEYBOARD_THRESHOLD","isEditableElementFocused","tag","CLOSED","decideKeyboardInset","explicit","open","delta","useKeyboardInset","enabled","override","state","setState","useState","baselineRef","useRef","overrideRef","useEffect","coarse","recompute","editable","injected","wt","vv","raf","schedule","se","BUBBLE_FONT","clamp01","v","AnnotationLayer","_n","screenshot","tool","color","strokeWidth","onDrawingChange","onHistoryChange","ref","baseCanvasRef","overlayCanvasRef","containerRef","imageBitmap","setImageBitmap","baseDrawFailed","setBaseDrawFailed","fallbackUrl","setFallbackUrl","annotations","setAnnotations","draftRef","isDrawingRef","lastSampleAtRef","rafPendingRef","comments","setComments","seqRef","undoStackRef","redoStackRef","annotationsRef","commentsRef","pendingFocusRef","onHistoryChangeRef","fireHistory","useCallback","handleCommentChange","cur","c","handleCommentRemove","decoded","bm","base","overlay","redraw","useImperativeHandle","last","removed","draft","all","liveComments","anno","drawAnno","renderedWidth","bubbleScale","drawBubble","clientToCanvas","rect","sx","sy","scheduleDraftPaint","onPointerDown","fx","fy","p","onPointerMove","dist2","now","elapsed","onPointerUp","dx","dy","jsxs","jsx","Bubble","comment","onChange","onRemove","elRef","x","y","w","h","drawSmoothPath","from","to","width","angle","head","points","first","second","mx","my","W","H","pad","fontPx","labelPx","radius","lineH","labelH","maxBoxW","lines","wrapText","textW","l","boxW","boxH","roundRect","tailX","tailY","ty","line","maxWidth","words","test","anyCtx","Svg","children","props","IconScreenshot","IconVideo","IconUpload","IconComment","IconArrow","IconBox","IconDraw","IconUndo","IconRefresh","IconRedo","IconTrash","IconChevronLeft","IconSend","IconMonitor","IconMic","METHOD_ICONS","drawPoster","b","seek","POSTER_DECODE_TIMEOUT_MS","posterFromVideoBlob","poster","deadline","posterFromStream","placeholderPoster","VOICE_MAX_SECONDS","VIDEO_SIZE_WARN_BYTES","SWATCHES","STROKE_SIZES","CATEGORIES","PRIORITIES","SOURCE_CHIPS","deriveSource","PriorityIcon","METHODS","CaptureModal","client","isOpen","closeCapture","user","initialCapture","initialCaptureError","startVideoSession","consumePendingVideo","canRecordScreen","consumeRecordStartError","startScreenCaptureSession","consumePendingScreenshot","isolateEvents","keyboardInset","step","setStep","setMethod","phase","setPhase","submitting","setSubmitting","progress","setProgress","setTool","strokeColor","setStrokeColor","setStrokeWidth","setText","category","setCategory","priority","setPriority","source","setSource","toolsHidden","setToolsHidden","sheetCollapsed","setSheetCollapsed","recapMenuOpen","setRecapMenuOpen","colorPickerOpen","setColorPickerOpen","submitterEmail","setSubmitterEmail","setRecorder","audio","setAudio","recordSecs","setRecordSecs","setVideo","videoError","setVideoError","drawing","setDrawing","history","setHistory","annotationRef","uploadInputRef","modalRef","backdropRef","previouslyFocusedRef","keyboard","captureCancelledRef","seededRef","pendingShot","showCaptureWarnings","toast","Se","posterBlob","startErr","runCapture","html","prevOverflow","prevPaddingRight","scrollbar","restored","onKey","focusables","getFocusable","active","stopOnBackdrop","onPaste","file","item","acceptUploadedFile","sec","finishRecording","recorderRef","A","selectMethod","discardVideo","startRecording","ht","discardRecording","renderVoiceNote","variant","controls","Fragment","Waveform","AudioPreview","beginVideoRecording","captured","goNext","submit","goBack","trimmed","captureResult","flatScreenshot","V","fraction","onBackdropMouseDown","uploadingPct","isVideoMethod","trueScreenAvailable","showExactCapture","nextDisabled","nextLabel","captureFullscreen","reviewFullscreen","fsMode","SheetGrabber","Stepper","Icon","RecordPrompt","o","ToolButton","captureLabel","steps","canRecord","onRecord","onUpload","isIOSBrowser","label","onClick","icon","onDismiss","startYRef","startTimeRef","targetRef","dt","velocity","canvasRef","cssWidth","cssHeight","AudioCtor","audioCtx","analyser","BARS","GAP","MIN_H","barW","frame","bucketSize","getCssVar","peak","j","roundRectPath","setUrl","name","FOCUSABLE_SELECTOR","LumenErrorBoundary","Qn","info","err","RecordingHud","portalTarget","onStop","onCancel","mounted","setMounted","createPortal","RecordingControl","startedAt","setElapsed","fmt","ScreenCaptureHud","onCapture","grabbing","resolveRecordCapability","providerUsable","isRecorderStopped","asError","driveRecordSession","provider","stopRequested","finishCancelled","finishResult","finishError","detectBottomFloor","probeY","probeXs","tallest","stack","cs","measureExplicitAvoidForSide","selectors","side","nodes","node","overlap","useCollisionInsets","insets","setInsets","lastRef","avoidKey","avoidToKey","placement","offsetX","offsetY","measure","xSide","yExtra","xExtra","ro","mo","avoid","STOP_ONLY_EVENTS","useTriggerActivation","pdRef","clickRef","isolateRef","cleanupRef","stopOnly","FloatingTrigger","setTarget","buttonRef","activate","setButton","sideY","sideX","placementBottom","liftPx","hideForKeyboard","useOcclusionWarning","yPx","xPx","concealed","style","warnedRef","t","cx","cy","ourZ","parseZ","candidate","z","n","InlineTrigger","mount","NotchTrigger","onActivatePointerDown","expanded","setExpanded","dragStartRef","className","onPointerCancel","resolveNotchConfig","cfg","resolveKeyboardBehavior","resolveFloatingConfig","VAR_MAP","useApplyTheme","theme","instanceId","useId","attr","slug","previous","setVar","cssVar","PATCH_FLAG","EVENT_NAME","ensureHistoryPatch","dispatch","origPush","origReplace","useHideOn","predicate","setHidden","evaluate","NATIVE_UA_TOKENS","useNativeShell","native","setNative","wk","STORAGE_PREFIX","STORAGE_TTL_MS","useRemoteConfig","apiKey","apiUrl","cached","readCache","triggerEnabled","controller","trigger","parseTrigger","shake","parseShake","brand","parseBrand","writeCache","VALID_PLACEMENTS","VALID_EDGES","HEX6","VALID_MODES","accent","isShakeMessage","nt","createMotionShakeDetector","threshold","neededHits","windowMs","throttleMs","hits","useShakeToOpen","onShake","lastFire","COOLDOWN_MS","fire","detector","onMotion","hasMotion","VIDEO_MAX_SECONDS","hasGetDisplayMedia","LumenProvider","floatingButton","hideOn","record","shakeToOpen","onOpenChange","beforeOpen","onTriggerActivate","suppressTrigger","setIsOpen","isOpening","setIsOpening","setInitialCapture","setInitialCaptureError","isSubmitting","openingRef","triggerPreparedRef","triggerPreparePromiseRef","useMemo","E","Be","onOpenChangeRef","prevIsOpenRef","beforeOpenRef","onTriggerActivateRef","prepareTriggerOpen","recordingBusyRef","screenCaptureBusyRef","close","boundaryKey","setBoundaryKey","resetAfterCrash","recording","setRecording","providerAvailable","setProviderAvailable","activeRecorderRef","providerControlRef","posterRef","pendingVideoRef","recordStartErrorRef","finalizeVideo","rec","fromProvider","probe","ok","handle","bt","stopVideoSession","cancelVideoSession","screenCapture","setScreenCapture","screenSessionRef","pendingScreenshotRef","cancelScreenCaptureSession","grabScreenCaptureFrame","Z","isNativeShell","hideTrigger","remote","brandToTheme","effectiveShake","effectiveTrigger","resolveEffectiveTrigger","report","SdkToaster","shouldRender","setShouldRender","Toaster","FeedbackButton","floating","openCapture","cls"],"mappings":"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","file":"index.cjs","sourcesContent":["export class LumenError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status?: number,\n ) {\n super(message);\n this.name = \"LumenError\";\n }\n}\n\nexport class LumenOriginError extends LumenError {\n constructor() {\n super(\n \"Origin not allowed. Add this origin in your Lumen project settings.\",\n \"ORIGIN_NOT_ALLOWED\",\n 403,\n );\n this.name = \"LumenOriginError\";\n }\n}\n\nexport class LumenRateLimitError extends LumenError {\n constructor(public readonly retryAfter: number) {\n super(\n `Rate limited — retry after ${retryAfter}s.`,\n \"RATE_LIMITED\",\n 429,\n );\n this.name = \"LumenRateLimitError\";\n }\n}\n\nexport class LumenNetworkError extends LumenError {\n constructor(message: string) {\n super(message, \"NETWORK_ERROR\");\n this.name = \"LumenNetworkError\";\n }\n}\n","import type {\n AmplitudeIdentity,\n ClientErrorReport,\n LumenClientConfig,\n LumenUser,\n SubmitOptions,\n SubmitPayload,\n SubmitResult,\n} from \"./types\";\nimport {\n LumenError,\n LumenNetworkError,\n LumenOriginError,\n LumenRateLimitError,\n} from \"./errors\";\n\nconst DEFAULT_API_URL = \"https://shakebugs.vercel.app\";\nconst SUBMIT_PATH = \"/api/v1/sdk/submit\";\nconst ERROR_PATH = \"/api/v1/sdk/error\";\n\n// Kept in sync with @lumen-stack/core's package version at publish time — a\n// coarse signal for which SDK build a crash came from. A patch of drift is\n// harmless; it just narrows \"which release\" in the telemetry.\nconst LUMEN_SDK_VERSION = \"0.13.2\";\n// Hard cap on crash reports per client session, so a render-loop that remounts\n// straight into another crash can't turn the boundary into a beacon flood.\nconst MAX_CLIENT_ERROR_REPORTS = 5;\n\nconst RETRYABLE_STATUSES = new Set([502, 503, 504]);\n\nexport class LumenClient {\n readonly apiKey: string;\n readonly apiUrl: string;\n user: LumenUser | undefined;\n amplitude: AmplitudeIdentity | undefined;\n // Per-session de-dupe + cap for client-error beacons.\n #errorReportKeys = new Set<string>();\n #errorReportCount = 0;\n\n constructor(config: LumenClientConfig) {\n if (!config.apiKey || !config.apiKey.startsWith(\"lk_pub_\")) {\n throw new LumenError(\n \"Invalid Lumen apiKey — expected a key starting with `lk_pub_`.\",\n \"INVALID_API_KEY\",\n );\n }\n this.apiKey = config.apiKey;\n this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, \"\");\n this.user = config.user;\n this.amplitude = config.amplitude;\n }\n\n /**\n * Submit a feedback payload. Uses XHR (not fetch) so we can surface\n * upload-progress events to the UI. Retries up to 2 times on 5xx /\n * network errors with exponential backoff.\n */\n async submit(\n payload: SubmitPayload,\n options: SubmitOptions = {},\n ): Promise<SubmitResult> {\n const url = `${this.apiUrl}${SUBMIT_PATH}`;\n const body = this.#buildFormData(payload);\n\n let lastError: unknown = null;\n for (let attempt = 0; attempt < 3; attempt++) {\n if (attempt > 0) {\n await wait(2 ** attempt * 250);\n }\n try {\n return await this.#sendOnce(url, body, options);\n } catch (e) {\n lastError = e;\n // Don't retry deterministic client errors.\n if (\n e instanceof LumenOriginError ||\n e instanceof LumenRateLimitError\n ) {\n throw e;\n }\n if (\n e instanceof LumenError &&\n typeof e.status === \"number\" &&\n !RETRYABLE_STATUSES.has(e.status)\n ) {\n throw e;\n }\n }\n }\n if (lastError instanceof Error) throw lastError;\n throw new LumenNetworkError(\"Submit failed after 3 attempts.\");\n }\n\n /**\n * Best-effort crash beacon. Called by the React error boundary when the\n * widget's own UI throws during render/commit — the channel that tells us\n * WHY the web widget \"hit a snag\", since the crash itself prevents a normal\n * feedback submission. Never throws, never blocks the page, and is capped +\n * deduped per session. The boundary supplies the error fields; this fills in\n * ambient environment (the memory fields directly test the OOM theory).\n */\n reportClientError(input: ClientErrorReport): void {\n try {\n if (typeof window === \"undefined\") return;\n if (this.#errorReportCount >= MAX_CLIENT_ERROR_REPORTS) return;\n const firstFrame = (input.stack ?? \"\").split(\"\\n\")[1]?.trim() ?? \"\";\n const key = `${input.name}:${input.message}@${firstFrame}`;\n if (this.#errorReportKeys.has(key)) return;\n this.#errorReportKeys.add(key);\n this.#errorReportCount += 1;\n\n const nav = typeof navigator !== \"undefined\" ? navigator : undefined;\n const mem =\n typeof performance !== \"undefined\"\n ? (\n performance as Performance & {\n memory?: { usedJSHeapSize?: number; jsHeapSizeLimit?: number };\n }\n ).memory\n : undefined;\n\n // Origin + path only — never the query/hash, which can carry tokens/PII.\n let url: string | undefined;\n try {\n const u = new URL(window.location.href);\n url = u.origin + u.pathname;\n } catch {\n url = undefined;\n }\n\n const body = {\n message: String(input.message ?? \"\").slice(0, 1000),\n name: String(input.name ?? \"Error\").slice(0, 200),\n stack: input.stack?.slice(0, 8000),\n componentStack: input.componentStack?.slice(0, 8000),\n url,\n userAgent: nav?.userAgent,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n dpr: window.devicePixelRatio,\n deviceMemory: (nav as Navigator & { deviceMemory?: number } | undefined)\n ?.deviceMemory,\n jsHeap: mem\n ? { used: mem.usedJSHeapSize, limit: mem.jsHeapSizeLimit }\n : undefined,\n sdkVersion: LUMEN_SDK_VERSION,\n context: input.context,\n };\n\n void fetch(`${this.apiUrl}${ERROR_PATH}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Lumen-Api-Key\": this.apiKey,\n },\n body: JSON.stringify(body),\n keepalive: true,\n credentials: \"omit\",\n mode: \"cors\",\n }).catch(() => {\n // Swallow — telemetry failure must never surface to the user.\n });\n } catch {\n // Telemetry must never throw back into the error boundary's recovery.\n }\n }\n\n #buildFormData(payload: SubmitPayload): FormData {\n const fd = new FormData();\n if (payload.rawText) fd.append(\"rawText\", payload.rawText);\n if (payload.category) fd.append(\"category\", payload.category);\n if (payload.priority) fd.append(\"priority\", payload.priority);\n if (payload.source) fd.append(\"source\", payload.source);\n if (payload.submitterEmail) fd.append(\"submitterEmail\", payload.submitterEmail);\n if (payload.submitterFingerprint) {\n fd.append(\"submitterFingerprint\", payload.submitterFingerprint);\n }\n // Inject the configured Amplitude identity into the context channel\n // (unless the caller already set one on the payload). These are\n // analytics ids, not PII — the server reads them to pull the user's\n // event timeline during enrichment.\n const amplitude = payload.context.amplitude ?? this.amplitude;\n const context = amplitude\n ? { ...payload.context, amplitude }\n : payload.context;\n fd.append(\"context\", JSON.stringify(context));\n if (payload.screenshot) {\n fd.append(\n \"screenshot\",\n payload.screenshot,\n screenshotFilename(payload.screenshot),\n );\n }\n if (payload.audio) {\n fd.append(\"audio\", payload.audio, \"audio\");\n }\n if (payload.audioDurationMs != null) {\n fd.append(\"audioDurationMs\", String(payload.audioDurationMs));\n }\n if (payload.video) {\n fd.append(\"video\", payload.video, \"video\");\n }\n if (payload.videoDurationMs != null) {\n fd.append(\"videoDurationMs\", String(payload.videoDurationMs));\n }\n // `user` (id/email/name) is intentionally NOT sent. The server has\n // never read these fields, so transmitting them just leaks PII over\n // the wire for no benefit. The `LumenUser` type stays in the public\n // API as a no-op until a future release adds an authenticated\n // identity flow that the server can actually trust.\n return fd;\n }\n\n #sendOnce(\n url: string,\n body: FormData,\n options: SubmitOptions,\n ): Promise<SubmitResult> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open(\"POST\", url, true);\n xhr.setRequestHeader(\"X-Lumen-Api-Key\", this.apiKey);\n xhr.responseType = \"text\";\n\n const { onUploadProgress, signal } = options;\n\n if (onUploadProgress) {\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable && e.total > 0) {\n onUploadProgress(Math.min(1, e.loaded / e.total));\n }\n });\n }\n\n const onAbort = () => {\n xhr.abort();\n reject(new LumenNetworkError(\"Submit aborted.\"));\n };\n if (signal) {\n if (signal.aborted) {\n reject(new LumenNetworkError(\"Submit aborted.\"));\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n xhr.addEventListener(\"load\", () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n\n if (xhr.status === 403) {\n reject(new LumenOriginError());\n return;\n }\n if (xhr.status === 429) {\n const retryAfter = Number(xhr.getResponseHeader(\"Retry-After\")) || 60;\n reject(new LumenRateLimitError(retryAfter));\n return;\n }\n if (xhr.status < 200 || xhr.status >= 300) {\n reject(\n new LumenError(\n parseError(xhr.responseText) ?? `HTTP ${xhr.status}`,\n \"HTTP_ERROR\",\n xhr.status,\n ),\n );\n return;\n }\n try {\n const parsed = JSON.parse(xhr.responseText) as SubmitResult;\n resolve(parsed);\n } catch {\n reject(new LumenError(\"Malformed response from server.\", \"BAD_RESPONSE\"));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n reject(new LumenNetworkError(\"Network error during submit.\"));\n });\n\n xhr.send(body);\n });\n }\n}\n\nfunction screenshotFilename(blob: Blob): string {\n const ext =\n blob.type === \"image/jpeg\"\n ? \"jpg\"\n : blob.type === \"image/webp\"\n ? \"webp\"\n : \"png\";\n return `screenshot.${ext}`;\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nfunction parseError(text: string): string | null {\n try {\n const obj = JSON.parse(text) as { error?: string; message?: string };\n return obj.error ?? obj.message ?? null;\n } catch {\n return text || null;\n }\n}\n","/**\n * Hide Lumen's own UI before a *real-pixel* capture (native screenshot,\n * browser `getDisplayMedia`). Unlike the DOM/html2canvas path — which can\n * skip elements via `data-lumen-capture-ignore` — a real screen grab records\n * whatever is actually painted, so the only way to keep the widget out of the\n * shot is to make it `visibility: hidden` for the duration of the capture.\n */\n\n/** Lumen-owned roots + anything tagged capture-ignore (trigger, sheet, HUDs). */\nexport const DEFAULT_CONCEAL =\n '[data-lumen-root], [data-lumen-capture-ignore=\"true\"]';\n\n/**\n * Hide matching elements via `visibility: hidden`; returns a `restore()` that\n * puts each element's previous inline visibility back. Safe to call with a\n * null selector or outside the browser (returns a no-op restore).\n */\nexport function concealLumenChrome(\n selector: string | null = DEFAULT_CONCEAL,\n): () => void {\n if (!selector || typeof document === \"undefined\") return () => {};\n const hidden: Array<{ el: HTMLElement; prev: string }> = [];\n for (const el of Array.from(\n document.querySelectorAll<HTMLElement>(selector),\n )) {\n hidden.push({ el, prev: el.style.visibility });\n el.style.visibility = \"hidden\";\n }\n return () => {\n for (const { el, prev } of hidden) el.style.visibility = prev;\n };\n}\n","import { concealLumenChrome } from \"./conceal\";\nimport { LumenError } from \"./errors\";\nimport type {\n CaptureResult,\n ScreenshotCaptureOptions,\n} from \"./types\";\n\nconst DEFAULT_MAX_SCALE = 2;\n// Phones (esp. iOS Safari/WKWebView) jettison the page when html2canvas\n// rasterizes a heavy document at full DPR. Clamp the raster scale harder on\n// small touch viewports and never let the output canvas exceed a pixel budget,\n// trading a little sharpness for not crashing.\nconst SMALL_VIEWPORT_MAX_SCALE = 1.5;\nconst SMALL_VIEWPORT_MAX_WIDTH = 820;\nconst MAX_CANVAS_MEGAPIXELS = 12;\nconst MAX_SCREENSHOT_BYTES = 8 * 1024 * 1024;\n\ntype Html2Canvas = typeof import(\"html2canvas-pro\").default;\n\nlet html2canvasForTest: Html2Canvas | null = null;\n\nexport function __setHtml2CanvasForTest(renderer: Html2Canvas | null): void {\n html2canvasForTest = renderer;\n}\n\n/**\n * Capture the visible app screen with method/platform metadata.\n *\n * `mode: \"auto\"` keeps the no-permission DOM path first, then falls\n * back to the browser Screen Capture API if DOM rendering fails.\n * Hosts that need native-quality pixels can pass a custom provider.\n */\nexport async function captureScreen(\n options: ScreenshotCaptureOptions = {},\n): Promise<CaptureResult> {\n assertBrowser();\n\n const mode = options.mode ?? \"auto\";\n\n if (options.provider && (mode === \"auto\" || mode === \"custom\")) {\n try {\n return normalizeProviderResult(await options.provider(), options);\n } catch (e) {\n if (mode === \"custom\") throw e;\n // In auto mode a broken custom provider should not strand web apps.\n options.onWarning?.([\n \"Custom capture provider failed; falling back to browser DOM capture.\",\n ]);\n }\n }\n\n if (mode === \"manual\") {\n throw new LumenError(\n \"Manual screenshot upload is required for this capture mode.\",\n \"MANUAL_CAPTURE_REQUIRED\",\n );\n }\n\n if (mode === \"true-screen\") {\n return captureDisplayMedia(options);\n }\n\n if (mode === \"dom\") {\n return captureDom(options);\n }\n\n if (mode === \"custom\") {\n throw new LumenError(\n \"`capture.provider` is required when capture mode is `custom`.\",\n \"CAPTURE_PROVIDER_REQUIRED\",\n );\n }\n\n try {\n return await captureDom(options);\n } catch (domError) {\n if (canUseDisplayMedia()) {\n const result = await captureDisplayMedia(options);\n result.warnings = uniq([\n \"DOM screenshot failed; used browser screen permission fallback.\",\n ...result.warnings,\n ]);\n options.onWarning?.(result.warnings);\n return result;\n }\n throw domError;\n }\n}\n\n/**\n * Back-compatible wrapper kept for existing integrations.\n * New code should prefer `captureScreen()` so capture quality metadata\n * can be stored with the feedback.\n */\nexport async function captureScreenshot(\n target?: HTMLElement,\n): Promise<Blob> {\n const result = await captureScreen({ target, mode: \"auto\" });\n return result.blob;\n}\n\nexport function createManualCaptureResult(\n blob: Blob,\n warnings: string[] = [],\n): CaptureResult {\n assertBrowser();\n const viewport = currentViewport();\n return {\n blob,\n method: \"manual-upload\",\n platform: \"web\",\n viewport,\n pixelRatio: window.devicePixelRatio ?? 1,\n warnings: uniq(warnings),\n };\n}\n\n// Serializes DOM captures: html2canvas mutates shared cache/clone state and\n// isn't concurrency-safe, and two heavy passes overlapping is exactly what OOMs\n// iOS Safari on a fast open→cancel→reopen. Each call queues behind the previous\n// one (regardless of how the previous settled) so only one pass runs at a time.\nlet domCaptureTail: Promise<unknown> = Promise.resolve();\n\nfunction captureDom(\n options: ScreenshotCaptureOptions,\n): Promise<CaptureResult> {\n const run = domCaptureTail.then(\n () => doCaptureDom(options),\n () => doCaptureDom(options),\n );\n domCaptureTail = run.catch(() => undefined);\n return run;\n}\n\nasync function doCaptureDom(\n options: ScreenshotCaptureOptions,\n): Promise<CaptureResult> {\n const html2canvas = await loadHtml2Canvas();\n\n const target = options.target ?? document.documentElement;\n // Visual viewport = the region the user actually sees (and the crop size).\n const viewport = currentViewport();\n // Layout viewport = where the page lays out (vw/vh, fixed elements). On iOS\n // Safari these diverge; sizing the clone to the layout viewport and offsetting\n // the crop by the visual viewport's position keeps the shot aligned.\n const layout = layoutViewport();\n const visual = window.visualViewport;\n const originX = window.scrollX + (visual?.offsetLeft ?? 0);\n const originY = window.scrollY + (visual?.offsetTop ?? 0);\n const scale = resolveScale(options, viewport.width, viewport.height);\n const warnings = collectDomWarnings(target);\n if (!options.provider && isReactNativeWebView()) {\n // The DOM path is an html2canvas re-render, not a real screen grab: it\n // can't match native rendering and drops native overlays plus the live\n // text a user typed into native inputs. Surface the misconfiguration\n // instead of silently shipping a wrong-looking shot.\n warnings.unshift(\n \"Lumen is capturing inside a React Native WebView with no native capture \" +\n \"provider, so this screenshot is a DOM re-render — it won't match the \" +\n \"native screen and omits native overlays/inputs. Wire \" +\n 'createNativeCaptureProvider() with capture mode \"custom\" (see ' +\n \"docs/native-screenshot-expo.md).\",\n );\n }\n\n // html2canvas renders an <input>'s text from the *cloned* node's `.value`,\n // but cloneNode() copies only the `value` attribute — not the live value a\n // user typed — so typed text reverts to the placeholder. Snapshot live input\n // state now and re-apply it onto the clone in onclone. (Textareas and selects\n // are already handled by html2canvas itself via `clone.value = node.value`.)\n const inputSnapshots = snapshotInputs(target);\n\n // Wait for any in-flight CSS transition/animation (e.g. a host bottom sheet\n // finishing its open animation) to settle so the shot captures the real\n // resting frame, not a mid-animation one.\n await waitForAnimationsToSettle(\n options.awaitAnimationsMs ?? DEFAULT_AWAIT_ANIMATIONS_MS,\n );\n\n // Give the browser a frame to composite and reclaim the previous capture\n // session's canvases/bitmaps before we allocate this one. Without it, a fast\n // open→cancel→reopen stacks two rasterizations and exhausts iOS Safari's\n // memory budget — the white-screen crash.\n await nextFramePause();\n\n const canvas = await html2canvas(target, {\n backgroundColor: null,\n logging: false,\n useCORS: true,\n allowTaint: false,\n width: viewport.width,\n height: viewport.height,\n windowWidth: layout.width,\n windowHeight: layout.height,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n x: originX,\n y: originY,\n scale,\n ignoreElements: (el) =>\n el instanceof HTMLElement &&\n (el.dataset.lumenCaptureIgnore === \"true\" ||\n Boolean(el.closest(\"[data-lumen-capture-ignore='true']\"))),\n onclone: (clonedDoc, clonedRef) => {\n // Order matters: restore live values first, then mask — so any secret is\n // overwritten with bullets before the clone is rasterized.\n applyInputSnapshots(clonedRef, inputSnapshots);\n maskSensitiveFields(clonedDoc);\n },\n });\n\n const blob = await encodeCanvas(canvas, warnings);\n const result = {\n blob,\n method: \"web-dom\",\n platform: \"web\",\n viewport,\n pixelRatio: scale,\n warnings: uniq(warnings),\n } satisfies CaptureResult;\n if (result.warnings.length > 0) options.onWarning?.(result.warnings);\n return result;\n}\n\n/**\n * Selectors whose on-screen values must never end up in a screenshot:\n * password inputs, payment-card and one-time-code fields, and anything\n * the host explicitly tags with `data-lumen-mask`. Runs against the\n * CLONED document html2canvas renders from, so the live page is\n * untouched. (The `true-screen`/native paths rasterize real pixels and\n * cannot be masked — hosts should use `data-lumen-capture-ignore` and\n * this masking via the default DOM mode for sensitive views.)\n */\nconst MASK_SELECTOR = [\n 'input[type=\"password\"]',\n 'input[autocomplete^=\"cc-\"]',\n 'input[autocomplete=\"one-time-code\"]',\n \"[data-lumen-mask]\",\n].join(\", \");\n\nfunction maskSensitiveFields(doc: Document): void {\n for (const el of Array.from(doc.querySelectorAll(MASK_SELECTOR))) {\n // html2canvas renders from a clone living in its own <iframe> realm, so\n // `instanceof HTMLInputElement` (this realm's constructor) is always false\n // there. Branch on nodeName, which is realm-agnostic, so masking actually\n // runs against the rendered clone.\n if (el.nodeName === \"INPUT\" || el.nodeName === \"TEXTAREA\") {\n const field = el as HTMLInputElement | HTMLTextAreaElement;\n if (field.value) field.value = \"••••••••\";\n continue;\n }\n // Any other element: blank the region but keep the layout. html2canvas\n // skips visibility:hidden subtrees, leaving the element's box empty.\n (el as HTMLElement).style.visibility = \"hidden\";\n }\n}\n\n/**\n * Live `<input>` state captured just before html2canvas clones the page, then\n * re-applied onto the cloned inputs in `onclone`. This restores the typed text\n * and checkbox/radio state that `cloneNode()` drops (it copies only the `value`\n * attribute, not an input's live \"dirty\" value), which otherwise makes typed\n * text fall back to the placeholder in the screenshot.\n */\ninterface InputSnapshot {\n /** Sensitive or unsettable inputs are skipped; masking blanks those. */\n skip: boolean;\n value?: string;\n checked?: boolean;\n}\n\n/** Lumen's own UI, excluded so live↔clone input indices stay aligned. */\nconst SYNC_EXCLUDE_SELECTOR =\n \"[data-lumen-root], [data-lumen-capture-ignore='true']\";\n\nfunction collectSyncInputs(root: ParentNode): HTMLInputElement[] {\n return Array.from(root.querySelectorAll<HTMLInputElement>(\"input\")).filter(\n (el) => !el.closest(SYNC_EXCLUDE_SELECTOR),\n );\n}\n\nfunction snapshotInputs(root: ParentNode): InputSnapshot[] {\n return collectSyncInputs(root).map((el) => {\n // Never copy sensitive values into the clone; maskSensitiveFields blanks\n // these instead. Skipping here also avoids relying on cross-realm masking.\n if (el.matches(MASK_SELECTOR)) return { skip: true };\n const type = el.type;\n if (type === \"checkbox\" || type === \"radio\") {\n return { skip: false, checked: el.checked };\n }\n // File inputs can't be assigned programmatically; nothing to restore.\n if (type === \"file\") return { skip: true };\n return { skip: false, value: el.value };\n });\n}\n\nfunction applyInputSnapshots(\n root: ParentNode,\n snapshots: InputSnapshot[],\n): void {\n const inputs = collectSyncInputs(root);\n // Indices only align when the live and cloned input sets match 1:1. If the\n // host mutated the DOM between snapshot and clone, skip rather than risk\n // writing a value into the wrong field.\n if (inputs.length !== snapshots.length) return;\n inputs.forEach((el, i) => {\n const snap = snapshots[i];\n if (!snap || snap.skip) return;\n if (snap.checked !== undefined) el.checked = snap.checked;\n else if (snap.value !== undefined) el.value = snap.value;\n });\n}\n\nfunction isReactNativeWebView(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof (window as unknown as { ReactNativeWebView?: unknown })\n .ReactNativeWebView !== \"undefined\"\n );\n}\n\nasync function loadHtml2Canvas(): Promise<Html2Canvas> {\n if (html2canvasForTest) return html2canvasForTest;\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n return html2canvas;\n}\n\n/**\n * A live `getDisplayMedia` capture held open between the browser surface picker\n * and the actual frame grab. This lets the UI hide its own chrome and let the\n * user arrange/scroll the page before deciding the exact moment to capture —\n * instead of grabbing the first frame the instant the picker resolves.\n */\nexport interface DisplayMediaCaptureSession {\n readonly stream: MediaStream;\n /**\n * Draw the current live frame to a `CaptureResult`. By default it first\n * conceals Lumen's own UI (`visibility: hidden`) and waits for the live\n * stream to reflect that — real screen pixels can't be masked, so this is\n * the only way to keep the widget out of the shot. Pass `{ conceal: false }`\n * for one-shot captures taken when no Lumen UI is on screen.\n */\n grab(options?: { conceal?: boolean }): Promise<CaptureResult>;\n /** Stop all tracks and release the video element. Idempotent. */\n stop(): void;\n /** Register a callback fired when the user ends sharing (\"Stop sharing\"). */\n onEnded(cb: () => void): void;\n}\n\n/**\n * Open a `getDisplayMedia` session and wait for its first frame, but do NOT\n * grab yet — the caller decides when via `session.grab()`. Throws if the\n * picker is dismissed or screen capture is unavailable.\n */\nexport async function startDisplayMediaCapture(\n options: ScreenshotCaptureOptions = {},\n): Promise<DisplayMediaCaptureSession> {\n assertBrowser();\n if (!canUseDisplayMedia()) {\n throw new LumenError(\n \"Browser screen capture is unavailable in this environment.\",\n \"DISPLAY_MEDIA_UNAVAILABLE\",\n );\n }\n\n const stream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n audio: false,\n });\n\n let video: HTMLVideoElement | null = null;\n try {\n video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n video.srcObject = stream;\n await waitForVideoFrame(video);\n } catch (e) {\n for (const track of stream.getTracks()) track.stop();\n throw e;\n }\n\n const liveVideo = video;\n let stopped = false;\n const endedCbs: Array<() => void> = [];\n\n // The user can end sharing from the browser's own UI; surface that as a\n // track 'ended' so the host can tear the session down and reopen the sheet.\n for (const track of stream.getTracks()) {\n track.addEventListener(\"ended\", () => {\n if (!stopped) endedCbs.forEach((cb) => cb());\n });\n }\n\n return {\n stream,\n onEnded(cb) {\n endedCbs.push(cb);\n },\n async grab(grabOptions) {\n const shouldConceal = grabOptions?.conceal ?? true;\n const restore = shouldConceal ? concealLumenChrome() : () => {};\n try {\n // Give the live stream a few frames to reflect the just-concealed UI\n // so the widget's own chrome never lands in the real-pixel shot.\n if (shouldConceal) await waitForFreshFrames(liveVideo, 3, 400);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = liveVideo.videoWidth;\n canvas.height = liveVideo.videoHeight;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new LumenError(\n \"Could not create a drawing context for screen capture.\",\n \"CANVAS_CONTEXT_UNAVAILABLE\",\n );\n }\n ctx.drawImage(liveVideo, 0, 0, canvas.width, canvas.height);\n\n const viewport = currentViewport();\n const warnings = [\n \"Browser screen capture uses the window or tab selected by the user.\",\n ];\n const blob = await encodeCanvas(canvas, warnings);\n const result = {\n blob,\n method: \"web-display-media\",\n platform: \"web\",\n viewport,\n pixelRatio:\n viewport.width > 0 ? canvas.width / viewport.width : undefined,\n warnings: uniq(warnings),\n } satisfies CaptureResult;\n options.onWarning?.(result.warnings);\n return result;\n } finally {\n restore();\n }\n },\n stop() {\n if (stopped) return;\n stopped = true;\n for (const track of stream.getTracks()) track.stop();\n liveVideo.srcObject = null;\n },\n };\n}\n\n/**\n * One-shot screen capture: open a session, grab the first frame, stop. Used by\n * the auto-fallback path (DOM capture failed) where no Lumen UI is on screen,\n * so concealment is unnecessary.\n */\nasync function captureDisplayMedia(\n options: ScreenshotCaptureOptions,\n): Promise<CaptureResult> {\n const session = await startDisplayMediaCapture(options);\n try {\n return await session.grab({ conceal: false });\n } finally {\n session.stop();\n }\n}\n\nfunction normalizeProviderResult(\n result: CaptureResult,\n options: ScreenshotCaptureOptions,\n): CaptureResult {\n const viewport = currentViewport();\n const normalized = {\n ...result,\n method: result.method ?? \"custom\",\n platform: result.platform ?? \"custom\",\n viewport: result.viewport ?? viewport,\n pixelRatio: result.pixelRatio ?? window.devicePixelRatio ?? 1,\n warnings: uniq(result.warnings ?? []),\n } satisfies CaptureResult;\n if (normalized.warnings.length > 0) options.onWarning?.(normalized.warnings);\n return normalized;\n}\n\nfunction collectDomWarnings(target: HTMLElement): string[] {\n const warnings = new Set<string>();\n\n if (target.querySelector(\"iframe\")) {\n warnings.add(\"Embedded iframes may be blank or incomplete in DOM capture.\");\n }\n if (target.querySelector(\"video\")) {\n warnings.add(\"Video frames may be blank or stale in DOM capture.\");\n }\n if (target.querySelector(\"canvas\")) {\n warnings.add(\"Canvas/WebGL content may be blank if it is cross-origin tainted.\");\n }\n if (document.fonts && document.fonts.status !== \"loaded\") {\n warnings.add(\"Web fonts were still loading when the screenshot was captured.\");\n }\n\n let crossOriginImages = 0;\n for (const img of Array.from(target.querySelectorAll(\"img\"))) {\n const src = img.currentSrc || img.src;\n if (!src) continue;\n try {\n const url = new URL(src, window.location.href);\n if (url.origin !== window.location.origin && !img.crossOrigin) {\n crossOriginImages += 1;\n }\n } catch {\n // Invalid image URLs are ignored here; html2canvas will handle them.\n }\n }\n if (crossOriginImages > 0) {\n warnings.add(\n `${crossOriginImages} cross-origin image${crossOriginImages === 1 ? \"\" : \"s\"} without CORS may be omitted from the screenshot.`,\n );\n }\n\n return Array.from(warnings);\n}\n\nasync function encodeCanvas(\n canvas: HTMLCanvasElement,\n warnings: string[],\n): Promise<Blob> {\n let blob = await canvasToBlob(canvas, \"image/png\", 0.92);\n if (blob.size <= MAX_SCREENSHOT_BYTES) return blob;\n\n warnings.push(\"Screenshot exceeded the upload cap and was compressed.\");\n\n // Progressively downscale + re-encode until we're under the cap, or until\n // the image is too small to be useful. Without this loop a very large\n // screenshot from a 4K monitor at 2x DPR could still exceed the cap after\n // a single pass and silently fail to upload server-side.\n let working = canvas;\n let attempt = 0;\n while (blob.size > MAX_SCREENSHOT_BYTES && attempt < 6) {\n const ratio = Math.max(\n 0.35,\n Math.min(0.95, Math.sqrt(MAX_SCREENSHOT_BYTES / blob.size) * 0.9),\n );\n const next = document.createElement(\"canvas\");\n next.width = Math.max(1, Math.round(working.width * ratio));\n next.height = Math.max(1, Math.round(working.height * ratio));\n const ctx = next.getContext(\"2d\");\n if (!ctx) return blob;\n ctx.drawImage(working, 0, 0, next.width, next.height);\n working = next;\n\n for (const quality of [0.86, 0.74, 0.62, 0.5]) {\n blob = await canvasToBlob(working, \"image/jpeg\", quality);\n if (blob.size <= MAX_SCREENSHOT_BYTES) return blob;\n }\n\n attempt += 1;\n if (next.width < 480 || next.height < 320) break;\n }\n\n if (blob.size > MAX_SCREENSHOT_BYTES) {\n warnings.push(\n \"Screenshot remained large after compression; upload may be rejected.\",\n );\n }\n return blob;\n}\n\nfunction canvasToBlob(\n canvas: HTMLCanvasElement,\n type: \"image/png\" | \"image/jpeg\",\n quality: number,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new LumenError(\"Could not encode screenshot.\", \"ENCODE_FAILED\"));\n return;\n }\n resolve(blob);\n },\n type,\n quality,\n );\n });\n}\n\nfunction currentViewport(): { width: number; height: number } {\n const visual = window.visualViewport;\n return {\n width: Math.round(visual?.width ?? window.innerWidth),\n height: Math.round(visual?.height ?? window.innerHeight),\n };\n}\n\n/** Layout viewport — where the page lays out (vw/vh, fixed positioning). */\nfunction layoutViewport(): { width: number; height: number } {\n const doc = document.documentElement;\n return {\n width: Math.round(doc.clientWidth || window.innerWidth),\n height: Math.round(doc.clientHeight || window.innerHeight),\n };\n}\n\n/**\n * Resolve the raster scale: DPR capped by maxScale (default 2), clamped to 1.5×\n * on small touch viewports, and finally bounded so the output canvas never\n * exceeds MAX_CANVAS_MEGAPIXELS however large the page × DPR is.\n */\nfunction resolveScale(\n options: ScreenshotCaptureOptions,\n cropWidth: number,\n cropHeight: number,\n): number {\n const dpr = window.devicePixelRatio ?? 1;\n let max = options.maxScale ?? DEFAULT_MAX_SCALE;\n if (isSmallTouchViewport()) max = Math.min(max, SMALL_VIEWPORT_MAX_SCALE);\n const scale = Math.max(1, Math.min(dpr, max));\n const budgetScale = Math.sqrt(\n (MAX_CANVAS_MEGAPIXELS * 1_000_000) /\n Math.max(1, cropWidth * cropHeight),\n );\n return Math.max(1, Math.min(scale, budgetScale));\n}\n\nfunction isSmallTouchViewport(): boolean {\n const touch =\n (typeof navigator !== \"undefined\" && (navigator.maxTouchPoints ?? 0) > 0) ||\n (typeof window !== \"undefined\" && \"ontouchstart\" in window);\n const layoutW = document.documentElement.clientWidth || window.innerWidth || 0;\n return touch && layoutW > 0 && layoutW <= SMALL_VIEWPORT_MAX_WIDTH;\n}\n\n/**\n * Yield one painted frame (double rAF) so the browser can reclaim memory before\n * the next allocation. Falls back to a short timeout where rAF is unavailable\n * (non-browser test envs).\n */\nfunction nextFramePause(): Promise<void> {\n if (typeof requestAnimationFrame !== \"function\") {\n return new Promise((resolve) => setTimeout(resolve, 32));\n }\n return new Promise((resolve) =>\n requestAnimationFrame(() => requestAnimationFrame(() => resolve())),\n );\n}\n\nconst DEFAULT_AWAIT_ANIMATIONS_MS = 400;\n\n/**\n * Wait (bounded) for in-flight CSS transitions/animations to finish before a\n * snapshot, so capture reflects the settled frame rather than a mid-animation\n * one — the cause of the \"half-dismissed bottom sheet\" screenshot. Looping /\n * infinite animations (spinners) are ignored so they can't stall capture.\n * Always resolves within `maxMs`.\n */\nexport async function waitForAnimationsToSettle(maxMs: number): Promise<void> {\n if (\n typeof document === \"undefined\" ||\n typeof (document as Document).getAnimations !== \"function\" ||\n !(maxMs > 0)\n ) {\n return;\n }\n let animations: Animation[];\n try {\n animations = document.getAnimations();\n } catch {\n return;\n }\n const pending = animations.filter((a) => {\n if (a.playState !== \"running\") return false;\n const timing = a.effect?.getComputedTiming?.();\n // Skip endless loops (spinners, pulsing dots) — they never finish.\n return Boolean(timing) && timing!.iterations !== Infinity;\n });\n if (pending.length === 0) return;\n const settled = Promise.allSettled(pending.map((a) => a.finished)).then(\n () => undefined,\n );\n const cap = new Promise<void>((resolve) => setTimeout(resolve, maxMs));\n await Promise.race([settled, cap]);\n}\n\nfunction canUseDisplayMedia(): boolean {\n return Boolean(navigator.mediaDevices?.getDisplayMedia);\n}\n\nasync function waitForVideoFrame(video: HTMLVideoElement): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const done = () => resolve();\n const fail = () =>\n reject(new LumenError(\"Could not read screen capture video.\", \"VIDEO_FAILED\"));\n video.addEventListener(\"loadedmetadata\", done, { once: true });\n video.addEventListener(\"error\", fail, { once: true });\n void video.play().catch(fail);\n });\n\n // Wait until the browser actually reports a non-zero frame size. We poll\n // via rAF (cheap, paints-aligned) with a hard cap so a stalled stream\n // can't hang the capture flow.\n const start = performance.now();\n const MAX_WAIT_MS = 1500;\n while (video.videoWidth === 0 || video.videoHeight === 0) {\n if (performance.now() - start > MAX_WAIT_MS) {\n throw new LumenError(\n \"Screen capture did not produce a frame in time.\",\n \"VIDEO_TIMEOUT\",\n );\n }\n await new Promise<void>((resolve) =>\n requestAnimationFrame(() => resolve()),\n );\n }\n}\n\n/**\n * Resolve once the live capture stream has presented `minFrames` new frames\n * (so a just-applied DOM change — e.g. concealing Lumen's chrome — is reflected\n * in the pixels we're about to grab), bounded by `maxMs` so a stalled/low-fps\n * stream can never hang the grab. Uses `requestVideoFrameCallback` where\n * available; otherwise falls back to a single bounded delay.\n */\nasync function waitForFreshFrames(\n video: HTMLVideoElement,\n minFrames: number,\n maxMs: number,\n): Promise<void> {\n const rvfc = (\n video as HTMLVideoElement & {\n requestVideoFrameCallback?: (cb: () => void) => number;\n }\n ).requestVideoFrameCallback?.bind(video);\n if (typeof rvfc !== \"function\") {\n await new Promise<void>((resolve) =>\n setTimeout(resolve, Math.min(maxMs, 250)),\n );\n return;\n }\n const start = performance.now();\n let seen = 0;\n await new Promise<void>((resolve) => {\n const tick = () => {\n seen += 1;\n if (seen >= minFrames || performance.now() - start >= maxMs) {\n resolve();\n return;\n }\n rvfc(tick);\n };\n rvfc(tick);\n setTimeout(resolve, maxMs); // hard cap; resolve() is idempotent\n });\n}\n\nfunction assertBrowser(): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new LumenError(\n \"Screenshot capture can only run in the browser.\",\n \"INVALID_ENV\",\n );\n }\n}\n\nfunction uniq(values: string[]): string[] {\n return Array.from(new Set(values.filter(Boolean)));\n}\n","/**\n * Client-side secret scrubbing for captured breadcrumbs and page context.\n *\n * This is the FIRST line of defense: it runs before anything enters the\n * ring buffers, so tokens logged by the host app never leave the page at\n * all. The server applies the same rules again at ingest (defense in\n * depth — a hostile client can skip this file, but honest SDKs shouldn't\n * ship secrets). Mirrors `packages/ai/src/breadcrumbs.ts`; kept as a\n * standalone copy because the published SDK deliberately has no\n * workspace dependencies.\n *\n * Conservative by design: masks obvious credentials and opaque\n * high-entropy tokens, leaves ordinary text intact so the debugging\n * signal survives.\n */\n\n/** Query/body params whose VALUES are credentials/PII and must be masked. */\nconst SENSITIVE_PARAM =\n /^(token|access_token|refresh_token|id_token|api_?key|key|secret|password|passwd|pwd|auth|authorization|sig|signature|session|sessionid|sid|email|jwt)$/i;\n\n/**\n * Fixed-shape secrets that must be masked wherever they appear — even when\n * logged bare (`console.log(token)`), space-separated, or nested in JSON,\n * none of which the `key=value` rule below catches. Each has a distinctive\n * prefix or structure, so false positives on ordinary text are negligible.\n */\nconst KNOWN_SECRET_PATTERNS: readonly RegExp[] = [\n // PEM private key blocks.\n /-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----[\\s\\S]*?-----END (?:[A-Z]+ )?PRIVATE KEY-----/g,\n // JSON Web Tokens (header.payload.signature).\n /\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+/g,\n // AWS access key IDs.\n /\\b(?:AKIA|ASIA|AGPA|AIDA|AROA|ANPA|ANVA|AIPA)[A-Z0-9]{16}\\b/g,\n // GitHub tokens (PAT / OAuth / app / refresh) + fine-grained PATs.\n /\\bgh[posru]_[A-Za-z0-9]{20,}\\b/g,\n /\\bgithub_pat_[A-Za-z0-9_]{20,}\\b/g,\n // GitLab personal access tokens.\n /\\bglpat-[A-Za-z0-9_-]{18,}\\b/g,\n // Slack tokens.\n /\\bxox[baprs]-[A-Za-z0-9-]{10,}\\b/g,\n // Google API keys.\n /\\bAIza[A-Za-z0-9_-]{35}\\b/g,\n // Stripe-style prefixed secret/restricted/publishable keys.\n /\\b[srp]k_(?:live|test)_[A-Za-z0-9]{10,}\\b/g,\n // OpenAI / Anthropic style keys (long, to avoid masking kebab-case text).\n /\\bsk-(?:proj-|ant-)?[A-Za-z0-9_-]{32,}\\b/g,\n];\n\n/** Luhn check so credit-card masking doesn't fire on arbitrary digit runs. */\nfunction isLuhnValid(raw: string): boolean {\n const digits = raw.replace(/\\D/g, \"\");\n if (digits.length < 13 || digits.length > 19) return false;\n let sum = 0;\n let double = false;\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48;\n if (double) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n double = !double;\n }\n return sum % 10 === 0;\n}\n\n/** Best-effort secret scrubbing for an arbitrary log string. */\nexport function redactText(input: string): string {\n let s = input;\n\n // Fixed-shape secrets first — masks bare/JSON-nested tokens the pair rule\n // can't see, and collapses real JWT values to *** before later passes.\n for (const re of KNOWN_SECRET_PATTERNS) s = s.replace(re, \"***\");\n\n // Authorization headers / bearer tokens embedded in messages.\n s = s.replace(/\\b(Bearer|Basic)\\s+[A-Za-z0-9._\\-+/=]+/gi, \"$1 ***\");\n\n // `key=value` / `key: value` / `\"key\":\"value\"` credential pairs in free\n // text, query strings, or JSON (the optional `\"?` after the key matches\n // a quoted JSON property name).\n s = s.replace(\n /\\b([A-Za-z_][\\w-]*)\"?\\s*[=:]\\s*(\"?)([^\"\\s&]{6,})\\2/g,\n (whole, key: string, quote: string, value: string) => {\n // Scheme keyword (e.g. `Authorization: Bearer ***`) — the bearer rule\n // above already masked the real token; don't re-chew the keyword.\n if (/^(Bearer|Basic)$/i.test(value)) return whole;\n if (SENSITIVE_PARAM.test(key)) return `${key}=${quote}***${quote}`;\n // Mask long opaque tokens regardless of key name (JWTs, hex, base64url).\n if (\n value.length >= 24 &&\n /^[A-Za-z0-9._\\-+/=]+$/.test(value) &&\n !value.includes(\" \")\n ) {\n return `${key}=${quote}${value.slice(0, 4)}…${quote}`;\n }\n return whole;\n },\n );\n\n // Credit-card-like digit runs (Luhn-validated) and US SSNs.\n s = s.replace(/\\b\\d(?:[ -]?\\d){12,18}\\b/g, (m) => (isLuhnValid(m) ? \"***\" : m));\n s = s.replace(/\\b\\d{3}-\\d{2}-\\d{4}\\b/g, \"***\");\n\n // Bare email addresses.\n s = s.replace(/\\b[\\w.+-]+@[\\w-]+\\.[\\w.-]+\\b/g, \"***@***\");\n\n return s;\n}\n\n/**\n * Mask credential query params in a URL while keeping it a usable URL\n * (scheme, host, path, and harmless params survive). Falls back to plain\n * text redaction when the input doesn't parse.\n */\nexport function redactUrl(raw: string): string {\n try {\n const u = new URL(raw, \"http://relative.invalid\");\n for (const k of [...u.searchParams.keys()]) {\n if (SENSITIVE_PARAM.test(k)) u.searchParams.set(k, \"***\");\n }\n // URL fragments never reach servers but DO reach our capture — and\n // OAuth implicit flows put access tokens there. Drop them outright.\n u.hash = \"\";\n const out = u.toString();\n // Relative inputs keep their relative form.\n return redactText(\n u.host === \"relative.invalid\"\n ? out.replace(/^http:\\/\\/relative\\.invalid/, \"\")\n : out,\n );\n } catch {\n return redactText(raw);\n }\n}\n\n/**\n * Reduce a page URL to origin + path. Query strings and fragments\n * routinely carry reset tokens, magic-link tokens, and PII — none of\n * which a feedback tool needs to identify the page.\n */\nexport function stripUrlToPath(raw: string): string {\n try {\n const u = new URL(raw);\n return `${u.origin}${u.pathname}`;\n } catch {\n return redactUrl(raw);\n }\n}\n","/**\n * Lightweight runtime capture: console + fetch/XHR ring buffers.\n *\n * Patched lazily on first install; idempotent. The buffers are drained\n * (not cleared) when `readRuntimeCapture()` is called so multiple\n * submissions in one session each get the latest tail.\n *\n * Entries are redacted BEFORE they enter the buffers (see redact.ts):\n * tokens/credentials a host app logs to the console or puts in request\n * URLs never leave the page, rather than being scrubbed server-side\n * after the fact.\n *\n * Keep this file dependency-free and small — it sits on every host\n * page's main bundle.\n */\nimport { redactText, redactUrl } from \"./redact\";\n\nconst MAX_ENTRIES = 200;\nconst MAX_STRING = 4096;\n\ntype ConsoleLevel = \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\";\n\nexport interface ConsoleEntry {\n level: ConsoleLevel;\n ts: number;\n message: string;\n}\n\nexport interface NetworkEntry {\n type: \"fetch\" | \"xhr\";\n method: string;\n url: string;\n status: number;\n ok: boolean;\n durationMs: number;\n ts: number;\n error?: string;\n}\n\nconst consoleBuf: ConsoleEntry[] = [];\nconst networkBuf: NetworkEntry[] = [];\n\nlet installed = false;\nlet ignoreUrlPrefix: string | null = null;\n\nexport interface InstallRuntimeCaptureOptions {\n /**\n * Requests to URLs starting with this prefix are skipped — prevents\n * the SDK from logging its own submit/config calls in a recursive\n * loop and from leaking apiKey headers into the buffer.\n */\n ignoreUrlPrefix?: string;\n}\n\nexport function installRuntimeCapture(\n options: InstallRuntimeCaptureOptions = {},\n): void {\n if (installed) return;\n if (typeof window === \"undefined\") return;\n installed = true;\n ignoreUrlPrefix = options.ignoreUrlPrefix ?? null;\n patchConsole();\n patchFetch();\n patchXhr();\n}\n\nexport function readRuntimeCapture(): {\n consoleLog: ConsoleEntry[];\n networkLog: NetworkEntry[];\n} {\n return {\n consoleLog: consoleBuf.slice(),\n networkLog: networkBuf.slice(),\n };\n}\n\nfunction pushBounded<T>(buf: T[], entry: T): void {\n buf.push(entry);\n if (buf.length > MAX_ENTRIES) buf.splice(0, buf.length - MAX_ENTRIES);\n}\n\nfunction safeStringify(args: unknown[]): string {\n const out: string[] = [];\n for (const arg of args) {\n if (typeof arg === \"string\") {\n out.push(arg);\n continue;\n }\n if (arg instanceof Error) {\n out.push(`${arg.name}: ${arg.message}${arg.stack ? `\\n${arg.stack}` : \"\"}`);\n continue;\n }\n try {\n out.push(JSON.stringify(arg, replacer));\n } catch {\n out.push(String(arg));\n }\n }\n const joined = out.join(\" \");\n return joined.length > MAX_STRING\n ? joined.slice(0, MAX_STRING) + \"…[truncated]\"\n : joined;\n}\n\n// Drops common circular refs (DOM nodes, React fibers) so JSON.stringify\n// doesn't throw and the buffer stays small.\nfunction replacer(_key: string, value: unknown): unknown {\n if (value instanceof Element) return `[Element ${(value as Element).tagName}]`;\n if (typeof value === \"function\") return \"[Function]\";\n return value;\n}\n\nfunction patchConsole(): void {\n const target = window.console;\n if (!target) return;\n const levels: ConsoleLevel[] = [\"log\", \"info\", \"warn\", \"error\", \"debug\"];\n for (const level of levels) {\n const original = target[level]?.bind(target);\n if (!original) continue;\n target[level] = (...args: unknown[]) => {\n try {\n pushBounded(consoleBuf, {\n level,\n ts: Date.now(),\n message: redactText(safeStringify(args)),\n });\n } catch {\n // Never let our interception throw into the host app.\n }\n original(...args);\n };\n }\n}\n\nfunction isIgnored(url: string): boolean {\n if (!ignoreUrlPrefix) return false;\n return url.startsWith(ignoreUrlPrefix);\n}\n\nfunction patchFetch(): void {\n const originalFetch = window.fetch;\n if (typeof originalFetch !== \"function\") return;\n window.fetch = async function patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n const method = (init?.method ?? (input instanceof Request ? input.method : \"GET\")).toUpperCase();\n if (isIgnored(url)) {\n return originalFetch.call(window, input as RequestInfo, init);\n }\n const started = performance.now();\n try {\n const res = await originalFetch.call(window, input as RequestInfo, init);\n pushBounded(networkBuf, {\n type: \"fetch\",\n method,\n url: sanitizeUrl(url),\n status: res.status,\n ok: res.ok,\n durationMs: Math.round(performance.now() - started),\n ts: Date.now(),\n });\n return res;\n } catch (e) {\n pushBounded(networkBuf, {\n type: \"fetch\",\n method,\n url: sanitizeUrl(url),\n status: 0,\n ok: false,\n durationMs: Math.round(performance.now() - started),\n ts: Date.now(),\n error: e instanceof Error ? e.message : \"fetch error\",\n });\n throw e;\n }\n } as typeof window.fetch;\n}\n\nfunction patchXhr(): void {\n const OriginalXHR = window.XMLHttpRequest;\n if (!OriginalXHR) return;\n const originalOpen = OriginalXHR.prototype.open;\n const originalSend = OriginalXHR.prototype.send;\n\n OriginalXHR.prototype.open = function patchedOpen(\n this: XMLHttpRequest & { __lumen?: { method: string; url: string; t: number } },\n method: string,\n url: string | URL,\n ...rest: unknown[]\n ) {\n this.__lumen = {\n method: String(method).toUpperCase(),\n url: typeof url === \"string\" ? url : url.toString(),\n t: 0,\n };\n // @ts-expect-error variadic passthrough\n return originalOpen.call(this, method, url, ...rest);\n } as typeof OriginalXHR.prototype.open;\n\n OriginalXHR.prototype.send = function patchedSend(\n this: XMLHttpRequest & { __lumen?: { method: string; url: string; t: number } },\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n const meta = this.__lumen;\n if (meta && !isIgnored(meta.url)) {\n meta.t = performance.now();\n const onDone = () => {\n try {\n pushBounded(networkBuf, {\n type: \"xhr\",\n method: meta.method,\n url: sanitizeUrl(meta.url),\n status: this.status,\n ok: this.status >= 200 && this.status < 400,\n durationMs: Math.round(performance.now() - meta.t),\n ts: Date.now(),\n });\n } catch {\n // ignore\n }\n this.removeEventListener(\"loadend\", onDone);\n };\n this.addEventListener(\"loadend\", onDone);\n }\n return originalSend.call(this, body ?? null);\n } as typeof OriginalXHR.prototype.send;\n}\n\nfunction truncate(s: string): string {\n return s.length > 512 ? s.slice(0, 512) + \"…\" : s;\n}\n\n/** Redact-then-truncate for captured request URLs. */\nfunction sanitizeUrl(url: string): string {\n return truncate(redactUrl(url));\n}\n","import { readRuntimeCapture } from \"./capture-runtime\";\nimport { stripUrlToPath } from \"./redact\";\nimport type {\n CapturedContext,\n CaptureMetadata,\n CaptureResult,\n DeviceContext,\n} from \"./types\";\n\n/**\n * Snapshot of basic page context at submit-time.\n *\n * Console + network logs are sourced from the runtime ring buffer when\n * `installRuntimeCapture()` has been called by the host (the React\n * provider does this on mount). When the host hasn't installed\n * interception the buffer is empty and the legacy `[]` is sent — same\n * shape, no migration impact.\n */\nexport function captureContext(\n capture?: CaptureResult | CaptureMetadata,\n): CapturedContext {\n if (typeof window === \"undefined\") {\n return {\n url: \"\",\n userAgent: \"\",\n viewport: { width: 0, height: 0 },\n capture: toCaptureMetadata(capture),\n consoleLog: [],\n networkLog: [],\n };\n }\n\n const runtime = readRuntimeCapture();\n return {\n // Origin + path only. Query strings and fragments routinely carry\n // reset tokens, magic links, and PII — none needed to identify the\n // page a report came from.\n url: stripUrlToPath(window.location.href),\n userAgent: navigator.userAgent,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n capture: toCaptureMetadata(capture),\n device: snapshotDevice(),\n consoleLog: runtime.consoleLog,\n networkLog: runtime.networkLog,\n };\n}\n\nfunction snapshotDevice(): DeviceContext {\n const device: DeviceContext = {};\n try {\n device.screen = {\n width: window.screen?.width ?? 0,\n height: window.screen?.height ?? 0,\n };\n device.pixelRatio = window.devicePixelRatio ?? 1;\n device.language = navigator.language;\n device.languages = Array.from(navigator.languages ?? []);\n device.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n device.colorScheme = window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n device.referrer = document.referrer\n ? stripUrlToPath(document.referrer)\n : undefined;\n device.title = document.title || undefined;\n device.online = navigator.onLine;\n const nav = performance.getEntriesByType(\"navigation\")[0] as\n | PerformanceNavigationTiming\n | undefined;\n if (nav) {\n device.uptimeMs = Math.round(performance.now());\n }\n } catch {\n // Best-effort snapshot — don't block submit on a missing API.\n }\n return device;\n}\n\nfunction toCaptureMetadata(\n capture?: CaptureResult | CaptureMetadata,\n): CaptureMetadata | undefined {\n if (!capture) return undefined;\n return {\n method: capture.method,\n platform: capture.platform,\n viewport: capture.viewport,\n pixelRatio: capture.pixelRatio,\n warnings: capture.warnings,\n };\n}\n","const LUMEN_ROOT_SELECTOR = \"[data-lumen-root]\";\nconst LUMEN_MARKER_SELECTOR =\n \"[data-lumen-root], [data-lumen-trigger], [data-lumen-capture-ignore='true']\";\n\n/**\n * Public DOM contract for host overlay outside-click handlers.\n *\n * Lumen mounts its owned UI under a stable `[data-lumen-root]` host when using\n * the framework-agnostic mount. React trigger elements also carry stable Lumen\n * markers. Use this helper from document-level pointer/click handlers to keep\n * host sheets or modals open when the user activates Lumen.\n */\nexport function isLumenEventTarget(event: Event): boolean {\n const path =\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\n\n for (const entry of path) {\n if (isLumenNode(entry)) return true;\n }\n\n return isLumenNode(event.target);\n}\n\n/**\n * Pointer/click event types a host overlay's outside-click listener typically\n * reacts to. Stopping their bubble-phase propagation keeps a tap on Lumen-owned\n * UI from reading as an outside-click in the host's sheet/dialog layer.\n */\nconst ISOLATED_EVENT_TYPES = [\n \"pointerdown\",\n \"mousedown\",\n \"touchstart\",\n \"click\",\n] as const;\n\n/**\n * Make a Lumen-owned element a good citizen inside host overlays: stop its own\n * pointer/click events from bubbling into host document-level outside-click\n * handlers (Silk / Vaul / Radix dismissable layers). Bubble-phase only — hosts\n * that listen in the *capture* phase should additionally guard with\n * {@link isLumenEventTarget}. Returns a cleanup function.\n *\n * Safe for all-native subtrees (the framework-agnostic mount). React widgets\n * must instead bind their activation handlers natively (see the React SDK's\n * `useTriggerActivation`) because React 18 delegates events at the tree root, so\n * a `stopPropagation` from a synthetic handler runs *after* the host already saw\n * the event.\n */\nexport function isolateLumenEvents(el: Element): () => void {\n if (!el || typeof el.addEventListener !== \"function\") return () => {};\n const stop = (event: Event) => event.stopPropagation();\n for (const type of ISOLATED_EVENT_TYPES) {\n el.addEventListener(\n type,\n stop,\n type === \"touchstart\" ? { passive: true } : undefined,\n );\n }\n return () => {\n for (const type of ISOLATED_EVENT_TYPES) {\n el.removeEventListener(type, stop);\n }\n };\n}\n\nfunction isLumenNode(value: unknown): boolean {\n if (!value) return false;\n\n if (typeof Element !== \"undefined\" && value instanceof Element) {\n if (value.matches(LUMEN_MARKER_SELECTOR)) return true;\n return Boolean(value.closest(LUMEN_ROOT_SELECTOR));\n }\n\n if (typeof ShadowRoot !== \"undefined\" && value instanceof ShadowRoot) {\n return isLumenNode(value.host);\n }\n\n return false;\n}\n","import { waitForAnimationsToSettle } from \"./capture-screenshot\";\nimport { concealLumenChrome, DEFAULT_CONCEAL } from \"./conceal\";\nimport { LumenError } from \"./errors\";\nimport type {\n CaptureMethod,\n CaptureResult,\n CapturePlatform,\n ScreenshotCaptureProvider,\n} from \"./types\";\n\n/**\n * Native-screenshot bridge for WebView hosts (Expo / react-native-webview,\n * Capacitor, …).\n *\n * The browser DOM renderer (`html2canvas`) only rasterizes what lives in the\n * DOM, so anything the native layer draws — native overlays, modals, tab\n * bars, the OS status bar — never shows up. To get a pixel-accurate shot of\n * what the user actually sees, capture has to happen on the native side\n * (e.g. `react-native-view-shot`).\n *\n * This helper builds a `ScreenshotCaptureProvider` you can pass straight into\n * `<LumenProvider capture={{ mode: \"custom\", provider }}>`. When Lumen needs a\n * screenshot it:\n * 1. requests the native host to capture after screen updates; if this is a\n * recapture while Lumen UI is already open, the provider also conceals\n * `[data-lumen-root]` / `data-lumen-capture-ignore` before the request,\n * 2. posts a `lumen:capture-request` message to the native host,\n * 3. waits for the host to send back a PNG/JPEG data URL,\n * 4. restores the sheet and resolves with a native `CaptureResult`.\n *\n * On the native side, respond by injecting JS that calls\n * `window.__lumenNativeCapture.resolve(id, dataUrl)` (or post a\n * `{ type: \"lumen:capture-response\", id, dataUrl }` message back into the\n * WebView). See the package README for a full Expo example.\n */\nexport interface NativeCaptureProviderOptions {\n /** Recorded in the submission metadata. Defaults to platform autodetection. */\n platform?: Extract<CapturePlatform, \"ios\" | \"android\">;\n /** Give up after this long if the native host never answers. Default 8000ms. */\n timeoutMs?: number;\n /**\n * How to deliver the capture request to the native host. Defaults to\n * `window.ReactNativeWebView.postMessage(JSON.stringify(request))`, which is\n * what react-native-webview exposes. Override for Capacitor / custom shells.\n */\n send?: (request: NativeCaptureRequest) => void;\n /**\n * CSS selector for elements to hide while the native shot is taken. Defaults\n * to the Lumen root and sheet markers so the feedback UI stays out of the\n * screenshot during recapture/legacy submit-time captures.\n * Pass `null` to disable hiding entirely.\n */\n concealSelector?: string | null;\n /**\n * Extra delay after concealment before `send` fires. Native iOS hosts should\n * still snapshot with `afterScreenUpdates: true`; this delay gives the\n * WebView compositor a chance to flush hidden DOM state first.\n */\n captureSettleMs?: number;\n /**\n * Before requesting the native shot, wait up to this many ms for in-flight\n * CSS transitions/animations (e.g. a host bottom sheet finishing its open\n * animation) to settle, so the screenshot reflects the resting frame.\n * Looping animations are ignored. Default 400ms; set to 0 to disable.\n */\n awaitAnimationsMs?: number;\n}\n\nexport interface NativeCaptureRequest {\n type: \"lumen:capture-request\";\n /** Correlates the response with this request. */\n id: string;\n /**\n * Native hosts should honor this by capturing after pending screen updates\n * have committed, e.g. `drawHierarchy(..., afterScreenUpdates: true)` on iOS.\n */\n afterScreenUpdates: true;\n}\n\n/**\n * Message a native host posts into the WebView to open the Lumen sheet when\n * it detects a device shake. Deliver it the same way as any other bridge\n * message — `window.ReactNativeWebView` round-trips it back via the WebView's\n * `onMessage`, or inject `window.dispatchEvent(new MessageEvent(\"message\", …))`.\n * The React SDK listens for it when shake-to-open is enabled.\n */\nexport const LUMEN_SHAKE_MESSAGE = \"lumen:shake\";\n\nexport interface ShakeMessage {\n type: typeof LUMEN_SHAKE_MESSAGE;\n}\n\nexport interface NativeCaptureResponse {\n type: \"lumen:capture-response\";\n id: string;\n /** A `data:image/png;base64,…` (or jpeg/webp) URL of the captured screen. */\n dataUrl?: string;\n /** Set instead of `dataUrl` when the native capture failed. */\n error?: string;\n /** Optional device pixel ratio so metadata matches the native render. */\n pixelRatio?: number;\n}\n\ninterface PendingCapture {\n resolve: (response: NativeCaptureResponse) => void;\n reject: (error: Error) => void;\n}\n\ninterface NativeCaptureRegistry {\n pending: Map<string, PendingCapture>;\n /** Called by the native host (via injected JS) to deliver a result. */\n resolve: (id: string, dataUrl: string, pixelRatio?: number) => void;\n /** Called by the native host to report a capture failure. */\n reject: (id: string, error?: string) => void;\n}\n\ndeclare global {\n interface Window {\n __lumenNativeCapture?: NativeCaptureRegistry;\n ReactNativeWebView?: { postMessage: (msg: string) => void };\n }\n}\n\nconst DEFAULT_TIMEOUT_MS = 8000;\nconst DEFAULT_CAPTURE_SETTLE_MS = 50;\nconst DEFAULT_AWAIT_ANIMATIONS_MS = 400;\n\n/**\n * Build a native-screenshot provider for a WebView host. Safe to call at\n * module scope; the registry + message listener install lazily on first use.\n */\nexport function createNativeCaptureProvider(\n options: NativeCaptureProviderOptions = {},\n): ScreenshotCaptureProvider {\n return async function nativeCaptureProvider(): Promise<CaptureResult> {\n if (typeof window === \"undefined\") {\n throw new LumenError(\n \"Native capture bridge requires a WebView/browser window.\",\n \"INVALID_ENV\",\n );\n }\n\n const registry = ensureRegistry();\n const send = options.send ?? defaultSend;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const captureSettleMs =\n options.captureSettleMs ?? DEFAULT_CAPTURE_SETTLE_MS;\n const awaitAnimationsMs =\n options.awaitAnimationsMs ?? DEFAULT_AWAIT_ANIMATIONS_MS;\n const id = newRequestId();\n\n const restore = concealLumenChrome(\n options.concealSelector === undefined\n ? DEFAULT_CONCEAL\n : options.concealSelector,\n );\n try {\n await settleAfterConceal(captureSettleMs, awaitAnimationsMs);\n\n const response = await new Promise<NativeCaptureResponse>(\n (resolve, reject) => {\n const timer = window.setTimeout(() => {\n registry.pending.delete(id);\n reject(\n new LumenError(\n \"Native screenshot timed out; the host did not respond.\",\n \"NATIVE_CAPTURE_TIMEOUT\",\n ),\n );\n }, timeoutMs);\n\n registry.pending.set(id, {\n resolve: (r) => {\n window.clearTimeout(timer);\n resolve(r);\n },\n reject: (e) => {\n window.clearTimeout(timer);\n reject(e);\n },\n });\n\n try {\n send({ type: \"lumen:capture-request\", id, afterScreenUpdates: true });\n } catch (e) {\n registry.pending.delete(id);\n window.clearTimeout(timer);\n reject(\n new LumenError(\n \"Could not reach the native host for screen capture.\",\n \"NATIVE_CAPTURE_UNAVAILABLE\",\n ),\n );\n void e;\n }\n },\n );\n\n if (response.error || !response.dataUrl) {\n throw new LumenError(\n response.error ?? \"Native screenshot returned no image.\",\n \"NATIVE_CAPTURE_FAILED\",\n );\n }\n\n const blob = dataUrlToBlob(response.dataUrl);\n const platform = options.platform ?? detectPlatform();\n const method: CaptureMethod =\n platform === \"android\" ? \"android-native\" : \"ios-native\";\n\n return {\n blob,\n method,\n platform,\n viewport: {\n width: Math.round(window.innerWidth),\n height: Math.round(window.innerHeight),\n },\n pixelRatio: response.pixelRatio ?? window.devicePixelRatio ?? 1,\n warnings: [],\n } satisfies CaptureResult;\n } finally {\n restore();\n }\n };\n}\n\n/** Default transport: react-native-webview's postMessage channel. */\nfunction defaultSend(request: NativeCaptureRequest): void {\n const rn = window.ReactNativeWebView;\n if (!rn?.postMessage) {\n throw new LumenError(\n \"window.ReactNativeWebView is unavailable; pass a custom `send`.\",\n \"NATIVE_CAPTURE_UNAVAILABLE\",\n );\n }\n rn.postMessage(JSON.stringify(request));\n}\n\nfunction ensureRegistry(): NativeCaptureRegistry {\n if (window.__lumenNativeCapture) return window.__lumenNativeCapture;\n\n const registry: NativeCaptureRegistry = {\n pending: new Map(),\n resolve(id, dataUrl, pixelRatio) {\n const entry = registry.pending.get(id);\n if (!entry) return;\n registry.pending.delete(id);\n entry.resolve({ type: \"lumen:capture-response\", id, dataUrl, pixelRatio });\n },\n reject(id, error) {\n const entry = registry.pending.get(id);\n if (!entry) return;\n registry.pending.delete(id);\n entry.resolve({ type: \"lumen:capture-response\", id, error });\n },\n };\n\n // Hosts that prefer postMessage (instead of injected JS) can post a\n // capture-response back into the WebView; accept it on window and document.\n const onMessage = (event: MessageEvent) => {\n const data = parseMessage(event.data);\n if (!data || data.type !== \"lumen:capture-response\") return;\n const entry = registry.pending.get(data.id);\n if (!entry) return;\n registry.pending.delete(data.id);\n entry.resolve(data);\n };\n window.addEventListener(\"message\", onMessage);\n document.addEventListener(\"message\", onMessage as EventListener);\n\n window.__lumenNativeCapture = registry;\n return registry;\n}\n\nfunction parseMessage(data: unknown): NativeCaptureResponse | null {\n if (data && typeof data === \"object\" && \"type\" in data) {\n return data as NativeCaptureResponse;\n }\n if (typeof data === \"string\") {\n try {\n const parsed = JSON.parse(data);\n if (parsed && typeof parsed === \"object\" && parsed.type) return parsed;\n } catch {\n // Not a Lumen message — ignore.\n }\n }\n return null;\n}\n\nasync function settleAfterConceal(\n captureSettleMs: number,\n awaitAnimationsMs: number,\n): Promise<void> {\n // Let any in-flight host transition (bottom sheet open/close) finish first so\n // the native shot reflects the settled frame, not a mid-animation one.\n await waitForAnimationsToSettle(awaitAnimationsMs);\n await nextAnimationFrame();\n if (captureSettleMs > 0) {\n await new Promise((resolve) => window.setTimeout(resolve, captureSettleMs));\n }\n}\n\nfunction nextAnimationFrame(): Promise<void> {\n return new Promise((resolve) => {\n requestAnimationFrame(() => resolve());\n });\n}\n\nfunction detectPlatform(): \"ios\" | \"android\" {\n const ua = navigator.userAgent || \"\";\n return /android/i.test(ua) ? \"android\" : \"ios\";\n}\n\nfunction newRequestId(): string {\n const rand =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : Math.random().toString(36).slice(2);\n return `lumen-cap-${rand}`;\n}\n\n/** Decode a data: URL into a Blob without relying on fetch() (some old\n * WebViews block fetch on data: URIs). */\nfunction dataUrlToBlob(dataUrl: string): Blob {\n const match = /^data:([^;,]*)(;base64)?,(.*)$/s.exec(dataUrl);\n if (!match) {\n throw new LumenError(\n \"Native host returned an invalid image data URL.\",\n \"NATIVE_CAPTURE_FAILED\",\n );\n }\n const mime = match[1] || \"image/png\";\n const isBase64 = Boolean(match[2]);\n const data = match[3] ?? \"\";\n\n if (!isBase64) {\n return new Blob([decodeURIComponent(data)], { type: mime });\n }\n\n const binary = atob(data);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return new Blob([bytes], { type: mime });\n}\n","/**\n * Soft-keyboard inset bridge.\n *\n * In an iOS WKWebView (`react-native-webview`) `window.visualViewport` does NOT\n * shrink when the keyboard opens, so the widget can't measure the keyboard from\n * inside the page. A native shell can instead push the keyboard height in here;\n * the React SDK's `useKeyboardInset` reads it (and the `--lumen-keyboard-inset`\n * CSS var) and lifts the trigger + modal input above the keyboard.\n *\n * Call from injected JS in your WebView host, e.g. on RN `Keyboard` events:\n * `window.dispatchEvent` is fired for you so the widget updates immediately.\n * `@lumen-stack/expo`'s `LumenWebView` wires this automatically.\n */\nexport const LUMEN_KEYBOARD_EVENT = \"lumen:keyboardchange\";\n\nexport const LUMEN_KEYBOARD_CSS_VAR = \"--lumen-keyboard-inset\";\n\ndeclare global {\n interface Window {\n __lumenKeyboardInset?: number;\n }\n}\n\n/**\n * Set the current soft-keyboard inset (CSS px from the bottom of the viewport)\n * and notify the widget. Pass 0 (or a negative/NaN value) when the keyboard\n * closes. Mirrors the value onto the `--lumen-keyboard-inset` CSS var on\n * `<html>` so CSS-only hosts can read it too.\n */\nexport function setLumenKeyboardInset(insetPx: number): void {\n if (typeof window === \"undefined\") return;\n const px =\n typeof insetPx === \"number\" && Number.isFinite(insetPx) && insetPx > 0\n ? Math.round(insetPx)\n : 0;\n window.__lumenKeyboardInset = px;\n if (typeof document !== \"undefined\") {\n document.documentElement.style.setProperty(\n LUMEN_KEYBOARD_CSS_VAR,\n `${px}px`,\n );\n }\n window.dispatchEvent(new Event(LUMEN_KEYBOARD_EVENT));\n}\n\n/**\n * Read the injected keyboard inset (window global first, then the CSS var).\n * Returns `null` when no host has provided one, so callers can fall back to\n * `visualViewport`. Never negative.\n */\nexport function readLumenKeyboardInset(): number | null {\n if (typeof window === \"undefined\") return null;\n const g = window.__lumenKeyboardInset;\n if (typeof g === \"number\" && Number.isFinite(g) && g >= 0) return g;\n if (typeof document !== \"undefined\" && typeof getComputedStyle === \"function\") {\n const raw = getComputedStyle(document.documentElement)\n .getPropertyValue(LUMEN_KEYBOARD_CSS_VAR)\n .trim();\n if (raw) {\n const n = parseFloat(raw);\n if (Number.isFinite(n) && n >= 0) return n;\n }\n }\n return null;\n}\n","import { LumenError } from \"./errors\";\n\nexport interface AudioRecording {\n blob: Blob;\n durationMs: number;\n mimeType: string;\n}\n\nexport interface RecorderHandle {\n /**\n * Stop recording and resolve with the recorded blob. Safe to call after\n * the max-duration auto-stop already fired — the result promise is shared,\n * so the take is delivered instead of lost.\n */\n stop: () => Promise<AudioRecording>;\n /** Cancel without producing a blob; releases the mic immediately. */\n cancel: () => void;\n /** Stream object (use to render a live waveform in Phase 2). */\n stream: MediaStream;\n}\n\n/**\n * Start a MediaRecorder. Caller is responsible for stopping/canceling.\n * Auto-stops after `maxSeconds` seconds to avoid runaway recordings.\n *\n * Single-funnel design (mirrors record-video.ts): every termination path —\n * consumer `stop()`, the auto-stop timeout, `cancel()` — lands in the one\n * `stop`-event handler registered at creation. That handler settles the\n * shared result promise and releases the mic tracks, so a consumer `stop()`\n * racing the auto-stop can never lose the recording, and the auto-stop can\n * never leave the mic live.\n */\nexport async function recordAudio(\n maxSeconds = 60,\n): Promise<RecorderHandle> {\n if (typeof window === \"undefined\" || !navigator.mediaDevices) {\n throw new LumenError(\n \"Audio recording requires a browser with MediaDevices.\",\n \"INVALID_ENV\",\n );\n }\n\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch {\n throw new LumenError(\n \"Microphone access denied or unavailable.\",\n \"MIC_DENIED\",\n );\n }\n\n // Pick the first MIME type supported by the browser; webm/opus on\n // Chromium, mp4/aac on Safari, ogg on Firefox.\n const candidates = [\n \"audio/webm;codecs=opus\",\n \"audio/webm\",\n \"audio/mp4\",\n \"audio/ogg;codecs=opus\",\n ];\n const mimeType =\n candidates.find((m) => MediaRecorder.isTypeSupported(m)) ?? \"\";\n\n const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);\n const chunks: Blob[] = [];\n const start = performance.now();\n let timeoutId: number | null = null;\n let cancelled = false;\n let settled = false;\n\n let resolveResult!: (recording: AudioRecording) => void;\n let rejectResult!: (reason: unknown) => void;\n const result = new Promise<AudioRecording>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n // A cancel() without a matching stop() leaves the rejection unobserved.\n result.catch(() => {});\n\n recorder.addEventListener(\"dataavailable\", (e) => {\n if (e.data && e.data.size > 0) chunks.push(e.data);\n });\n\n recorder.addEventListener(\"stop\", () => {\n if (timeoutId !== null) window.clearTimeout(timeoutId);\n timeoutId = null;\n for (const track of stream.getTracks()) track.stop();\n if (settled) return;\n settled = true;\n if (cancelled) {\n rejectResult(\n new LumenError(\"Recording cancelled.\", \"RECORDER_STOPPED\"),\n );\n return;\n }\n const durationMs = performance.now() - start;\n const finalType = recorder.mimeType || mimeType || \"audio/webm\";\n const blob = new Blob(chunks, { type: finalType });\n resolveResult({ blob, durationMs, mimeType: finalType });\n });\n\n recorder.start();\n timeoutId = window.setTimeout(() => {\n if (recorder.state !== \"inactive\") recorder.stop();\n }, maxSeconds * 1000);\n\n function requestStop() {\n if (recorder.state === \"inactive\") return;\n try {\n recorder.stop();\n } catch {\n /* ignore — stop on a closing recorder can throw on some engines */\n }\n }\n\n return {\n stream,\n cancel() {\n cancelled = true;\n requestStop();\n // If the recorder already stopped (auto-stop fired), the stop handler\n // has run; make doubly sure nothing keeps the mic indicator alive.\n if (timeoutId !== null) window.clearTimeout(timeoutId);\n timeoutId = null;\n for (const track of stream.getTracks()) track.stop();\n },\n stop(): Promise<AudioRecording> {\n requestStop();\n return result;\n },\n };\n}\n","import { LumenError } from \"./errors\";\n\n/**\n * A finished screen recording. `mimeType` is `video/webm` (or `video/mp4`)\n * from the browser `getDisplayMedia` path, and whatever a custom/native host\n * produces — e.g. `video/mp4` from an iOS ReplayKit host.\n */\nexport interface LumenRecordingResult {\n blob: Blob;\n durationMs: number;\n mimeType: string;\n}\n\n/** Back-compat alias for the original name; identical shape. */\nexport type VideoRecording = LumenRecordingResult;\n\n/**\n * A live recording the widget can stop/cancel and await. Both the built-in\n * browser recorder ({@link VideoRecorderHandle}) and custom {@link\n * LumenRecordProvider}s return this shape. The widget relies ONLY on\n * `result`/`stop`/`cancel`; `stream` is optional (native hosts omit it).\n */\nexport interface LumenRecordingSession {\n /** Resolves with the finished clip; rejects with `LumenError(\"RECORDER_STOPPED\")` when cancelled. */\n result: Promise<LumenRecordingResult>;\n /** Ask the recorder to stop; the clip then arrives via `result`. */\n stop(): void;\n /** Abort and discard the recording. */\n cancel(): void;\n /** Only present for browser getDisplayMedia recordings. Custom providers may omit it. */\n stream?: MediaStream;\n}\n\n/**\n * A factory the host wires into `<LumenProvider record={{ provider }}>` to\n * delegate screen recording to a native/custom recorder (e.g. an iOS WebView\n * host using ReplayKit over its postMessage bridge), mirroring the\n * `capture.provider` extension point for screenshots. Called from the user's\n * tap on the Record button, after the Lumen sheet has been closed.\n */\nexport type LumenRecordProvider = (options: {\n maxDurationSeconds: number;\n}) => Promise<LumenRecordingSession> | LumenRecordingSession;\n\nexport interface VideoRecorderHandle {\n /**\n * Request a stop (idempotent). The recording is delivered via {@link result},\n * NOT a return value — so whoever stops it (your button, the browser's \"Stop\n * sharing\", or the max-duration cap) all funnel through the same place.\n */\n stop: () => void;\n /** Cancel without producing a usable recording; releases the capture. */\n cancel: () => void;\n /** The screen-capture stream (use to render a live preview / poster). */\n stream: MediaStream;\n /**\n * Resolves exactly once when recording stops for ANY reason — your `stop()`,\n * the browser's own \"Stop sharing\" control, or the `maxSeconds` cap. Rejects\n * only if cancelled. Await this to get the blob.\n */\n result: Promise<LumenRecordingResult>;\n}\n\n/**\n * Record the screen via the browser Screen Capture API + MediaRecorder.\n * The user picks a tab / window / screen in the browser's native picker; if\n * they cancel the picker this rejects with `SCREEN_DENIED`.\n *\n * The recording is delivered through {@link VideoRecorderHandle.result}, which\n * resolves no matter how the capture ends — a single funnel for the three stop\n * paths (manual `stop()`, the browser's \"Stop sharing\" bar, and the\n * `maxSeconds` auto-stop). This is the key correctness property: earlier the\n * blob was only delivered if the consumer happened to win the race to call\n * stop(), so a browser-initiated stop or the timeout could drop the take.\n */\nexport async function recordVideo(\n maxSeconds = 60,\n): Promise<VideoRecorderHandle> {\n if (\n typeof window === \"undefined\" ||\n !navigator.mediaDevices ||\n typeof navigator.mediaDevices.getDisplayMedia !== \"function\"\n ) {\n throw new LumenError(\n \"Screen recording requires a browser with getDisplayMedia.\",\n \"INVALID_ENV\",\n );\n }\n\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getDisplayMedia({\n video: true,\n // Capture system/tab audio when the user opts in via the picker.\n audio: true,\n });\n } catch {\n throw new LumenError(\n \"Screen capture was denied or cancelled.\",\n \"SCREEN_DENIED\",\n );\n }\n\n // VP9/VP8 webm on Chromium; mp4 on Safari.\n const candidates = [\n \"video/webm;codecs=vp9,opus\",\n \"video/webm;codecs=vp8,opus\",\n \"video/webm\",\n \"video/mp4\",\n ];\n const mimeType =\n candidates.find((m) => MediaRecorder.isTypeSupported(m)) ?? \"\";\n\n const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);\n const chunks: Blob[] = [];\n const start = performance.now();\n let timeoutId: number | null = null;\n let settled = false;\n let cancelled = false;\n\n let resolveResult!: (rec: VideoRecording) => void;\n let rejectResult!: (err: Error) => void;\n const result = new Promise<VideoRecording>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n // Avoid an unhandled-rejection warning if a caller cancels without awaiting.\n result.catch(() => undefined);\n\n function release() {\n if (timeoutId !== null) {\n window.clearTimeout(timeoutId);\n timeoutId = null;\n }\n for (const track of stream.getTracks()) track.stop();\n }\n\n recorder.addEventListener(\"dataavailable\", (e) => {\n if (e.data && e.data.size > 0) chunks.push(e.data);\n });\n\n // Single funnel: whatever stops the recorder ends up here exactly once.\n recorder.addEventListener(\"stop\", () => {\n if (settled) return;\n settled = true;\n release();\n if (cancelled) {\n rejectResult(new LumenError(\"Recording cancelled.\", \"RECORDER_STOPPED\"));\n return;\n }\n const finalType = recorder.mimeType || mimeType || \"video/webm\";\n resolveResult({\n blob: new Blob(chunks, { type: finalType }),\n durationMs: performance.now() - start,\n mimeType: finalType,\n });\n });\n\n function requestStop() {\n if (recorder.state !== \"inactive\") recorder.stop();\n }\n\n recorder.start();\n timeoutId = window.setTimeout(requestStop, maxSeconds * 1000);\n\n // The user can end the share from the browser's own UI — funnel that into\n // the same stop path so the in-flight recording still resolves.\n stream.getVideoTracks()[0]?.addEventListener(\"ended\", requestStop);\n\n return {\n stream,\n result,\n stop: requestStop,\n cancel() {\n cancelled = true;\n if (recorder.state !== \"inactive\") {\n recorder.stop();\n } else if (!settled) {\n settled = true;\n release();\n rejectResult(\n new LumenError(\"Recording cancelled.\", \"RECORDER_STOPPED\"),\n );\n }\n },\n };\n}\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type {\n LumenClient,\n CaptureResult,\n ScreenshotCaptureOptions,\n LumenUser,\n SubmitOptions,\n SubmitPayload,\n SubmitResult,\n} from \"@lumen-stack/core\";\n\n/**\n * Live screen-recording state, surfaced to the floating HUD. The browser path\n * only ever produces `recording`; the `starting`/`processing` phases are used\n * by the custom/native `record.provider` path (consent window before the clip\n * starts, encode/transfer window after Stop).\n */\nexport type VideoRecordingState =\n | { phase: \"starting\" }\n | {\n phase: \"recording\";\n /** Null for native hosts that record without exposing a MediaStream. */\n stream: MediaStream | null;\n /** Epoch ms when recording began (the HUD derives elapsed time from this). */\n startedAt: number;\n maxSeconds: number;\n }\n | { phase: \"processing\" };\n\n/**\n * Live \"Capture exact screen\" (`getDisplayMedia`) state, surfaced to the\n * floating capture HUD while the sheet is hidden. `live` = stream is open and\n * the user is arranging the page; `grabbing` = the frame is being drawn.\n */\nexport type ScreenCaptureState = { phase: \"live\" } | { phase: \"grabbing\" };\n\n/** A finished clip handed to the modal on reopen so it can attach + preview. */\nexport interface PendingVideo {\n blob: Blob;\n durationMs: number;\n poster: Blob | null;\n /**\n * Provider clips arrive without a stream-derived poster; when true and\n * `poster` is null the modal derives a first-frame poster from the blob.\n * Never set on the browser path, so that path's behavior is unchanged.\n */\n deriveBlobPoster?: boolean;\n}\n\nexport interface LumenContextValue {\n client: LumenClient;\n user: LumenUser | undefined;\n\n // ── Video recording session ──────────────────────────────────────────\n // Lifted out of the modal so recording survives the sheet being closed.\n /** Start a screen recording from a user gesture (the Record button).\n * Closes the sheet; a floating HUD takes over until the user stops.\n * Rejects if the picker is denied so the modal can surface it. */\n startVideoSession: () => Promise<void>;\n /** Stop the active recording → reopens the sheet with the clip attached. */\n stopVideoSession: () => void;\n /** Abort the active recording without keeping a clip. */\n cancelVideoSession: () => void;\n /** Non-null while recording (sheet closed). Drives the floating HUD. */\n recording: VideoRecordingState | null;\n /** Consumed once by the modal on (re)open to seed a just-finished clip. */\n consumePendingVideo: () => PendingVideo | null;\n /**\n * Whether the Record tab should be offered, resolving `record.provider` +\n * `record.isAvailable` (probed on open) against browser `getDisplayMedia`.\n */\n canRecordScreen: boolean;\n /**\n * Consume-once error from a failed `record.provider` start. When present on\n * (re)open the modal lands on the Record step and shows it inline.\n */\n consumeRecordStartError: () => string | null;\n\n // ── \"Capture exact screen\" session (getDisplayMedia) ──────────────────\n // Lifted out of the modal so the live stream survives the sheet being\n // hidden, letting the user arrange the page before the frame is grabbed.\n /** Start an exact-screen capture from a user gesture (the button). Opens the\n * surface picker; on success hides the sheet and shows the floating bar. */\n startScreenCaptureSession: () => Promise<void>;\n /** Grab the current frame → reopens the sheet with the screenshot attached. */\n grabScreenCaptureFrame: () => void;\n /** Abort the session without capturing → reopens the sheet unchanged. */\n cancelScreenCaptureSession: () => void;\n /** Non-null while an exact-screen session is live. Drives the capture HUD. */\n screenCapture: ScreenCaptureState | null;\n /** Consumed once by the modal on reopen to seed a just-captured screenshot. */\n consumePendingScreenshot: () => CaptureResult | null;\n\n // v2 surface\n open: (event?: Event) => void;\n close: () => void;\n isOpen: boolean;\n /** Pass-through to client.submit — for headless hosts that build their own payload. */\n submit: (\n payload: SubmitPayload,\n options?: SubmitOptions,\n ) => Promise<SubmitResult>;\n /** Best-effort: true when running inside a native shell (RN WebView, Capacitor, …). */\n isNativeShell: boolean;\n /** Capture options from <LumenProvider>. */\n capture: ScreenshotCaptureOptions | undefined;\n /** Screenshot captured before the wizard mounted, when available. */\n initialCapture: CaptureResult | null;\n /** Error from the pre-open capture; the modal falls back to manual upload. */\n initialCaptureError: Error | null;\n /** True while the trigger has been activated and the pre-open capture is running. */\n isOpening: boolean;\n /** Whether Lumen stops its own pointer/click events from leaking into host overlays. */\n isolateEvents: boolean;\n /** Soft-keyboard inset override (px) from the host, when provided. */\n keyboardInset: number | undefined;\n\n // Back-compat aliases (kept; do not remove).\n openCapture: (event?: Event) => void;\n closeCapture: () => void;\n isSubmitting: boolean;\n error: Error | null;\n}\n\nexport const LumenContext = createContext<LumenContextValue | null>(null);\n\nexport function useLumen(): LumenContextValue {\n const ctx = useContext(LumenContext);\n if (!ctx) {\n throw new Error(\"useLumen() must be used inside <LumenProvider>.\");\n }\n return ctx;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\n/** Default visual-viewport shrink (px) that counts as the keyboard being up. */\nexport const KEYBOARD_THRESHOLD = 100;\n\nexport interface KeyboardStateInput {\n /** Whether an editable element currently holds focus. */\n editableFocused: boolean;\n /** Last \"no keyboard\" visual-viewport height (the calibrated baseline). */\n baseline: number;\n /** Current `visualViewport.height`. */\n vvHeight: number;\n /** Shrink (px) past which the keyboard is considered open. */\n threshold?: number;\n}\n\nexport interface KeyboardState {\n /** True when the keyboard is judged to be covering the viewport. */\n open: boolean;\n /** Baseline to carry into the next measurement. */\n baseline: number;\n}\n\n/**\n * Pure decision for keyboard visibility — framework-free so it can be unit\n * tested without a DOM (mirrors `record-availability.ts`).\n *\n * The keyboard is only reported open when an editable element is focused: iOS\n * never shows the soft keyboard otherwise, so a bare viewport shrink (Chrome\n * iOS collapsing its top/bottom toolbars on scroll) must NOT hide the trigger.\n * While nothing is focused the baseline tracks the current height, which\n * auto-calibrates per browser and survives orientation changes; while an\n * editable element is focused the baseline is frozen so `baseline - vvHeight`\n * measures the keyboard alone.\n */\nexport function nextKeyboardState({\n editableFocused,\n baseline,\n vvHeight,\n threshold = KEYBOARD_THRESHOLD,\n}: KeyboardStateInput): KeyboardState {\n if (!editableFocused) {\n return { open: false, baseline: vvHeight };\n }\n return { open: baseline - vvHeight > threshold, baseline };\n}\n\n/** True when an editable element holds focus, piercing open shadow roots. */\nexport function isEditableElementFocused(): boolean {\n if (typeof document === \"undefined\") return false;\n let el: Element | null = document.activeElement;\n while (el?.shadowRoot?.activeElement) {\n el = el.shadowRoot.activeElement;\n }\n if (!el) return false;\n const tag = el.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") return true;\n return (el as HTMLElement).isContentEditable === true;\n}\n\n/**\n * True when the on-screen keyboard is likely covering the viewport. Touch\n * devices only — desktop never returns true.\n */\nexport function useViewportKeyboard(enabled: boolean): boolean {\n const [open, setOpen] = useState(false);\n const baselineRef = useRef(0);\n\n useEffect(() => {\n if (!enabled) {\n setOpen(false);\n return;\n }\n if (typeof window === \"undefined\") return;\n const vv = window.visualViewport;\n if (!vv) return;\n if (\n typeof window.matchMedia !== \"function\" ||\n !window.matchMedia(\"(pointer: coarse)\").matches\n ) {\n return;\n }\n\n baselineRef.current = vv.height;\n\n let raf = 0;\n const check = () => {\n raf = 0;\n const result = nextKeyboardState({\n editableFocused: isEditableElementFocused(),\n baseline: baselineRef.current,\n vvHeight: vv.height,\n });\n baselineRef.current = result.baseline;\n setOpen(result.open);\n };\n const schedule = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(check);\n };\n\n schedule();\n vv.addEventListener(\"resize\", schedule);\n vv.addEventListener(\"scroll\", schedule);\n document.addEventListener(\"focusin\", schedule);\n document.addEventListener(\"focusout\", schedule);\n return () => {\n if (raf) window.cancelAnimationFrame(raf);\n vv.removeEventListener(\"resize\", schedule);\n vv.removeEventListener(\"scroll\", schedule);\n document.removeEventListener(\"focusin\", schedule);\n document.removeEventListener(\"focusout\", schedule);\n };\n }, [enabled]);\n\n return open;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { LUMEN_KEYBOARD_EVENT, readLumenKeyboardInset } from \"@lumen-stack/core\";\n\nimport {\n KEYBOARD_THRESHOLD,\n isEditableElementFocused,\n} from \"./useViewportKeyboard\";\n\nexport interface KeyboardInsetState {\n /** True when the soft keyboard is judged to be covering the viewport. */\n open: boolean;\n /** Keyboard height (CSS px) to lift UI by. 0 when closed/unknown. */\n inset: number;\n}\n\nconst CLOSED: KeyboardInsetState = { open: false, inset: 0 };\n\nexport interface KeyboardInsetDecisionInput {\n /** Whether an editable element holds focus (iOS only shows the keyboard then). */\n editable: boolean;\n /** Explicit `keyboardInset` prop override, if any. */\n override?: number;\n /** Injected inset (window global / CSS var), or null when absent. */\n injected: number | null;\n /** Last \"no keyboard\" visualViewport height (the calibrated baseline). */\n vvBaseline: number;\n /** Current visualViewport height, or null when unavailable. */\n vvHeight: number | null;\n /** Coarse pointer (touch) — gates the visualViewport fallback path. */\n coarse: boolean;\n}\n\n/**\n * Pure decision for keyboard height — framework-free so it can be unit tested\n * (mirrors `nextKeyboardState` / `record-availability.ts`). Priority:\n * 1. explicit prop override, 2. injected inset (WebView), 3. visualViewport.\n * The keyboard is only \"open\" while an editable element is focused.\n */\nexport function decideKeyboardInset(\n input: KeyboardInsetDecisionInput,\n): KeyboardInsetState {\n const explicit = input.override ?? input.injected;\n if (explicit != null) {\n const open = explicit > 1 && input.editable;\n return open ? { open, inset: Math.round(explicit) } : CLOSED;\n }\n // visualViewport fallback — touch web only (desktop has no soft keyboard, and\n // Chrome-iOS toolbar collapse must not count as the keyboard).\n if (input.vvHeight == null || !input.coarse || !input.editable) return CLOSED;\n const delta = input.vvBaseline - input.vvHeight;\n return delta > KEYBOARD_THRESHOLD\n ? { open: true, inset: Math.round(delta) }\n : CLOSED;\n}\n\n/**\n * Keyboard-awareness that works on web AND inside an iOS WKWebView.\n *\n * `window.visualViewport` does NOT shrink for the keyboard in a WKWebView, so a\n * viewport-only approach silently fails there. This hook merges three sources\n * (see {@link decideKeyboardInset}) and returns both whether the keyboard is\n * open and how tall it is, so callers can lift the trigger / modal input above\n * it rather than just hiding them.\n */\nexport function useKeyboardInset(\n enabled: boolean,\n override?: number,\n): KeyboardInsetState {\n const [state, setState] = useState<KeyboardInsetState>(CLOSED);\n const baselineRef = useRef(0);\n const overrideRef = useRef(override);\n overrideRef.current = override;\n\n useEffect(() => {\n if (!enabled) {\n setState(CLOSED);\n return;\n }\n if (typeof window === \"undefined\") return;\n\n const coarse =\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(pointer: coarse)\").matches;\n\n const recompute = () => {\n const editable = isEditableElementFocused();\n const override = overrideRef.current;\n const injected = readLumenKeyboardInset();\n const vv = window.visualViewport ?? null;\n // Recalibrate the visualViewport baseline while nothing is focused (and no\n // host inset is driving us) so it survives rotation / browser-chrome shifts.\n if (vv && override == null && injected == null && !editable) {\n baselineRef.current = vv.height;\n }\n setState(\n decideKeyboardInset({\n editable,\n override,\n injected,\n vvBaseline: baselineRef.current,\n vvHeight: vv ? vv.height : null,\n coarse,\n }),\n );\n };\n\n let raf = 0;\n const schedule = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(() => {\n raf = 0;\n recompute();\n });\n };\n\n const vv = window.visualViewport;\n if (vv) baselineRef.current = vv.height;\n\n schedule();\n vv?.addEventListener(\"resize\", schedule);\n vv?.addEventListener(\"scroll\", schedule);\n document.addEventListener(\"focusin\", schedule);\n document.addEventListener(\"focusout\", schedule);\n window.addEventListener(LUMEN_KEYBOARD_EVENT, schedule);\n return () => {\n if (raf) window.cancelAnimationFrame(raf);\n vv?.removeEventListener(\"resize\", schedule);\n vv?.removeEventListener(\"scroll\", schedule);\n document.removeEventListener(\"focusin\", schedule);\n document.removeEventListener(\"focusout\", schedule);\n window.removeEventListener(LUMEN_KEYBOARD_EVENT, schedule);\n };\n }, [enabled]);\n\n return state;\n}\n","\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport * as React from \"react\";\n\nexport type AnnotationTool = \"arrow\" | \"rect\" | \"freehand\" | \"comment\";\n\ninterface ArrowAnno {\n kind: \"arrow\";\n from: { x: number; y: number };\n to: { x: number; y: number };\n color: string;\n width: number;\n}\ninterface RectAnno {\n kind: \"rect\";\n from: { x: number; y: number };\n to: { x: number; y: number };\n color: string;\n width: number;\n}\ninterface FreehandAnno {\n kind: \"freehand\";\n points: Array<{ x: number; y: number }>;\n color: string;\n width: number;\n}\ntype Annotation = ArrowAnno | RectAnno | FreehandAnno;\n\n/** A text \"speech bubble\" callout placed directly on the screenshot.\n * Unlike the canvas shapes, comments live as inline-editable DOM nodes\n * (Figma-style: click to place, type in place, multiple allowed) and are\n * baked into the image only at flatten() time. Position is stored as a\n * fraction of the image so it maps to both the rendered box and the\n * full-resolution bitmap. */\ninterface CommentAnno {\n id: number;\n x: number;\n y: number;\n text: string;\n color: string;\n}\n\nconst HISTORY_LIMIT = 50;\nconst BUBBLE_FONT =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, ui-sans-serif, sans-serif';\n\nfunction clamp01(v: number, max = 1): number {\n return Math.max(0, Math.min(max, v));\n}\n\nexport interface AnnotationLayerHandle {\n flatten: () => Promise<Blob>;\n reset: () => void;\n undo: () => void;\n redo: () => void;\n hasAnnotations: () => boolean;\n}\n\nexport interface AnnotationLayerProps {\n screenshot: Blob;\n tool: AnnotationTool;\n /** Stroke color (CSS color). Default red-500. */\n color?: string;\n /** Stroke width in bitmap px. Default 4. */\n strokeWidth?: number;\n /** Called when the user starts/stops drawing — used by the modal to\n * lock its scrollable body during a stroke. */\n onDrawingChange?: (drawing: boolean) => void;\n /** Called whenever the undo/redo history changes (a mark is added, undone,\n * redone, or cleared) so the parent can enable/disable its toolbar buttons. */\n onHistoryChange?: (state: { canUndo: boolean; canRedo: boolean }) => void;\n}\n\n// forwardRef so the parent (CaptureModal) can call flatten() imperatively.\n// React 18 does NOT forward `ref` to plain function components — it must be\n// declared with forwardRef. React 19 deprecated forwardRef but still supports\n// it, so this is safe across both major versions.\nexport const AnnotationLayer = React.forwardRef<\n AnnotationLayerHandle,\n AnnotationLayerProps\n>(function AnnotationLayer({\n screenshot,\n tool,\n color = \"rgb(239, 68, 68)\",\n strokeWidth = 4,\n onDrawingChange,\n onHistoryChange,\n}, ref) {\n const baseCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const overlayCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [imageBitmap, setImageBitmap] = useState<ImageBitmap | null>(null);\n // iOS Safari can throw InvalidStateError from drawImage(ImageBitmap) even for\n // small images. If the base-canvas paint fails we fall back to rendering the\n // screenshot as a plain <img> (which WebKit handles reliably) so the widget\n // degrades gracefully instead of crashing into the error boundary.\n const [baseDrawFailed, setBaseDrawFailed] = useState(false);\n const [fallbackUrl, setFallbackUrl] = useState<string>(\"\");\n const [annotations, setAnnotations] = useState<Annotation[]>([]);\n const draftRef = useRef<Annotation | null>(null);\n const isDrawingRef = useRef(false);\n const lastSampleAtRef = useRef(0);\n const rafPendingRef = useRef(false);\n const [comments, setComments] = useState<CommentAnno[]>([]);\n const seqRef = useRef(0);\n // LIFO of what was added so undo() removes the most recent of either a\n // canvas shape or a comment bubble, in true insertion order.\n const undoStackRef = useRef<Array<\"anno\" | \"comment\">>([]);\n // Items popped by undo(), kept so redo() can re-add them in order. Each\n // entry carries the removed object itself — for comments that means the\n // latest typed text survives an undo→redo round-trip.\n const redoStackRef = useRef<\n Array<{ type: \"anno\"; item: Annotation } | { type: \"comment\"; item: CommentAnno }>\n >([]);\n // Mirror the live state so undo/redo can read the current arrays (and mutate\n // them synchronously) from event handlers without stale-closure or\n // Strict-Mode double-update hazards.\n const annotationsRef = useRef<Annotation[]>(annotations);\n annotationsRef.current = annotations;\n const commentsRef = useRef<CommentAnno[]>(comments);\n commentsRef.current = comments;\n // Set when a bubble is placed so the next render can focus it for typing.\n const pendingFocusRef = useRef<number | null>(null);\n\n // Notify the parent so it can enable/disable its Undo/Redo buttons. Held in a\n // ref so callers don't need it in their dependency arrays.\n const onHistoryChangeRef = useRef(onHistoryChange);\n onHistoryChangeRef.current = onHistoryChange;\n const fireHistory = useCallback(() => {\n onHistoryChangeRef.current?.({\n canUndo: undoStackRef.current.length > 0,\n canRedo: redoStackRef.current.length > 0,\n });\n }, []);\n\n const handleCommentChange = useCallback((id: number, text: string) => {\n setComments((cur) =>\n cur.map((c) => (c.id === id ? { ...c, text } : c)),\n );\n }, []);\n const handleCommentRemove = useCallback(\n (id: number) => {\n setComments((cur) => cur.filter((c) => c.id !== id));\n const i = undoStackRef.current.lastIndexOf(\"comment\");\n if (i >= 0) undoStackRef.current.splice(i, 1);\n // A manual delete is a fresh action — invalidate any redo trail.\n redoStackRef.current = [];\n fireHistory();\n },\n [fireHistory],\n );\n\n // Focus a freshly-placed bubble so the user can type immediately.\n useEffect(() => {\n const id = pendingFocusRef.current;\n if (id == null) return;\n pendingFocusRef.current = null;\n const el = containerRef.current?.querySelector<HTMLElement>(\n `[data-bubble-id=\"${id}\"] .lumen-bubble-text`,\n );\n el?.focus();\n }, [comments]);\n\n // A new screenshot (recapture, exact-screen swap, upload) is a clean slate:\n // drop any marks + history so undo/redo can't act on shapes drawn over a\n // previous shot. Runs harmlessly on first mount (everything already empty).\n useEffect(() => {\n setAnnotations([]);\n setComments([]);\n setBaseDrawFailed(false);\n undoStackRef.current = [];\n redoStackRef.current = [];\n fireHistory();\n }, [screenshot, fireHistory]);\n\n // Decode the screenshot once into a bitmap so we can redraw cheaply.\n // In React Strict Mode the effect runs twice on mount — we must close\n // the second-run bitmap and free both via .close() on unmount so we\n // don't leak GPU memory across repeated capture sessions.\n useEffect(() => {\n let cancelled = false;\n let decoded: ImageBitmap | null = null;\n (async () => {\n try {\n const bm = await createImageBitmap(screenshot);\n if (cancelled) {\n bm.close?.();\n return;\n }\n decoded = bm;\n setImageBitmap(bm);\n } catch {\n // Decoding failure leaves the layer in its loading state; the\n // surrounding modal will surface the error via toast on submit.\n }\n })();\n return () => {\n cancelled = true;\n decoded?.close?.();\n };\n }, [screenshot]);\n\n // Size + paint base canvas exactly once per bitmap. The overlay is always\n // sized to the bitmap so annotation coordinates map even if the base paint\n // fails. The drawImage is guarded: iOS Safari can throw InvalidStateError\n // here, and an unguarded throw in an effect tears the whole widget down via\n // the error boundary — instead we flip to the <img> fallback below.\n useEffect(() => {\n if (!imageBitmap) return;\n const base = baseCanvasRef.current;\n const overlay = overlayCanvasRef.current;\n if (!base || !overlay) return;\n overlay.width = imageBitmap.width;\n overlay.height = imageBitmap.height;\n try {\n base.width = imageBitmap.width;\n base.height = imageBitmap.height;\n const ctx = base.getContext(\"2d\");\n if (!ctx) return;\n ctx.imageSmoothingEnabled = false;\n ctx.drawImage(imageBitmap, 0, 0);\n setBaseDrawFailed(false);\n } catch {\n // WebKit/iOS drawImage failure — show the screenshot as an <img> instead.\n setBaseDrawFailed(true);\n }\n }, [imageBitmap]);\n\n // Object URL for the <img> fallback, created only when the canvas paint\n // failed. Revoked on cleanup so we never leak the blob.\n useEffect(() => {\n if (!baseDrawFailed) {\n setFallbackUrl(\"\");\n return;\n }\n const url = URL.createObjectURL(screenshot);\n setFallbackUrl(url);\n return () => {\n URL.revokeObjectURL(url);\n };\n }, [baseDrawFailed, screenshot]);\n\n // Repaint the OVERLAY only when annotations change. Base canvas is\n // never touched after the initial draw.\n useEffect(() => {\n const overlay = overlayCanvasRef.current;\n if (!overlay) return;\n // Defensive: a failed 2d context op must not tear down the widget.\n try {\n redraw(overlay, annotations, draftRef.current);\n } catch {\n // ignore — overlay just stays as-is\n }\n }, [annotations]);\n\n useImperativeHandle(\n ref,\n (): AnnotationLayerHandle => ({\n hasAnnotations: () =>\n annotations.length > 0 ||\n comments.some((c) => c.text.trim().length > 0),\n reset: () => {\n setAnnotations([]);\n setComments([]);\n annotationsRef.current = [];\n commentsRef.current = [];\n undoStackRef.current = [];\n redoStackRef.current = [];\n fireHistory();\n },\n undo: () => {\n const last = undoStackRef.current[undoStackRef.current.length - 1];\n if (!last) return;\n if (last === \"comment\") {\n const cur = commentsRef.current;\n const removed = cur[cur.length - 1];\n if (!removed) return;\n const next = cur.slice(0, -1);\n commentsRef.current = next;\n redoStackRef.current.push({ type: \"comment\", item: removed });\n setComments(next);\n } else {\n const cur = annotationsRef.current;\n const removed = cur[cur.length - 1];\n if (!removed) return;\n const next = cur.slice(0, -1);\n annotationsRef.current = next;\n redoStackRef.current.push({ type: \"anno\", item: removed });\n setAnnotations(next);\n }\n undoStackRef.current.pop();\n fireHistory();\n },\n redo: () => {\n const entry = redoStackRef.current[redoStackRef.current.length - 1];\n if (!entry) return;\n if (entry.type === \"comment\") {\n const next = [...commentsRef.current, entry.item];\n commentsRef.current = next;\n setComments(next);\n } else {\n const next = [...annotationsRef.current, entry.item];\n annotationsRef.current = next;\n setAnnotations(next);\n }\n undoStackRef.current.push(entry.type);\n redoStackRef.current.pop();\n fireHistory();\n },\n async flatten() {\n // Mid-stroke at submit time: bake the live draft so the user\n // doesn't lose the annotation they were drawing when they clicked\n // Send.\n const draft = draftRef.current;\n const all = draft ? [...annotations, draft] : annotations;\n // Only bake bubbles the user actually typed into.\n const liveComments = comments.filter((c) => c.text.trim().length > 0);\n // No marks at all → no re-encode (a 2MB PNG through canvas.toBlob\n // costs 100-300ms on a phone for zero benefit). CRITICAL: this gate\n // MUST consider comments too — comments live in a separate array, so\n // a strokes-empty check alone would silently drop every bubble from\n // the submitted image.\n if (all.length === 0 && liveComments.length === 0) return screenshot;\n // No usable bitmap (decode failed) or the base paint already failed on\n // this device → can't composite; submit the original screenshot.\n if (!imageBitmap || baseDrawFailed) return screenshot;\n try {\n const out = document.createElement(\"canvas\");\n out.width = imageBitmap.width;\n out.height = imageBitmap.height;\n const ctx = out.getContext(\"2d\");\n if (!ctx) return screenshot;\n ctx.imageSmoothingEnabled = false;\n ctx.drawImage(imageBitmap, 0, 0);\n for (const anno of all) drawAnno(ctx, anno);\n // Bubbles bake at bitmap resolution; scale the on-screen UI font by\n // the bitmap/rendered ratio so baked text matches what the user saw\n // instead of rendering tiny on a hi-dpi screenshot.\n const renderedWidth =\n baseCanvasRef.current?.clientWidth || imageBitmap.width;\n const bubbleScale = imageBitmap.width / Math.max(renderedWidth, 1);\n for (const c of liveComments) {\n drawBubble(ctx, c, imageBitmap.width, imageBitmap.height, bubbleScale);\n }\n // JPEG q=0.85: ~4-10× smaller than PNG for screenshot content,\n // which dominates submit time on slow uplinks. Annotations are\n // simple shapes that survive JPEG without visible artifacts.\n return await new Promise<Blob>((resolve) => {\n out.toBlob(\n (blob) => {\n resolve(blob ?? screenshot);\n },\n \"image/jpeg\",\n 0.85,\n );\n });\n } catch {\n // Compositing failed (e.g. iOS Safari drawImage) — never block\n // submit; fall back to the original screenshot blob.\n return screenshot;\n }\n },\n }),\n [annotations, comments, imageBitmap, screenshot, baseDrawFailed, fireHistory],\n );\n\n function clientToCanvas(\n e: React.PointerEvent<HTMLCanvasElement>,\n ): { x: number; y: number } {\n const c = overlayCanvasRef.current;\n if (!c) return { x: 0, y: 0 };\n const rect = c.getBoundingClientRect();\n const sx = c.width / Math.max(rect.width, 1);\n const sy = c.height / Math.max(rect.height, 1);\n return {\n x: (e.clientX - rect.left) * sx,\n y: (e.clientY - rect.top) * sy,\n };\n }\n\n function scheduleDraftPaint() {\n if (rafPendingRef.current) return;\n rafPendingRef.current = true;\n requestAnimationFrame(() => {\n rafPendingRef.current = false;\n const overlay = overlayCanvasRef.current;\n if (!overlay) return;\n // Read the LIVE committed set, not the render closure: a rAF scheduled\n // during the last pointer-move can fire after pointer-up has committed the\n // stroke, and a stale `annotations` would repaint without it — erasing the\n // just-finished stroke until the next interaction.\n redraw(overlay, annotationsRef.current, draftRef.current);\n });\n }\n\n function onPointerDown(e: React.PointerEvent<HTMLCanvasElement>) {\n if (e.button !== undefined && e.button !== 0) return;\n // Comment tool: place an inline-editable bubble at the tap and bail —\n // no stroke. Clamp so the bubble box stays inside the frame.\n if (tool === \"comment\") {\n const c = overlayCanvasRef.current;\n if (!c) return;\n const rect = c.getBoundingClientRect();\n const fx = clamp01((e.clientX - rect.left) / Math.max(rect.width, 1), 0.72);\n const fy = clamp01((e.clientY - rect.top) / Math.max(rect.height, 1), 0.8);\n const id = ++seqRef.current;\n setComments((cur) => [...cur, { id, x: fx, y: fy, text: \"\", color }]);\n undoStackRef.current.push(\"comment\");\n // A new mark invalidates the redo trail.\n redoStackRef.current = [];\n pendingFocusRef.current = id;\n fireHistory();\n return;\n }\n try {\n e.currentTarget.setPointerCapture(e.pointerId);\n } catch {\n // iOS Safari can throw NotSupportedError if the pointer is already\n // captured by an ancestor (e.g. the sheet grabber's drag handler).\n // Swallow — capture is a nice-to-have for off-canvas tracking; the\n // stroke still works without it.\n }\n isDrawingRef.current = true;\n onDrawingChange?.(true);\n const p = clientToCanvas(e);\n if (tool === \"arrow\") {\n draftRef.current = { kind: \"arrow\", from: p, to: p, color, width: strokeWidth };\n } else if (tool === \"rect\") {\n draftRef.current = { kind: \"rect\", from: p, to: p, color, width: strokeWidth };\n } else {\n draftRef.current = {\n kind: \"freehand\",\n points: [p],\n color,\n width: strokeWidth,\n };\n }\n lastSampleAtRef.current = performance.now();\n scheduleDraftPaint();\n }\n\n function onPointerMove(e: React.PointerEvent<HTMLCanvasElement>) {\n if (!isDrawingRef.current || !draftRef.current) return;\n const p = clientToCanvas(e);\n const draft = draftRef.current;\n if (draft.kind === \"arrow\" || draft.kind === \"rect\") {\n draft.to = p;\n } else {\n const last = draft.points[draft.points.length - 1];\n const dist2 = last\n ? (last.x - p.x) ** 2 + (last.y - p.y) ** 2\n : Infinity;\n const now = performance.now();\n const elapsed = now - lastSampleAtRef.current;\n // Sample if we've moved ≥ 4 bitmap-px OR ≥ 16ms passed (handles\n // very slow strokes where a single point would otherwise stall).\n if (dist2 > 16 || elapsed > 16) {\n draft.points.push(p);\n lastSampleAtRef.current = now;\n }\n }\n scheduleDraftPaint();\n }\n\n function onPointerUp() {\n if (!isDrawingRef.current) return;\n isDrawingRef.current = false;\n onDrawingChange?.(false);\n const draft = draftRef.current;\n draftRef.current = null;\n if (!draft) return;\n if (draft.kind === \"arrow\" || draft.kind === \"rect\") {\n const dx = draft.to.x - draft.from.x;\n const dy = draft.to.y - draft.from.y;\n if (dx * dx + dy * dy < 16) {\n // Tap — discard. Force a clean overlay repaint so the empty\n // draft doesn't linger.\n const overlay = overlayCanvasRef.current;\n if (overlay) redraw(overlay, annotationsRef.current, null);\n return;\n }\n } else if (draft.points.length < 2) {\n const overlay = overlayCanvasRef.current;\n if (overlay) redraw(overlay, annotationsRef.current, null);\n return;\n }\n setAnnotations((cur) => [...cur, draft].slice(-HISTORY_LIMIT));\n undoStackRef.current.push(\"anno\");\n // A new stroke invalidates the redo trail.\n redoStackRef.current = [];\n fireHistory();\n }\n\n return (\n <div\n ref={containerRef}\n className=\"lumen-annotate-frame\"\n data-lumen-tool={tool}\n >\n <canvas ref={baseCanvasRef} />\n {baseDrawFailed && fallbackUrl ? (\n // iOS Safari couldn't paint the bitmap onto the canvas; show the\n // screenshot as a plain <img> so it's never blank. The overlay canvas\n // (rendered after this) still sits on top and takes annotation input.\n <img\n src={fallbackUrl}\n alt=\"\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n objectFit: \"fill\",\n pointerEvents: \"none\",\n }}\n />\n ) : null}\n <canvas\n ref={overlayCanvasRef}\n className=\"lumen-annotate-overlay\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n />\n <div className=\"lumen-bubble-layer\">\n {comments.map((c) => (\n <Bubble\n key={c.id}\n comment={c}\n onChange={handleCommentChange}\n onRemove={handleCommentRemove}\n />\n ))}\n </div>\n </div>\n );\n});\n\n/** A single inline-editable speech-bubble. Uncontrolled contenteditable:\n * the text is seeded once on mount and thereafter owned by the DOM, so the\n * caret never jumps when the parent re-renders. Edits mirror up to state\n * (for flatten/undo) via onInput. */\nfunction Bubble({\n comment,\n onChange,\n onRemove,\n}: {\n comment: CommentAnno;\n onChange: (id: number, text: string) => void;\n onRemove: (id: number) => void;\n}) {\n const elRef = useRef<HTMLDivElement | null>(null);\n useEffect(() => {\n const el = elRef.current;\n if (el && el.textContent !== comment.text) el.textContent = comment.text;\n // Seed once — comment.text is intentionally not a dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return (\n <div\n className=\"lumen-bubble\"\n data-bubble-id={comment.id}\n style={{\n left: `${comment.x * 100}%`,\n top: `${comment.y * 100}%`,\n [\"--lumen-bubble-accent\" as string]: comment.color,\n }}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <span className=\"lumen-bubble-label\">Comment</span>\n <div\n ref={elRef}\n className=\"lumen-bubble-text\"\n contentEditable\n suppressContentEditableWarning\n role=\"textbox\"\n aria-label=\"Comment text\"\n data-placeholder=\"Type a note…\"\n onInput={(e) => onChange(comment.id, e.currentTarget.textContent ?? \"\")}\n />\n <button\n type=\"button\"\n className=\"lumen-bubble-del\"\n aria-label=\"Remove comment\"\n onPointerDown={(e) => e.stopPropagation()}\n onClick={() => onRemove(comment.id)}\n >\n ×\n </button>\n </div>\n );\n}\n\nfunction redraw(\n canvas: HTMLCanvasElement,\n annotations: Annotation[],\n draft: Annotation | null,\n) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const a of annotations) drawAnno(ctx, a);\n if (draft) drawAnno(ctx, draft);\n}\n\nfunction drawAnno(ctx: CanvasRenderingContext2D, anno: Annotation) {\n ctx.save();\n ctx.strokeStyle = anno.color;\n ctx.fillStyle = anno.color;\n ctx.lineWidth = anno.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n if (anno.kind === \"rect\") {\n const x = Math.min(anno.from.x, anno.to.x);\n const y = Math.min(anno.from.y, anno.to.y);\n const w = Math.abs(anno.to.x - anno.from.x);\n const h = Math.abs(anno.to.y - anno.from.y);\n ctx.strokeRect(x, y, w, h);\n } else if (anno.kind === \"freehand\") {\n drawSmoothPath(ctx, anno.points);\n } else {\n const { from, to, width } = anno;\n ctx.beginPath();\n ctx.moveTo(from.x, from.y);\n ctx.lineTo(to.x, to.y);\n ctx.stroke();\n const angle = Math.atan2(to.y - from.y, to.x - from.x);\n const head = Math.max(12, width * 4);\n ctx.beginPath();\n ctx.moveTo(to.x, to.y);\n ctx.lineTo(\n to.x - head * Math.cos(angle - Math.PI / 7),\n to.y - head * Math.sin(angle - Math.PI / 7),\n );\n ctx.lineTo(\n to.x - head * Math.cos(angle + Math.PI / 7),\n to.y - head * Math.sin(angle + Math.PI / 7),\n );\n ctx.closePath();\n ctx.fill();\n }\n\n ctx.restore();\n}\n\n/**\n * Draw a polyline as quadratic curves through midpoints. Each pair of\n * adjacent points contributes one curve where the original point is\n * the control point and the midpoint to the next is the end. This is\n * the standard \"midpoint smoothing\" trick — zero-dep, single pass.\n */\nfunction drawSmoothPath(\n ctx: CanvasRenderingContext2D,\n points: ReadonlyArray<{ x: number; y: number }>,\n) {\n if (points.length === 0) return;\n ctx.beginPath();\n const first = points[0];\n if (!first) return;\n ctx.moveTo(first.x, first.y);\n if (points.length === 1) {\n // Single dot — render a small filled circle so a tap is visible.\n ctx.arc(first.x, first.y, ctx.lineWidth / 2, 0, Math.PI * 2);\n ctx.fill();\n return;\n }\n if (points.length === 2) {\n const second = points[1]!;\n ctx.lineTo(second.x, second.y);\n ctx.stroke();\n return;\n }\n for (let i = 1; i < points.length - 1; i++) {\n const p = points[i]!;\n const next = points[i + 1]!;\n const mx = (p.x + next.x) / 2;\n const my = (p.y + next.y) / 2;\n ctx.quadraticCurveTo(p.x, p.y, mx, my);\n }\n // Final segment to the last point.\n const last = points[points.length - 1]!;\n ctx.lineTo(last.x, last.y);\n ctx.stroke();\n}\n\n/** Bake one comment bubble onto the output canvas at full bitmap resolution.\n * `scale` maps the on-screen UI px sizes to bitmap px so the baked bubble\n * matches what the user saw. Box top-left sits at (c.x, c.y); a small tail\n * hangs from the bottom-left, mirroring the DOM bubble. */\nfunction drawBubble(\n ctx: CanvasRenderingContext2D,\n c: CommentAnno,\n W: number,\n H: number,\n scale: number,\n) {\n const text = c.text.trim();\n if (!text) return;\n const pad = 10 * scale;\n const fontPx = 14 * scale;\n const labelPx = 10 * scale;\n const radius = 12 * scale;\n const lineH = fontPx * 1.35;\n const labelH = labelPx * 1.7;\n\n const x = c.x * W;\n const y = c.y * H;\n const maxBoxW = Math.min(W * 0.6, W - x - 8 * scale);\n\n ctx.save();\n ctx.font = `500 ${fontPx}px ${BUBBLE_FONT}`;\n ctx.textBaseline = \"top\";\n const lines = wrapText(ctx, text, maxBoxW - pad * 2);\n const textW = lines.reduce(\n (m, l) => Math.max(m, ctx.measureText(l).width),\n 0,\n );\n const boxW = Math.min(\n maxBoxW,\n Math.max(textW, 56 * scale) + pad * 2,\n );\n const boxH = pad * 2 + labelH + lines.length * lineH;\n\n // Bubble body.\n roundRect(ctx, x, y, boxW, boxH, radius);\n ctx.fillStyle = \"#ffffff\";\n ctx.fill();\n ctx.lineWidth = Math.max(1, scale);\n ctx.strokeStyle = \"rgba(0,0,0,0.10)\";\n ctx.stroke();\n\n // Tail.\n const tailX = x + 18 * scale;\n const tailY = y + boxH;\n ctx.beginPath();\n ctx.moveTo(tailX, tailY - scale);\n ctx.lineTo(tailX + 13 * scale, tailY - scale);\n ctx.lineTo(tailX + 4 * scale, tailY + 9 * scale);\n ctx.closePath();\n ctx.fillStyle = \"#ffffff\";\n ctx.fill();\n\n // Accent label.\n ctx.fillStyle = c.color || \"rgb(239, 68, 68)\";\n ctx.font = `700 ${labelPx}px ${BUBBLE_FONT}`;\n ctx.fillText(\"COMMENT\", x + pad, y + pad);\n\n // Body text.\n ctx.fillStyle = \"#111318\";\n ctx.font = `500 ${fontPx}px ${BUBBLE_FONT}`;\n let ty = y + pad + labelH;\n for (const line of lines) {\n ctx.fillText(line, x + pad, ty);\n ty += lineH;\n }\n ctx.restore();\n}\n\n/** Greedy word-wrap against a pixel width using the ctx's current font. */\nfunction wrapText(\n ctx: CanvasRenderingContext2D,\n text: string,\n maxWidth: number,\n): string[] {\n const words = text.split(/\\s+/).filter(Boolean);\n const lines: string[] = [];\n let line = \"\";\n for (const w of words) {\n const test = line ? `${line} ${w}` : w;\n if (line && ctx.measureText(test).width > maxWidth) {\n lines.push(line);\n line = w;\n } else {\n line = test;\n }\n }\n if (line) lines.push(line);\n return lines.length ? lines : [text];\n}\n\n/** Trace a rounded-rect path, using native roundRect when present. */\nfunction roundRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): void {\n const radius = Math.min(r, w / 2, h / 2);\n ctx.beginPath();\n const anyCtx = ctx as CanvasRenderingContext2D & {\n roundRect?: (x: number, y: number, w: number, h: number, r: number) => void;\n };\n if (typeof anyCtx.roundRect === \"function\") {\n anyCtx.roundRect(x, y, w, h, radius);\n return;\n }\n ctx.moveTo(x + radius, y);\n ctx.arcTo(x + w, y, x + w, y + h, radius);\n ctx.arcTo(x + w, y + h, x, y + h, radius);\n ctx.arcTo(x, y + h, x, y, radius);\n ctx.arcTo(x, y, x + w, y, radius);\n ctx.closePath();\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * Dependency-free inline SVG icons for the capture methods and annotation\n * tools. The SDK keeps zero icon-library deps (host-provided icons are\n * pass-through ReactNode elsewhere), so these are hand-rolled 24×24 strokes\n * that inherit `currentColor`.\n */\ntype IconProps = React.SVGProps<SVGSVGElement>;\n\nfunction Svg({ children, ...props }: React.PropsWithChildren<IconProps>) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.8}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n {children}\n </svg>\n );\n}\n\nexport function IconScreenshot(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M3 9a2 2 0 0 1 2-2h1.5l1-1.5h5l1 1.5H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\" />\n <circle cx=\"12\" cy=\"13\" r=\"3.2\" />\n </Svg>\n );\n}\n\nexport function IconVideo(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"3\" y=\"6\" width=\"13\" height=\"12\" rx=\"2.5\" />\n <path d=\"m16 10 5-3v10l-5-3\" />\n </Svg>\n );\n}\n\nexport function IconUpload(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M12 16V4m0 0 4 4m-4-4-4 4\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Svg>\n );\n}\n\nexport function IconComment(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M21 11.5a8.38 8.38 0 0 1-8.5 8.5 9.5 9.5 0 0 1-3.5-.7L3 21l1.7-5.5A8.38 8.38 0 0 1 4 11.5 8.5 8.5 0 0 1 12.5 3 8.38 8.38 0 0 1 21 11.5Z\" />\n </Svg>\n );\n}\n\nexport function IconArrow(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M5 19 19 5\" />\n <path d=\"M11 5h8v8\" />\n </Svg>\n );\n}\n\nexport function IconBox(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"4\" y=\"6\" width=\"16\" height=\"12\" rx=\"2\" />\n </Svg>\n );\n}\n\nexport function IconDraw(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M5 19l1.5-5L16 4.5 19.5 8 10 17.5 5 19z\" />\n <path d=\"M14 6.5l3.5 3.5\" />\n </Svg>\n );\n}\n\nexport function IconUndo(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M9 8 4 13l5 5\" />\n <path d=\"M4 13h11a5 5 0 0 1 0 10h-1\" />\n </Svg>\n );\n}\n\nexport function IconRefresh(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M21 12a9 9 0 1 1-3-6.7\" />\n <path d=\"M21 4v4h-4\" />\n </Svg>\n );\n}\n\nexport function IconRedo(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M15 8 20 13l-5 5\" />\n <path d=\"M20 13H9a5 5 0 0 0 0 10h1\" />\n </Svg>\n );\n}\n\nexport function IconTrash(props: IconProps) {\n return (\n <Svg {...props}>\n <path d=\"M4 7h16\" />\n <path d=\"M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\" />\n <path d=\"M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13\" />\n </Svg>\n );\n}\n\nexport function IconChevronLeft(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={2.2}>\n <path d=\"M15 6l-6 6 6 6\" />\n </Svg>\n );\n}\n\nexport function IconSend(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={1.9}>\n <path d=\"M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z\" />\n </Svg>\n );\n}\n\nexport function IconImage(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={1.7}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2.5\" />\n <circle cx=\"8.5\" cy=\"9.5\" r=\"1.6\" />\n <path d=\"m4 17 5-5 5 4 2-2 4 4\" />\n </Svg>\n );\n}\n\nexport function IconFilm(props: IconProps) {\n return (\n <Svg {...props} strokeWidth={1.7}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2.5\" />\n <path d=\"M3 9h18M3 15h18M8 4v16M16 4v16\" />\n </Svg>\n );\n}\n\nexport function IconMonitor(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"13\" rx=\"2\" />\n <path d=\"M8 21h8M12 17v4\" />\n </Svg>\n );\n}\n\nexport function IconMic(props: IconProps) {\n return (\n <Svg {...props}>\n <rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\" />\n <path d=\"M5 11a7 7 0 0 0 14 0M12 18v3\" />\n </Svg>\n );\n}\n\nexport const METHOD_ICONS = {\n shot: IconScreenshot,\n video: IconVideo,\n upload: IconUpload,\n} as const;\n","\"use client\";\n\n/**\n * First-frame poster helpers for the Video and Upload methods. Kept in the\n * React layer (not core) so the published core API surface stays unchanged.\n * A video submission still wants a still image for the `screenshot` field —\n * the thumbnail the dashboard shows — so we grab the first frame.\n */\n\nfunction drawPoster(video: HTMLVideoElement): Promise<Blob | null> {\n const w = video.videoWidth || 1280;\n const h = video.videoHeight || 720;\n const canvas = document.createElement(\"canvas\");\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return Promise.resolve(null);\n ctx.drawImage(video, 0, 0, w, h);\n return new Promise((resolve) =>\n canvas.toBlob((b) => resolve(b), \"image/jpeg\", 0.82),\n );\n}\n\nfunction seek(video: HTMLVideoElement, t: number): Promise<void> {\n if (!Number.isFinite(t) || t <= 0) return Promise.resolve();\n return new Promise<void>((resolve) => {\n video.addEventListener(\"seeked\", () => resolve(), { once: true });\n try {\n video.currentTime = t;\n } catch {\n resolve();\n }\n });\n}\n\n/** Overall deadline for decoding a poster out of a video blob. The decode\n * events this relies on (`loadeddata`, `seeked`) are NOT guaranteed to fire\n * — `preload` quirks and MediaRecorder blobs with broken metadata can leave\n * them pending forever, which previously stranded the reopen flow on an\n * endless \"Capturing…\" phase. Past the deadline callers fall back to the\n * placeholder poster. */\nconst POSTER_DECODE_TIMEOUT_MS = 4000;\n\n/** Poster (first frame) + duration from an uploaded/recorded video blob.\n * Never hangs: resolves with a null poster after the decode deadline. */\nexport async function posterFromVideoBlob(\n blob: Blob,\n): Promise<{ poster: Blob | null; durationMs: number }> {\n if (typeof document === \"undefined\") return { poster: null, durationMs: 0 };\n const url = URL.createObjectURL(blob);\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n // \"auto\", not \"metadata\" — we need a decoded frame, and some browsers\n // never advance past metadata (no `loadeddata`) without it.\n video.preload = \"auto\";\n video.src = url;\n\n const attempt = async (): Promise<{ poster: Blob | null; durationMs: number }> => {\n await new Promise<void>((resolve, reject) => {\n if (video.readyState >= 2) return resolve();\n video.addEventListener(\"loadeddata\", () => resolve(), { once: true });\n video.addEventListener(\n \"error\",\n () => reject(new Error(\"video decode failed\")),\n { once: true },\n );\n });\n // A small seek forces a decoded frame on browsers that leave the poster\n // black at t=0.\n await seek(video, Math.min(0.1, (video.duration || 0) / 2));\n const poster = await drawPoster(video);\n const durationMs = Number.isFinite(video.duration)\n ? video.duration * 1000\n : 0;\n return { poster, durationMs };\n };\n\n let timer: number | undefined;\n const deadline = new Promise<{ poster: Blob | null; durationMs: number }>(\n (resolve) => {\n timer = window.setTimeout(\n () => resolve({ poster: null, durationMs: 0 }),\n POSTER_DECODE_TIMEOUT_MS,\n );\n },\n );\n\n try {\n return await Promise.race([\n attempt().catch(() => ({ poster: null, durationMs: 0 })),\n deadline,\n ]);\n } finally {\n window.clearTimeout(timer);\n video.removeAttribute(\"src\");\n URL.revokeObjectURL(url);\n }\n}\n\n/**\n * Poster (first frame) from a live screen-capture stream — grabbed at record\n * start so we never re-decode the recorded blob (the flaky path). Returns\n * null if a frame can't be read in time; callers fall back to a placeholder.\n */\nexport async function posterFromStream(\n stream: MediaStream,\n): Promise<Blob | null> {\n if (typeof document === \"undefined\") return null;\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n video.srcObject = stream;\n try {\n await video.play().catch(() => undefined);\n await new Promise<void>((resolve) => {\n if (video.readyState >= 2) return resolve();\n video.addEventListener(\"loadeddata\", () => resolve(), { once: true });\n window.setTimeout(resolve, 600);\n });\n return await drawPoster(video);\n } catch {\n return null;\n } finally {\n video.srcObject = null;\n }\n}\n\n/** Neutral fallback poster (dark frame + play glyph) when a real frame can't\n * be grabbed, so the wizard always has a `screenshot` blob to proceed with. */\nexport async function placeholderPoster(): Promise<Blob | null> {\n if (typeof document === \"undefined\") return null;\n const canvas = document.createElement(\"canvas\");\n canvas.width = 1280;\n canvas.height = 720;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n ctx.fillStyle = \"#0e0e12\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = \"#52525b\";\n ctx.beginPath();\n ctx.moveTo(590, 312);\n ctx.lineTo(590, 408);\n ctx.lineTo(694, 360);\n ctx.closePath();\n ctx.fill();\n return new Promise((resolve) =>\n canvas.toBlob((b) => resolve(b), \"image/jpeg\", 0.8),\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\nimport { toast } from \"sonner\";\nimport {\n captureContext,\n captureScreen,\n createManualCaptureResult,\n recordAudio,\n type CaptureResult,\n type FeedbackCategory,\n type FeedbackPriority,\n type FeedbackSource,\n type RecorderHandle,\n type ScreenshotCaptureMode,\n} from \"@lumen-stack/core\";\n\nimport { useLumen } from \"./context\";\nimport { useKeyboardInset } from \"./trigger/useKeyboardInset\";\nimport {\n AnnotationLayer,\n type AnnotationLayerHandle,\n type AnnotationTool,\n} from \"./AnnotationLayer\";\nimport {\n METHOD_ICONS,\n IconMic,\n IconMonitor,\n IconArrow,\n IconBox,\n IconDraw,\n IconComment,\n IconUndo,\n IconRedo,\n IconTrash,\n IconRefresh,\n IconUpload,\n IconChevronLeft,\n IconSend,\n} from \"./icons\";\nimport { posterFromVideoBlob, placeholderPoster } from \"./video-poster\";\n\nconst VOICE_MAX_SECONDS = 60;\n// Mirrors the server's MAX_VIDEO_BYTES cap. Native screen recordings (mp4) can\n// easily exceed this, so warn at attach time rather than letting submit fail\n// with an opaque upload error. Kept local so the published SDK has no workspace\n// dep on the server's constants.\nconst VIDEO_SIZE_WARN_BYTES = 25 * 1024 * 1024;\n\nconst SWATCHES: ReadonlyArray<{ label: string; value: string }> = [\n { label: \"Red\", value: \"rgb(239, 68, 68)\" },\n { label: \"Amber\", value: \"rgb(245, 158, 11)\" },\n { label: \"Blue\", value: \"rgb(59, 130, 246)\" },\n { label: \"Green\", value: \"rgb(34, 197, 94)\" },\n { label: \"Neutral\", value: \"rgb(244, 244, 245)\" },\n];\n\nconst STROKE_SIZES: ReadonlyArray<{ label: string; value: number; dot: number }> = [\n { label: \"Small\", value: 2, dot: 6 },\n { label: \"Medium\", value: 4, dot: 9 },\n { label: \"Large\", value: 6, dot: 12 },\n];\n\nconst CATEGORIES: ReadonlyArray<{ value: FeedbackCategory; label: string }> = [\n { value: \"bug\", label: \"Bug\" },\n { value: \"feature\", label: \"Idea\" },\n { value: \"other\", label: \"Other\" },\n];\n\n// Reporter-set priority, using Linear's naming. \"\" = \"No priority\" (the default\n// — the reporter opts in). Sent to the server and pushed to Linear as-is.\nconst PRIORITIES: ReadonlyArray<{ value: FeedbackPriority | \"\"; label: string }> = [\n { value: \"\", label: \"No priority\" },\n { value: \"urgent\", label: \"Urgent\" },\n { value: \"high\", label: \"High\" },\n { value: \"medium\", label: \"Medium\" },\n { value: \"low\", label: \"Low\" },\n];\n\n// The review detent's editable platform chips. \"custom\" stays under the hood\n// (no chip) — the server still records it — but it can't be picked here.\nconst SOURCE_CHIPS: ReadonlyArray<{ value: FeedbackSource; label: string }> = [\n { value: \"web\", label: \"Web\" },\n { value: \"ios-web\", label: \"iOS web\" },\n { value: \"android-web\", label: \"Android web\" },\n { value: \"ios-native\", label: \"iOS native\" },\n { value: \"android-native\", label: \"Android native\" },\n];\n\n// Default platform for the review chips, derived from the capture environment.\n// The native bridge reports ios/android (→ *-native). For a browser capture\n// (platform \"web\") we further split desktop vs mobile web by the user agent,\n// so the report is tagged ios-web / android-web / web. Mirrors what the user\n// can still override via the chips.\nfunction deriveSource(cap: CaptureResult): FeedbackSource {\n if (cap.platform === \"ios\") return \"ios-native\";\n if (cap.platform === \"android\") return \"android-native\";\n if (cap.platform === \"custom\") return \"custom\";\n // Browser capture — distinguish mobile web from desktop by UA.\n const ua = typeof navigator !== \"undefined\" ? navigator.userAgent || \"\" : \"\";\n if (/android/i.test(ua)) return \"android-web\";\n const isIOS =\n /iphone|ipad|ipod/i.test(ua) ||\n // iPadOS reports a desktop \"Macintosh\" UA but is touch-capable.\n (/macintosh/i.test(ua) &&\n typeof document !== \"undefined\" &&\n \"ontouchend\" in document);\n if (isIOS) return \"ios-web\";\n return \"web\";\n}\n\n// Linear-style priority glyph: an urgent square, else 1–3 ascending bars.\nfunction PriorityIcon({ value }: { value: FeedbackPriority }) {\n if (value === \"urgent\") {\n return <span className=\"lumen-pri-ic lumen-pri-urgent\" aria-hidden=\"true\">!</span>;\n }\n const level = value === \"high\" ? 3 : value === \"medium\" ? 2 : 1;\n return (\n <span className=\"lumen-pri-ic lumen-pri-bars\" data-level={level} aria-hidden=\"true\">\n <i />\n <i />\n <i />\n </span>\n );\n}\n\ntype CaptureMethod = \"shot\" | \"video\" | \"upload\";\n\nconst METHODS: ReadonlyArray<{\n value: CaptureMethod;\n label: string;\n hint: string;\n /** Screenshot is the prominent hero card; the rest sit in a row below. */\n primary?: boolean;\n}> = [\n { value: \"shot\", label: \"Screenshot\", hint: \"This page, instantly\", primary: true },\n { value: \"video\", label: \"Video\", hint: \"Record up to 60s\" },\n { value: \"upload\", label: \"Upload\", hint: \"Image or video\" },\n];\n\ntype Step = 1 | 2 | 3;\n\n// Capture sub-state, independent of the wizard step. The annotated artifact\n// lives on `ready`. `idle` = step 1 with nothing captured yet.\ntype Phase =\n | { kind: \"idle\" }\n | { kind: \"capturing\" }\n | { kind: \"manual\"; error?: string }\n | { kind: \"ready\"; capture: CaptureResult };\n\nexport function CaptureModal() {\n const {\n client,\n isOpen,\n closeCapture,\n user,\n capture,\n initialCapture,\n initialCaptureError,\n startVideoSession,\n consumePendingVideo,\n canRecordScreen,\n consumeRecordStartError,\n startScreenCaptureSession,\n consumePendingScreenshot,\n isolateEvents,\n keyboardInset,\n } = useLumen();\n const [step, setStep] = useState<Step>(1);\n const [method, setMethod] = useState<CaptureMethod | null>(null);\n const [phase, setPhase] = useState<Phase>({ kind: \"idle\" });\n const [submitting, setSubmitting] = useState(false);\n const [progress, setProgress] = useState(0);\n // The AnnotationLayer stays mounted on both the markup (1) and review (2)\n // steps, so the annotated shot is flattened lazily in submit() — no need to\n // stash it on Next, and Back never loses the strokes.\n\n const [tool, setTool] = useState<AnnotationTool>(\"arrow\");\n const [strokeColor, setStrokeColor] = useState<string>(SWATCHES[0]!.value);\n const [strokeWidth, setStrokeWidth] = useState<number>(STROKE_SIZES[1]!.value);\n const [text, setText] = useState(\"\");\n const [category, setCategory] = useState<FeedbackCategory>(\"bug\");\n const [priority, setPriority] = useState<FeedbackPriority | \"\">(\"\");\n // Capture source (platform). Defaulted from the capture environment when the\n // review detent opens, then editable via chips (\"auto-detected — change if\n // wrong\"). \"\" until derived.\n const [source, setSource] = useState<FeedbackSource | \"\">(\"\");\n // Fullscreen markup: show/hide the floating tool palette (the prototype's\n // pen-toggle), so the user can clear the view to see the capture.\n const [toolsHidden, setToolsHidden] = useState(false);\n // Fullscreen markup: drag/tap the grabber to minimize the compose sheet and\n // reveal the full capture.\n const [sheetCollapsed, setSheetCollapsed] = useState(false);\n const [recapMenuOpen, setRecapMenuOpen] = useState(false);\n const [colorPickerOpen, setColorPickerOpen] = useState(false);\n const [submitterEmail, setSubmitterEmail] = useState(user?.email ?? \"\");\n const [recorder, setRecorder] = useState<RecorderHandle | null>(null);\n const [audio, setAudio] = useState<{ blob: Blob; durationMs: number } | null>(\n null,\n );\n const [recordSecs, setRecordSecs] = useState(0);\n const [video, setVideo] = useState<{ blob: Blob; durationMs: number } | null>(\n null,\n );\n // Inline error shown on the Record step when a custom/native record provider\n // fails to start (seeded from the provider's consume-once start error).\n const [videoError, setVideoError] = useState<string | null>(null);\n const [drawing, setDrawing] = useState(false);\n // Mirrors AnnotationLayer's undo/redo stacks so the toolbar buttons can\n // disable themselves at each end of the history.\n const [history, setHistory] = useState({ canUndo: false, canRedo: false });\n const annotationRef = useRef<AnnotationLayerHandle>(null);\n // Hidden file input for the Upload method — opened straight from the method\n // pill so there's no empty boxed \"choose a file\" step in between.\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n const modalRef = useRef<HTMLDivElement | null>(null);\n const backdropRef = useRef<HTMLDivElement | null>(null);\n const previouslyFocusedRef = useRef<HTMLElement | null>(null);\n\n // Keyboard-aware while the sheet is open: lifts the sheet above the soft\n // keyboard and keeps the focused input visible — works in an iOS WKWebView\n // (where visualViewport is silent) when the host injects the inset.\n const keyboard = useKeyboardInset(isOpen, keyboardInset);\n\n // Cancellation flag for in-flight captures — survives a Strict-Mode double\n // mount or a fast re-open so a stale capture can't stomp the latest phase.\n const captureCancelledRef = useRef(false);\n // Seed the wizard exactly once per open. Without this, an unstable `capture`\n // prop re-rendering mid-session would re-run the reset effect and wipe a\n // just-recorded clip (consumePendingVideo is already drained).\n const seededRef = useRef(false);\n\n // Reset everything when the modal opens. For web capture the default shot is\n // taken before the wizard mounts (so Lumen chrome is absent); for provider\n // (native/custom) capture it is taken here from the open wizard, where the\n // provider conceals Lumen UI — this keeps host overlays in the shot.\n // Reset the per-open seed guard whenever the sheet closes.\n useEffect(() => {\n if (!isOpen) seededRef.current = false;\n }, [isOpen]);\n\n\n useEffect(() => {\n if (!isOpen) return;\n // Run the seed once per open — immune to spurious re-runs from an\n // unstable `capture` prop while the wizard is already in progress.\n if (seededRef.current) {\n // The cleanup below already flagged cancellation for this re-run,\n // which would strand any in-flight capture/poster derivation in the\n // \"capturing\" phase forever. The wizard is still open — undo it.\n captureCancelledRef.current = false;\n return;\n }\n seededRef.current = true;\n captureCancelledRef.current = false;\n setStep(1);\n setMethod(null);\n setText(\"\");\n setAudio(null);\n setRecordSecs(0);\n setVideo(null);\n setSubmitting(false);\n setProgress(0);\n setSource(\"\");\n setVideoError(null);\n setHistory({ canUndo: false, canRedo: false });\n // A just-grabbed exact-screen shot (sheet reopened by the capture HUD)\n // wins: seed it straight into the annotator, exactly like the default DOM\n // shot, instead of running a fresh capture.\n const pendingShot = consumePendingScreenshot();\n if (pendingShot) {\n setMethod(\"shot\");\n showCaptureWarnings(pendingShot);\n setPhase({ kind: \"ready\", capture: pendingShot });\n return;\n }\n // A just-finished recording (sheet reopened by the HUD's Stop) wins:\n // seed the video method with the clip + its poster instead of capturing\n // a fresh screenshot.\n const pending = consumePendingVideo();\n if (pending) {\n setMethod(\"video\");\n setVideo({ blob: pending.blob, durationMs: pending.durationMs });\n if (pending.blob.size > VIDEO_SIZE_WARN_BYTES) {\n toast.warning(\n \"This recording is large and may be too big to upload. Try a shorter clip if the upload fails.\",\n );\n }\n if (pending.poster) {\n setPhase({\n kind: \"ready\",\n capture: createManualCaptureResult(pending.poster, [\n \"Screen recording; preview is the first frame.\",\n ]),\n });\n } else {\n // No stream-derived poster. Provider clips (deriveBlobPoster) get a\n // first-frame poster decoded from the blob — handles mp4 from native\n // hosts; the browser path keeps its placeholder-only behavior.\n setPhase({ kind: \"capturing\" });\n void (async () => {\n let posterBlob: Blob | null = null;\n if (pending.deriveBlobPoster) {\n try {\n posterBlob = (await posterFromVideoBlob(pending.blob)).poster;\n } catch {\n posterBlob = null;\n }\n }\n posterBlob = posterBlob ?? (await placeholderPoster());\n if (captureCancelledRef.current) return;\n setPhase(\n posterBlob\n ? {\n kind: \"ready\",\n capture: createManualCaptureResult(posterBlob, [\n \"Screen recording; preview is the first frame.\",\n ]),\n }\n : { kind: \"manual\" },\n );\n })();\n }\n } else {\n const startErr = consumeRecordStartError();\n if (startErr) {\n // A custom/native record provider failed to start — land on the Record\n // step and surface it inline (Upload suggested as the fallback).\n setMethod(\"video\");\n setVideoError(startErr);\n setPhase({ kind: \"idle\" });\n } else if (initialCapture) {\n setMethod(\"shot\");\n setPhase({ kind: \"ready\", capture: initialCapture });\n } else if (capture?.mode === \"manual\") {\n setPhase({ kind: \"manual\" });\n } else if (capture?.provider && !initialCaptureError) {\n // Provider mode (native/custom capture) defers the default screenshot\n // to here so host overlays — e.g. native iOS overlays — render into the\n // shot. Capturing pre-open dropped them. The provider conceals Lumen's\n // own UI during the shot, so grabbing it from the open wizard is leak-\n // safe. Falls back to manual via runCapture's catch if the shot fails.\n setMethod(\"shot\");\n void runCapture(capture.mode ?? \"auto\");\n } else {\n setPhase({\n kind: \"manual\",\n error:\n initialCaptureError?.message ??\n \"Automatic screenshot capture was unavailable.\",\n });\n }\n }\n return () => {\n captureCancelledRef.current = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, capture, initialCapture, initialCaptureError]);\n\n // Body scroll-lock + remember/restore focus while the modal is open.\n // Restore is wired through pagehide as well, so a navigation or a host\n // app crash while the modal is open can't leave the page unscrollable.\n useEffect(() => {\n if (!isOpen) return;\n previouslyFocusedRef.current =\n (document.activeElement as HTMLElement | null) ?? null;\n const html = document.documentElement;\n const prevOverflow = html.style.overflow;\n const prevPaddingRight = html.style.paddingRight;\n const scrollbar = window.innerWidth - html.clientWidth;\n html.style.overflow = \"hidden\";\n if (scrollbar > 0) html.style.paddingRight = `${scrollbar}px`;\n let restored = false;\n const restore = () => {\n if (restored) return;\n restored = true;\n html.style.overflow = prevOverflow;\n html.style.paddingRight = prevPaddingRight;\n try {\n previouslyFocusedRef.current?.focus?.();\n } catch {\n // focus() can throw if the prior element was removed from DOM.\n }\n };\n window.addEventListener(\"pagehide\", restore);\n return () => {\n window.removeEventListener(\"pagehide\", restore);\n restore();\n };\n }, [isOpen]);\n\n // ESC to close. Tab/Shift-Tab focus trap.\n useEffect(() => {\n if (!isOpen) return;\n function onKey(e: KeyboardEvent) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n closeCapture();\n return;\n }\n if (e.key !== \"Tab\") return;\n const root = modalRef.current;\n if (!root) return;\n const focusables = getFocusable(root);\n if (focusables.length === 0) return;\n const first = focusables[0]!;\n const last = focusables[focusables.length - 1]!;\n const active = document.activeElement as HTMLElement | null;\n if (e.shiftKey && (active === first || !root.contains(active))) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [isOpen, closeCapture]);\n\n // Keep a tap on the empty backdrop from leaking into host outside-click\n // handlers (so a host bottom sheet under our opaque backdrop isn't dismissed).\n // Gated to the backdrop itself so the modal's own React handlers are untouched\n // — events from modal content (target !== backdrop) bubble normally. Hosts\n // that need full-subtree isolation should use isLumenEventTarget().\n useEffect(() => {\n if (!isOpen || !isolateEvents) return;\n const el = backdropRef.current;\n if (!el) return;\n const stopOnBackdrop = (event: Event) => {\n if (event.target === el) event.stopPropagation();\n };\n el.addEventListener(\"pointerdown\", stopOnBackdrop);\n el.addEventListener(\"click\", stopOnBackdrop);\n el.addEventListener(\"touchstart\", stopOnBackdrop, { passive: true });\n return () => {\n el.removeEventListener(\"pointerdown\", stopOnBackdrop);\n el.removeEventListener(\"click\", stopOnBackdrop);\n el.removeEventListener(\"touchstart\", stopOnBackdrop);\n };\n }, [isOpen, isolateEvents]);\n\n // When the keyboard opens, scroll the focused field into view so it never\n // sits behind the keyboard (the sheet itself is lifted via CSS var below).\n useEffect(() => {\n if (!isOpen || !keyboard.open) return;\n const root = modalRef.current;\n const active = document.activeElement as HTMLElement | null;\n if (root && active && root.contains(active)) {\n try {\n active.scrollIntoView({ block: \"center\" });\n } catch {\n // scrollIntoView options can throw on very old engines — ignore.\n }\n }\n }, [isOpen, keyboard.open, keyboard.inset]);\n\n // Paste-to-upload while on the manual-capture fallback.\n useEffect(() => {\n if (!isOpen || phase.kind !== \"manual\") return;\n function onPaste(e: ClipboardEvent) {\n const items = Array.from(e.clipboardData?.items ?? []);\n const image = items.find((item) => item.type.startsWith(\"image/\"));\n const file = image?.getAsFile();\n if (!file) return;\n e.preventDefault();\n void acceptUploadedFile(file);\n }\n window.addEventListener(\"paste\", onPaste);\n return () => window.removeEventListener(\"paste\", onPaste);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, phase.kind]);\n\n // Voice record timer.\n useEffect(() => {\n if (!recorder) return;\n const start = Date.now();\n const id = window.setInterval(() => {\n const sec = Math.floor((Date.now() - start) / 1000);\n setRecordSecs(sec);\n if (sec >= VOICE_MAX_SECONDS) finishRecording();\n }, 250);\n return () => window.clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recorder]);\n\n // Never leave the mic live after the sheet goes away: ESC, backdrop,\n // Cancel, and the HUD's record flow all just flip isOpen, so the active\n // recorder must be cancelled here — and again on unmount, in case the\n // host removes the provider while a voice note is running.\n const recorderRef = useRef<RecorderHandle | null>(null);\n recorderRef.current = recorder;\n useEffect(() => {\n if (isOpen) return;\n if (recorderRef.current) {\n recorderRef.current.cancel();\n recorderRef.current = null;\n setRecorder(null);\n setRecordSecs(0);\n }\n }, [isOpen]);\n useEffect(\n () => () => {\n recorderRef.current?.cancel();\n },\n [],\n );\n\n if (!isOpen) return null;\n\n // ── Capture ───────────────────────────────────────────────────────────\n async function runCapture(mode: ScreenshotCaptureMode): Promise<boolean> {\n captureCancelledRef.current = false;\n setPhase({ kind: \"capturing\" });\n try {\n const result = await captureScreen({\n ...capture,\n mode,\n target: capture?.target ?? document.documentElement,\n });\n if (captureCancelledRef.current) return false;\n showCaptureWarnings(result);\n setPhase({ kind: \"ready\", capture: result });\n return true;\n } catch (e) {\n if (captureCancelledRef.current) return false;\n setPhase({\n kind: \"manual\",\n error:\n e instanceof Error\n ? e.message\n : \"Automatic screenshot capture was unavailable.\",\n });\n return false;\n }\n }\n\n async function selectMethod(m: CaptureMethod) {\n setMethod(m);\n setVideoError(null);\n // A fresh capture yields a new screenshot blob, which remounts the\n // AnnotationLayer and clears any prior markup — recapture is explicit.\n if (m !== \"video\") discardVideo();\n if (m === \"shot\") {\n await runCapture(capture?.mode ?? \"auto\");\n } else if (m === \"video\") {\n // Show the Record button; recording only starts on an explicit tap so\n // getDisplayMedia fires from a fresh user gesture (no awaited capture\n // in between to drop the activation).\n setVideo(null);\n setPhase({ kind: \"idle\" });\n } else {\n // Upload: open the native picker right away (within this user gesture),\n // so the user never sees an empty boxed screen. The fullscreen drop zone\n // stays as a fallback if they dismiss the picker. Image → annotatable\n // screenshot slot; video → poster + attachment.\n setPhase({ kind: \"manual\" });\n uploadInputRef.current?.click();\n }\n }\n\n // Upload method: accept an image (→ annotatable screenshot slot) or a\n // video (→ video attachment + an auto-generated first-frame poster that\n // fills the `screenshot` slot the dashboard shows as a thumbnail).\n async function acceptUploadedFile(file: File) {\n if (file.type.startsWith(\"image/\")) {\n discardVideo();\n const result = createManualCaptureResult(file, [\n \"Manual image upload used.\",\n ]);\n setPhase({ kind: \"ready\", capture: result });\n return;\n }\n if (file.type.startsWith(\"video/\")) {\n setPhase({ kind: \"capturing\" });\n try {\n const { poster, durationMs } = await posterFromVideoBlob(file);\n const posterBlob = poster ?? (await placeholderPoster());\n if (!posterBlob) {\n setPhase({ kind: \"manual\", error: \"Could not read that video.\" });\n return;\n }\n const result = createManualCaptureResult(posterBlob, [\n \"Uploaded video; preview is the first frame.\",\n ]);\n setVideo({ blob: file, durationMs });\n setPhase({ kind: \"ready\", capture: result });\n } catch {\n setPhase({ kind: \"manual\", error: \"Could not read that video.\" });\n }\n return;\n }\n toast.error(\"Choose an image (PNG, JPEG, WebP) or a video (MP4, WebM).\");\n }\n\n function showCaptureWarnings(result: CaptureResult) {\n if (result.warnings.length === 0) return;\n toast.warning(\n \"Screenshot captured, but iframe, video, canvas, or cross-origin content may be incomplete.\",\n );\n }\n\n // ── Voice ─────────────────────────────────────────────────────────────\n async function startRecording() {\n try {\n const r = await recordAudio(VOICE_MAX_SECONDS);\n setRecorder(r);\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Microphone unavailable\");\n }\n }\n async function finishRecording() {\n if (!recorder) return;\n try {\n const result = await recorder.stop();\n setAudio({ blob: result.blob, durationMs: result.durationMs });\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Could not stop recording\");\n } finally {\n setRecorder(null);\n }\n }\n function discardRecording() {\n recorder?.cancel();\n setRecorder(null);\n setAudio(null);\n setRecordSecs(0);\n }\n\n // Shared voice control. `capture` is the prominent in-context affordance on\n // the capture screen (record while the bug is still on screen); `describe`\n // is the labelled form row on step 2. Both drive the same `audio` state, so\n // a note taken on the capture step shows up already-attached on step 2.\n function renderVoiceNote(variant: \"capture\" | \"describe\") {\n const controls = (\n <div className=\"lumen-audio-row\">\n {!recorder && !audio ? (\n <button\n type=\"button\"\n onClick={startRecording}\n className={\n variant === \"capture\"\n ? \"lumen-voice-capture-btn\"\n : \"lumen-btn-ghost\"\n }\n >\n <IconMic />\n Record voice note\n </button>\n ) : null}\n {recorder ? (\n <>\n <span className=\"lumen-recording\">\n <span className=\"lumen-rec-dot\" aria-hidden=\"true\" />\n <Waveform stream={recorder.stream} />\n <span className=\"lumen-rec-time\">\n {recordSecs}s / {VOICE_MAX_SECONDS}s\n </span>\n </span>\n <button\n type=\"button\"\n onClick={finishRecording}\n className=\"lumen-btn-ghost\"\n >\n Stop\n </button>\n <button\n type=\"button\"\n onClick={discardRecording}\n className=\"lumen-btn-ghost\"\n >\n Cancel\n </button>\n </>\n ) : null}\n {audio && !recorder ? (\n <>\n <AudioPreview blob={audio.blob} durationMs={audio.durationMs} />\n <button\n type=\"button\"\n onClick={() => setAudio(null)}\n className=\"lumen-btn-ghost\"\n >\n Remove\n </button>\n </>\n ) : null}\n </div>\n );\n\n if (variant === \"capture\") {\n return (\n <div className=\"lumen-voice-capture\">\n {controls}\n {!recorder && !audio ? (\n <p className=\"lumen-voice-capture-hint\">\n Say what went wrong while it’s fresh.\n </p>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className=\"lumen-label\">\n <span>Add a voice note (optional)</span>\n {controls}\n </div>\n );\n }\n\n // ── Screen recording (the session lives in the provider so it survives\n // the sheet closing) ─────────────────────────────────────────────────\n async function beginVideoRecording() {\n setVideoError(null);\n try {\n // Closes the sheet; the floating HUD takes over and the sheet reopens\n // with the clip attached when the user stops. The provider path reports\n // start failures inline via the record-start error (not a throw); the\n // browser path throws SCREEN_DENIED if the picker is dismissed.\n await startVideoSession();\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Screen capture unavailable\");\n }\n }\n function discardVideo() {\n setVideo(null);\n }\n\n // ── Navigation ────────────────────────────────────────────────────────\n const captured = phase.kind === \"ready\";\n async function goNext() {\n // Finalize a still-running voice note before advancing. Clicking \"Next\"\n // while recording should stop+keep the take, not silently drop it\n // (awaited so the blob is in state by the time submit reads it).\n if (recorder) await finishRecording();\n if (step === 1) {\n // Seed the review's platform chip from the capture environment (once);\n // the user can still override it before sending. The AnnotationLayer\n // stays mounted, so we flatten lazily in submit() rather than here.\n if (phase.kind === \"ready\" && !source) setSource(deriveSource(phase.capture));\n // → the review detent (editable priority/platform/description → Send).\n setStep(2);\n } else {\n await submit();\n }\n }\n function goBack() {\n if (step > 1) setStep((s) => (s - 1) as Step);\n }\n\n async function submit() {\n if (phase.kind !== \"ready\") return;\n const trimmed = text.trim();\n const { capture: captureResult } = phase;\n setSubmitting(true);\n setProgress(0);\n try {\n // Flatten the (still-mounted) annotation layer now, at send time.\n const flat = await annotationRef.current?.flatten();\n const flatScreenshot = flat ?? captureResult.blob;\n const result = await client.submit(\n {\n rawText: trimmed.length > 0 ? trimmed : undefined,\n category,\n priority: priority || undefined,\n source: source || undefined,\n submitterEmail: submitterEmail.trim() || undefined,\n screenshot: flatScreenshot,\n audio: audio?.blob,\n audioDurationMs: audio?.durationMs,\n video: video?.blob,\n videoDurationMs: video?.durationMs,\n context: captureContext(captureResult),\n },\n {\n onUploadProgress: (fraction) => setProgress(Math.min(0.95, fraction)),\n },\n );\n setProgress(1);\n toast.success(\"Feedback sent — thank you.\");\n void result.id;\n closeCapture();\n } catch (e) {\n toast.error(e instanceof Error ? e.message : \"Could not submit feedback\");\n setSubmitting(false);\n }\n }\n\n function onBackdropMouseDown(e: React.MouseEvent<HTMLDivElement>) {\n if (e.target === e.currentTarget && !submitting) closeCapture();\n }\n\n const uploadingPct = Math.round(progress * 100);\n const isVideoMethod = method === \"video\";\n // Web-only upgrade: the default screenshot is a DOM rasterization (a\n // reconstruction of the page). Offer a one-tap swap to a pixel-perfect\n // getDisplayMedia capture. Hidden on the native shell — a custom provider\n // already returns a real screenshot there, and iOS has no getDisplayMedia.\n const trueScreenAvailable =\n typeof navigator !== \"undefined\" &&\n !!navigator.mediaDevices?.getDisplayMedia;\n const showExactCapture =\n method === \"shot\" &&\n !capture?.provider &&\n capture?.allowTrueScreen !== false &&\n trueScreenAvailable;\n const nextDisabled =\n (step === 1 && !captured) || submitting;\n const nextLabel =\n step < 3\n ? \"Next\"\n : submitting\n ? uploadingPct < 95\n ? `Uploading ${uploadingPct}%…`\n : \"Almost done…\"\n : \"Send feedback\";\n\n // Stage 2a: once a capture is ready, the capture step renders as a fullscreen\n // markup surface — the screen large + dark surround + floating glass chrome,\n // instead of the boxed sheet view. Other steps keep the normal sheet.\n // Fullscreen surround applies for the entire capture step — the method\n // picker (fallback when auto-capture is unavailable), record prompt, upload\n // picker and \"capturing…\" all share the same dark surround + floating chrome\n // instead of the old boxed wizard.\n const captureFullscreen = step === 1;\n // The review detent (step 2) is also a fullscreen surface — the dimmed,\n // annotated capture sits behind the raised panel — so it reuses the same\n // chrome-hiding `data-lumen-fs` styling.\n const reviewFullscreen = step === 2 && phase.kind === \"ready\";\n const fsMode = captureFullscreen || reviewFullscreen;\n\n return (\n <div\n ref={backdropRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Send feedback\"\n className=\"lumen-modal-backdrop\"\n data-lumen-capture-ignore=\"true\"\n style={\n keyboard.inset\n ? ({\n \"--lumen-keyboard-inset\": `${keyboard.inset}px`,\n } as CSSProperties)\n : undefined\n }\n onMouseDown={onBackdropMouseDown}\n >\n <div\n ref={modalRef}\n className=\"lumen-modal\"\n data-lumen-drawing={drawing ? \"true\" : undefined}\n data-lumen-fs={fsMode ? \"true\" : undefined}\n data-lumen-review={reviewFullscreen ? \"true\" : undefined}\n data-lumen-sheet={\n captureFullscreen && sheetCollapsed ? \"down\" : undefined\n }\n >\n <SheetGrabber onDismiss={closeCapture} />\n\n <header className=\"lumen-modal-header\">\n <h2 className=\"lumen-modal-title\">\n <span className=\"lumen-modal-title-dot\" aria-hidden=\"true\" />\n Send feedback\n </h2>\n <button\n type=\"button\"\n onClick={closeCapture}\n className=\"lumen-icon-btn\"\n aria-label=\"Close\"\n >\n ×\n </button>\n </header>\n\n <Stepper step={step} />\n\n {/* Always-mounted picker the Upload method opens directly (no boxed\n intermediate). Image → annotatable; video → poster + attachment. */}\n <input\n ref={uploadInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/webp,video/mp4,video/webm,video/quicktime\"\n style={{ display: \"none\" }}\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n if (file) void acceptUploadedFile(file);\n e.currentTarget.value = \"\";\n }}\n />\n\n <div className=\"lumen-modal-body\">\n {/* ── STEP 1 Capture + STEP 2 Review share one pane so the\n AnnotationLayer stays mounted across Next/Back — going back never\n recaptures or loses the markup (recapture is explicit only). ── */}\n {step === 1 || step === 2 ? (\n <div className=\"lumen-pane\">\n {method === null ? (\n <>\n <div className=\"lumen-fs-top\">\n <div className=\"lumen-fs-toprow lumen-fs-row-corners\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip lumen-fs-x\"\n onClick={closeCapture}\n aria-label=\"Close\"\n >\n ✕\n </button>\n </div>\n </div>\n <div className=\"lumen-fs-center lumen-fs-picker\">\n <div className=\"lumen-fs-picker-head\">\n <div className=\"lumen-fs-picker-title\">\n How do you want to capture?\n </div>\n <div className=\"lumen-fs-picker-sub\">\n Pick a method to report this.\n </div>\n </div>\n <div\n className=\"lumen-method\"\n role=\"group\"\n aria-label=\"Capture method\"\n >\n {METHODS.map((m) => {\n const Icon = METHOD_ICONS[m.value];\n return (\n <button\n key={m.value}\n type=\"button\"\n className={\n \"lumen-method-btn\" +\n (m.primary ? \" lumen-method-primary\" : \"\")\n }\n onClick={() => selectMethod(m.value)}\n disabled={phase.kind === \"capturing\"}\n >\n <span className=\"lumen-method-ico\">\n <Icon />\n </span>\n {m.primary ? (\n <>\n <span className=\"lumen-method-text\">\n <span className=\"lumen-method-label\">\n {m.label}\n </span>\n <span className=\"lumen-method-hint\">\n {m.hint}\n </span>\n </span>\n <span className=\"lumen-method-badge\">Fastest</span>\n </>\n ) : (\n <>\n <span className=\"lumen-method-label\">\n {m.label}\n </span>\n <span className=\"lumen-method-hint\">{m.hint}</span>\n </>\n )}\n </button>\n );\n })}\n </div>\n </div>\n </>\n ) : (\n <>\n {/* Pre-capture states (record prompt · upload picker ·\n capturing) live inside the same fullscreen surround:\n floating ✕ + method pill on top, prompt centered below. */}\n {phase.kind !== \"ready\" ? (\n <>\n <div className=\"lumen-fs-top\">\n <div className=\"lumen-fs-toprow lumen-fs-row-corners\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip lumen-fs-x\"\n onClick={closeCapture}\n aria-label=\"Close\"\n >\n ✕\n </button>\n </div>\n <div className=\"lumen-fs-toprow lumen-fs-row-pill\">\n <div\n className=\"lumen-fs-pill\"\n role=\"group\"\n aria-label=\"Capture method\"\n >\n {METHODS.map((m) => {\n const Icon = METHOD_ICONS[m.value];\n return (\n <button\n key={m.value}\n type=\"button\"\n className=\"lumen-fs-pill-btn\"\n aria-pressed={method === m.value}\n aria-label={m.label}\n onClick={() => selectMethod(m.value)}\n disabled={phase.kind === \"capturing\"}\n >\n <Icon />\n </button>\n );\n })}\n </div>\n </div>\n </div>\n\n <div className=\"lumen-fs-center\">\n {method === \"video\" && phase.kind === \"idle\" ? (\n <RecordPrompt\n canRecord={canRecordScreen}\n onRecord={beginVideoRecording}\n onUpload={() => selectMethod(\"upload\")}\n error={videoError}\n />\n ) : null}\n\n {phase.kind === \"capturing\" ? (\n <p className=\"lumen-status\">\n <span className=\"lumen-spinner\" aria-hidden=\"true\" />\n Capturing…\n </p>\n ) : null}\n\n {phase.kind === \"manual\" ? (\n <div className=\"lumen-manual-capture\">\n <p className=\"lumen-status\">\n {method === \"upload\"\n ? \"Choose an image or video to attach — or paste an image.\"\n : phase.error\n ? \"Automatic capture was unavailable. Upload or paste an image to continue.\"\n : \"Upload or paste an image to continue.\"}\n </p>\n <label className=\"lumen-manual-drop\">\n <span>\n {method === \"upload\"\n ? \"Choose a file — image or video\"\n : \"Choose or paste an image\"}\n </span>\n <input\n type=\"file\"\n accept={\n method === \"upload\"\n ? \"image/png,image/jpeg,image/webp,video/mp4,video/webm,video/quicktime\"\n : \"image/png,image/jpeg,image/webp\"\n }\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n if (file) void acceptUploadedFile(file);\n e.currentTarget.value = \"\";\n }}\n />\n </label>\n </div>\n ) : null}\n </div>\n </>\n ) : null}\n\n {phase.kind === \"ready\" ? (\n <>\n {/* markup-only chrome (hidden once we're on the review step) */}\n {step === 1 ? (\n <>\n <div className=\"lumen-fs-top\">\n <div className=\"lumen-fs-toprow lumen-fs-row-corners\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip lumen-fs-x\"\n onClick={closeCapture}\n aria-label=\"Close\"\n >\n ✕\n </button>\n <div className=\"lumen-fs-recap\">\n <button\n type=\"button\"\n className=\"lumen-fs-chip\"\n onClick={() => setRecapMenuOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={recapMenuOpen}\n >\n <IconRefresh /> Recapture\n <svg\n width=\"11\"\n height=\"11\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ opacity: 0.6 }}\n aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </button>\n {recapMenuOpen ? (\n <>\n <div\n className=\"lumen-fs-recap-overlay\"\n onClick={() => setRecapMenuOpen(false)}\n />\n <div className=\"lumen-fs-recap-menu\" role=\"menu\">\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => {\n setRecapMenuOpen(false);\n if (method) selectMethod(method);\n }}\n >\n <span className=\"lumen-fs-mi-ic\">\n <IconRefresh />\n </span>\n <span>\n <b>Re-snap this view</b>\n <small>Instant · masks sensitive fields</small>\n </span>\n </button>\n {showExactCapture ? (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => {\n setRecapMenuOpen(false);\n void startScreenCaptureSession();\n }}\n >\n <span className=\"lumen-fs-mi-ic\">\n <IconMonitor />\n </span>\n <span>\n <b>Capture exact pixels</b>\n <small>\n Real screen — canvas, video & charts\n </small>\n </span>\n </button>\n ) : null}\n </div>\n </>\n ) : null}\n </div>\n </div>\n <div className=\"lumen-fs-toprow lumen-fs-row-pill\">\n <div\n className=\"lumen-fs-pill\"\n role=\"group\"\n aria-label=\"Tools and capture method\"\n >\n {!isVideoMethod ? (\n <>\n <button\n type=\"button\"\n className=\"lumen-fs-pill-btn lumen-fs-pentog\"\n data-on={!toolsHidden}\n onClick={() => setToolsHidden((h) => !h)}\n aria-label=\"Toggle markup tools\"\n title=\"Toggle markup tools\"\n >\n <IconDraw />\n </button>\n <span className=\"lumen-fs-pill-sep\" />\n </>\n ) : null}\n {METHODS.map((m) => {\n const Icon = METHOD_ICONS[m.value];\n return (\n <button\n key={m.value}\n type=\"button\"\n className=\"lumen-fs-pill-btn\"\n aria-pressed={method === m.value}\n aria-label={m.label}\n onClick={() => selectMethod(m.value)}\n >\n <Icon />\n </button>\n );\n })}\n </div>\n </div>\n </div>\n {!isVideoMethod && !toolsHidden ? (\n <div className=\"lumen-toolbar\">\n <div\n className=\"lumen-segmented\"\n role=\"group\"\n aria-label=\"Annotation tool\"\n >\n <ToolButton\n label=\"Arrow\"\n icon={<IconArrow />}\n active={tool === \"arrow\"}\n onClick={() => setTool(\"arrow\")}\n />\n <ToolButton\n label=\"Box\"\n icon={<IconBox />}\n active={tool === \"rect\"}\n onClick={() => setTool(\"rect\")}\n />\n <ToolButton\n label=\"Draw\"\n icon={<IconDraw />}\n active={tool === \"freehand\"}\n onClick={() => setTool(\"freehand\")}\n />\n <ToolButton\n label=\"Comment\"\n icon={<IconComment />}\n active={tool === \"comment\"}\n onClick={() => setTool(\"comment\")}\n />\n </div>\n <span className=\"lumen-toolbar-sep\" />\n <div className=\"lumen-fs-color\">\n <button\n type=\"button\"\n className=\"lumen-fs-color-btn\"\n style={{ background: strokeColor }}\n aria-label=\"Pick colour\"\n aria-haspopup=\"true\"\n aria-expanded={colorPickerOpen}\n onClick={() => setColorPickerOpen((o) => !o)}\n />\n {colorPickerOpen ? (\n <>\n <div\n className=\"lumen-fs-color-overlay\"\n onClick={() => setColorPickerOpen(false)}\n />\n <div\n className=\"lumen-fs-color-pop\"\n role=\"group\"\n aria-label=\"Colour\"\n >\n {SWATCHES.map((s) => (\n <button\n key={s.value}\n type=\"button\"\n className=\"lumen-swatch\"\n style={{ background: s.value }}\n aria-label={s.label}\n aria-pressed={strokeColor === s.value}\n onClick={() => {\n setStrokeColor(s.value);\n setColorPickerOpen(false);\n }}\n />\n ))}\n </div>\n </>\n ) : null}\n </div>\n {!captureFullscreen ? (\n <div\n className=\"lumen-stroke-sizes\"\n role=\"group\"\n aria-label=\"Stroke width\"\n >\n {STROKE_SIZES.map((s) => (\n <button\n key={s.value}\n type=\"button\"\n className=\"lumen-stroke-size\"\n aria-label={s.label}\n aria-pressed={strokeWidth === s.value}\n onClick={() => setStrokeWidth(s.value)}\n >\n <span\n className=\"lumen-stroke-size-dot\"\n style={{ width: s.dot, height: s.dot }}\n />\n </button>\n ))}\n </div>\n ) : null}\n {!captureFullscreen ? (\n <span className=\"lumen-toolbar-spacer\" />\n ) : null}\n <button\n type=\"button\"\n className=\"lumen-tool\"\n onClick={() => annotationRef.current?.undo()}\n disabled={!history.canUndo}\n aria-label=\"Undo\"\n title=\"Undo\"\n >\n <IconUndo />\n </button>\n <button\n type=\"button\"\n className=\"lumen-tool\"\n onClick={() => annotationRef.current?.redo()}\n disabled={!history.canRedo}\n aria-label=\"Redo\"\n title=\"Redo\"\n >\n <IconRedo />\n </button>\n <button\n type=\"button\"\n className=\"lumen-tool\"\n onClick={() => annotationRef.current?.reset()}\n disabled={!history.canUndo}\n aria-label=\"Clear\"\n title=\"Clear\"\n >\n <IconTrash />\n </button>\n </div>\n ) : null}\n </>\n ) : null}\n\n <div className=\"lumen-annotate\">\n <AnnotationLayer\n ref={annotationRef}\n screenshot={phase.capture.blob}\n tool={tool}\n color={strokeColor}\n strokeWidth={strokeWidth}\n onDrawingChange={setDrawing}\n onHistoryChange={setHistory}\n />\n </div>\n\n {step === 1 ? (\n <>\n <div className=\"lumen-cap-actions\">\n <button\n type=\"button\"\n className=\"lumen-btn-ghost\"\n onClick={() => method && selectMethod(method)}\n >\n {isVideoMethod ? \"↻ Re-record\" : \"↻ Recapture\"}\n </button>\n {showExactCapture ? (\n <button\n type=\"button\"\n className=\"lumen-btn-ghost lumen-exact-btn\"\n onClick={() => void startScreenCaptureSession()}\n title=\"Capture the real screen pixels — your browser will ask which tab or window to share, then you arrange the page and press Capture.\"\n >\n <IconMonitor /> Capture exact screen\n </button>\n ) : null}\n {isVideoMethod ? (\n video ? (\n <span className=\"lumen-cap-note\">\n ✓ {Math.round(video.durationMs / 1000)}s recorded\n </span>\n ) : null\n ) : (\n <span className=\"lumen-cap-note\">\n {phase.capture.method === \"web-display-media\"\n ? \"Exact screen captured\"\n : `${captureLabel(method)} captured · switch method above anytime`}\n </span>\n )}\n </div>\n\n <div className=\"lumen-fs-compose\">\n <button\n type=\"button\"\n className=\"lumen-fs-grab\"\n onClick={() => setSheetCollapsed((c) => !c)}\n aria-label={\n sheetCollapsed ? \"Expand sheet\" : \"Minimize sheet\"\n }\n />\n <div className=\"lumen-fs-field\">\n <input\n className=\"lumen-input lumen-fs-desc\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"Describe what's wrong — or use voice\"\n />\n <button\n type=\"button\"\n className=\"lumen-fs-mic\"\n onClick={startRecording}\n aria-label=\"Record voice note\"\n >\n <IconMic />\n </button>\n </div>\n {renderVoiceNote(\"capture\")}\n <button\n type=\"button\"\n className=\"lumen-btn-primary lumen-fs-next\"\n onClick={goNext}\n disabled={nextDisabled}\n >\n Next\n </button>\n </div>\n </>\n ) : null}\n </>\n ) : null}\n </>\n )}\n </div>\n ) : null}\n\n {/* ── STEP 2 — Review & send (detent over the dimmed capture) ── */}\n {step === 2 ? (\n <div className=\"lumen-pane lumen-rv-pane\">\n {/* the dimmed capture behind is the still-mounted AnnotationLayer\n from the shared pane — showing live strokes, not a snapshot */}\n <div className=\"lumen-rv-scrim\" aria-hidden=\"true\" />\n\n <div className=\"lumen-rv\">\n <div className=\"lumen-rv-head\">\n <button\n type=\"button\"\n className=\"lumen-rv-back\"\n onClick={goBack}\n >\n <IconChevronLeft />\n Back\n </button>\n <span className=\"lumen-rv-title\">Review & send</span>\n <span className=\"lumen-rv-spacer\" aria-hidden=\"true\" />\n </div>\n\n <div className=\"lumen-rv-rows\">\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">\n Description{\" \"}\n <span className=\"lumen-rv-muted\">· tap to edit</span>\n </span>\n <textarea\n className=\"lumen-input lumen-rv-desc\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n rows={2}\n placeholder=\"Describe what's wrong…\"\n />\n </div>\n\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">Type</span>\n <div\n className=\"lumen-rv-chips\"\n role=\"group\"\n aria-label=\"Type\"\n >\n {CATEGORIES.map((c) => (\n <button\n key={c.value}\n type=\"button\"\n className=\"lumen-rv-chip\"\n aria-pressed={category === c.value}\n onClick={() => setCategory(c.value)}\n >\n {c.label}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">Priority</span>\n <div\n className=\"lumen-rv-prio\"\n role=\"group\"\n aria-label=\"Priority\"\n >\n {PRIORITIES.filter(\n (p): p is { value: FeedbackPriority; label: string } =>\n p.value !== \"\",\n ).map((p) => (\n <button\n key={p.value}\n type=\"button\"\n className=\"lumen-rv-prio-opt\"\n aria-pressed={priority === p.value}\n onClick={() =>\n setPriority(priority === p.value ? \"\" : p.value)\n }\n >\n <PriorityIcon value={p.value} />\n {p.label}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"lumen-rv-set\">\n <span className=\"lumen-rv-k\">\n Platform{\" \"}\n <span className=\"lumen-rv-muted\">\n · auto-detected — change if wrong\n </span>\n </span>\n <div\n className=\"lumen-rv-chips\"\n role=\"group\"\n aria-label=\"Platform\"\n >\n {SOURCE_CHIPS.map((s) => (\n <button\n key={s.value}\n type=\"button\"\n className=\"lumen-rv-chip\"\n aria-pressed={source === s.value}\n onClick={() => setSource(s.value)}\n >\n {s.label}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"lumen-rv-row\">\n <span className=\"lumen-rv-rk\">Capture</span>\n <span className=\"lumen-rv-rv\">\n {captureLabel(method)}\n {history.canUndo ? \" · annotated\" : \"\"}\n <button\n type=\"button\"\n className=\"lumen-edit\"\n onClick={() => setStep(1)}\n >\n edit\n </button>\n </span>\n </div>\n\n {renderVoiceNote(\"describe\")}\n\n <div className=\"lumen-rv-attachrow\">\n {video ? (\n <span className=\"lumen-attach\">\n ▶ Video {Math.round(video.durationMs / 1000)}s\n <button\n type=\"button\"\n className=\"lumen-att-x\"\n aria-label=\"Remove video\"\n onClick={discardVideo}\n >\n ×\n </button>\n </span>\n ) : (\n <label className=\"lumen-rv-attach\">\n <IconUpload />\n Attach a video\n <input\n type=\"file\"\n accept=\"video/mp4,video/webm,video/quicktime\"\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n if (file)\n setVideo({ blob: file, durationMs: 0 });\n e.currentTarget.value = \"\";\n }}\n />\n </label>\n )}\n </div>\n </div>\n\n <button\n type=\"button\"\n className=\"lumen-btn-primary lumen-rv-send\"\n onClick={submit}\n disabled={submitting}\n >\n {submitting ? (\n uploadingPct < 95 ? (\n `Uploading ${uploadingPct}%…`\n ) : (\n \"Almost done…\"\n )\n ) : (\n <>\n <IconSend />\n Send feedback\n </>\n )}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n\n <footer className=\"lumen-modal-footer\">\n {submitting ? (\n <div\n className=\"lumen-progress\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={uploadingPct}\n >\n <div\n className=\"lumen-progress-fill\"\n style={{ width: `${uploadingPct}%` }}\n />\n </div>\n ) : null}\n <div className=\"lumen-modal-actions\">\n <button\n type=\"button\"\n onClick={step === 1 ? closeCapture : goBack}\n className=\"lumen-btn-ghost\"\n disabled={submitting}\n >\n {step === 1 ? \"Cancel\" : \"Back\"}\n </button>\n <button\n type=\"button\"\n onClick={goNext}\n className=\"lumen-btn-primary\"\n disabled={nextDisabled}\n >\n {nextLabel}\n </button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n\nfunction captureLabel(method: CaptureMethod | null): string {\n if (method === \"video\") return \"Screen recording\";\n if (method === \"upload\") return \"Upload\";\n return \"Screenshot\";\n}\n\nfunction Stepper({ step }: { step: Step }) {\n const steps = [\n { n: 1, label: \"Capture\" },\n { n: 2, label: \"Describe\" },\n { n: 3, label: \"Review\" },\n ] as const;\n return (\n <div className=\"lumen-stepper\" aria-hidden=\"true\">\n {steps.map((s, i) => (\n <div\n key={s.n}\n className={\n \"lumen-step\" +\n (step === s.n ? \" lumen-step-active\" : \"\") +\n (step > s.n ? \" lumen-step-done\" : \"\")\n }\n >\n <span className=\"lumen-step-num\">{s.n}</span>\n <span className=\"lumen-step-lbl\">{s.label}</span>\n {i < steps.length - 1 ? <span className=\"lumen-step-bar\" /> : null}\n </div>\n ))}\n </div>\n );\n}\n\nfunction RecordPrompt({\n canRecord,\n onRecord,\n onUpload,\n error,\n}: {\n canRecord: boolean;\n onRecord: () => void;\n onUpload: () => void;\n error?: string | null;\n}) {\n if (!canRecord) {\n return (\n <div className=\"lumen-record-prompt\">\n <p className=\"lumen-record-unavailable\">\n {isIOSBrowser() ? (\n <>\n Screen recording isn’t available on iOS browsers. Record with\n Control Center’s screen recorder, then attach the clip below.\n </>\n ) : (\n <>\n Screen recording isn’t available in this browser. Upload a video\n to attach one instead.\n </>\n )}\n </p>\n <button\n type=\"button\"\n className=\"lumen-btn-primary lumen-record-upload\"\n onClick={onUpload}\n >\n Upload a video\n </button>\n </div>\n );\n }\n return (\n <div className=\"lumen-record-prompt\">\n {error ? (\n <p className=\"lumen-record-unavailable\" role=\"alert\">\n {error} Try again, or switch to <strong>Upload</strong> to attach a\n video instead.\n </p>\n ) : null}\n <button\n type=\"button\"\n className=\"lumen-record-btn\"\n aria-label=\"Start screen recording\"\n onClick={onRecord}\n />\n <div className=\"lumen-record-copy\">\n <div className=\"lumen-record-title\">Record your screen</div>\n <div className=\"lumen-record-sub\">\n Tap to start. The sheet closes so you can record freely — a Stop\n button stays on screen, then the sheet returns with your clip. Max\n 60s.\n </div>\n </div>\n </div>\n );\n}\n\n/** Best-effort iOS detection for the actionable \"no screen recording\" copy.\n * Covers iPhone/iPad (incl. iPadOS reporting as Macintosh with touch). */\nfunction isIOSBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n const ua = navigator.userAgent || \"\";\n if (/iPad|iPhone|iPod/.test(ua)) return true;\n return (\n /Macintosh/.test(ua) &&\n typeof document !== \"undefined\" &&\n \"ontouchend\" in document\n );\n}\n\nfunction ToolButton({\n label,\n active,\n onClick,\n icon,\n}: {\n label: string;\n active: boolean;\n onClick: () => void;\n icon?: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"lumen-tool\"\n aria-pressed={active}\n aria-label={icon ? label : undefined}\n title={label}\n >\n {icon ?? label}\n </button>\n );\n}\n\n/** Mobile sheet drag-to-dismiss handle. Hidden on ≥ 640px via CSS. */\nfunction SheetGrabber({ onDismiss }: { onDismiss: () => void }) {\n const startYRef = useRef<number | null>(null);\n const startTimeRef = useRef<number>(0);\n const targetRef = useRef<HTMLElement | null>(null);\n\n function onPointerDown(e: React.PointerEvent<HTMLDivElement>) {\n e.currentTarget.setPointerCapture(e.pointerId);\n startYRef.current = e.clientY;\n startTimeRef.current = performance.now();\n targetRef.current = e.currentTarget.parentElement;\n }\n function onPointerMove(e: React.PointerEvent<HTMLDivElement>) {\n if (startYRef.current == null || !targetRef.current) return;\n const dy = Math.max(0, e.clientY - startYRef.current);\n targetRef.current.style.transform = `translateY(${dy}px)`;\n }\n function onPointerUp(e: React.PointerEvent<HTMLDivElement>) {\n if (startYRef.current == null || !targetRef.current) return;\n const dy = Math.max(0, e.clientY - startYRef.current);\n const dt = Math.max(1, performance.now() - startTimeRef.current);\n const velocity = dy / dt;\n targetRef.current.style.transform = \"\";\n targetRef.current.style.transition = \"\";\n startYRef.current = null;\n if (dy > 80 || velocity > 0.6) onDismiss();\n }\n\n return (\n <div\n className=\"lumen-modal-grabber\"\n aria-hidden=\"true\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n />\n );\n}\n\n/** Live mic level visualisation. Reads time-domain samples from the\n * recorder stream and renders a centred series of rounded bars that\n * ease toward each new amplitude. AudioContext + AnalyserNode are torn\n * down on unmount so the mic isn't held open by a stale graph. */\nfunction Waveform({ stream }: { stream: MediaStream }) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n const cssWidth = canvas.clientWidth || 88;\n const cssHeight = canvas.clientHeight || 22;\n canvas.width = Math.round(cssWidth * dpr);\n canvas.height = Math.round(cssHeight * dpr);\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.scale(dpr, dpr);\n\n const AudioCtor: typeof AudioContext | undefined =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext?: typeof AudioContext })\n .webkitAudioContext;\n if (!AudioCtor) return;\n const audioCtx = new AudioCtor();\n const source = audioCtx.createMediaStreamSource(stream);\n const analyser = audioCtx.createAnalyser();\n analyser.fftSize = 1024;\n analyser.smoothingTimeConstant = 0.6;\n source.connect(analyser);\n const data = new Uint8Array(analyser.fftSize);\n\n const BARS = 18;\n const GAP = 3;\n const MIN_H = 3;\n const barW = Math.max(2, (cssWidth - GAP * (BARS - 1)) / BARS);\n const radius = Math.min(barW / 2, 3);\n const levels = new Array<number>(BARS).fill(0);\n\n let raf = 0;\n let cancelled = false;\n function frame() {\n if (cancelled) return;\n analyser.getByteTimeDomainData(data);\n const bucketSize = Math.floor(data.length / BARS);\n ctx!.clearRect(0, 0, cssWidth, cssHeight);\n ctx!.fillStyle = getCssVar(\"--lumen-danger\") || \"rgb(239,68,68)\";\n for (let i = 0; i < BARS; i++) {\n let peak = 0;\n for (let j = 0; j < bucketSize; j++) {\n const v = Math.abs((data[i * bucketSize + j] ?? 128) - 128);\n if (v > peak) peak = v;\n }\n const target = Math.min(1, (peak / 128) * 1.8);\n const cur = levels[i] ?? 0;\n levels[i] = target > cur ? target : cur + (target - cur) * 0.35;\n const h = Math.max(MIN_H, levels[i]! * cssHeight);\n const x = i * (barW + GAP);\n const y = (cssHeight - h) / 2;\n roundRectPath(ctx!, x, y, barW, h, radius);\n ctx!.fill();\n }\n raf = requestAnimationFrame(frame);\n }\n raf = requestAnimationFrame(frame);\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(raf);\n try {\n source.disconnect();\n } catch {\n /* ignore */\n }\n void audioCtx.close();\n };\n }, [stream]);\n\n return <canvas ref={canvasRef} className=\"lumen-waveform\" aria-hidden=\"true\" />;\n}\n\n/** Trace a rounded-rect path. Uses native `roundRect` when present and\n * falls back to manual arcs for older Safari/Firefox. */\nfunction roundRectPath(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): void {\n const radius = Math.min(r, w / 2, h / 2);\n ctx.beginPath();\n const anyCtx = ctx as CanvasRenderingContext2D & {\n roundRect?: (x: number, y: number, w: number, h: number, r: number) => void;\n };\n if (typeof anyCtx.roundRect === \"function\") {\n anyCtx.roundRect(x, y, w, h, radius);\n return;\n }\n ctx.moveTo(x + radius, y);\n ctx.arcTo(x + w, y, x + w, y + h, radius);\n ctx.arcTo(x + w, y + h, x, y + h, radius);\n ctx.arcTo(x, y + h, x, y, radius);\n ctx.arcTo(x, y, x + w, y, radius);\n ctx.closePath();\n}\n\n/** Preview the recorded clip with a native <audio> element. ObjectURL is\n * revoked on unmount/swap to avoid leaking the blob into memory. */\nfunction AudioPreview({ blob, durationMs }: { blob: Blob; durationMs: number }) {\n const [url, setUrl] = useState<string>(\"\");\n useEffect(() => {\n const u = URL.createObjectURL(blob);\n setUrl(u);\n return () => {\n URL.revokeObjectURL(u);\n };\n }, [blob]);\n return (\n <div className=\"lumen-audio-preview\">\n <audio controls preload=\"metadata\" src={url} className=\"lumen-audio-el\" />\n <span className=\"lumen-audio-meta\">{Math.round(durationMs / 1000)}s</span>\n </div>\n );\n}\n\nfunction getCssVar(name: string): string {\n if (typeof window === \"undefined\") return \"\";\n return getComputedStyle(document.documentElement)\n .getPropertyValue(name)\n .trim();\n}\n\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(\n root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((el) => !el.hasAttribute(\"disabled\") && el.offsetParent !== null);\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\n\ninterface LumenErrorBoundaryProps {\n /**\n * Called once after the boundary catches an error. The provider uses this to\n * return to a clean, reopenable state (close the sheet + remount this\n * boundary via a fresh key) so a single crash never strands the widget.\n */\n onReset: () => void;\n /**\n * Best-effort crash telemetry. Called with the caught error + React\n * component stack so the provider can beacon it to the dashboard — this is\n * how we learn WHY the widget \"hit a snag\" in production. Purely additive;\n * recovery does not depend on it.\n */\n onError?: (report: {\n message: string;\n name: string;\n stack?: string;\n componentStack?: string;\n }) => void;\n children: React.ReactNode;\n}\n\ninterface LumenErrorBoundaryState {\n hasError: boolean;\n}\n\n/**\n * Wraps Lumen's own UI (triggers, capture sheet, recording HUD) so a render or\n * commit error inside the widget can never unmount the HOST app's React tree —\n * which is exactly what produced the iOS \"white screen\": an uncaught throw from\n * the capture path (e.g. an out-of-memory failure when html2canvas runs twice\n * in quick succession) bubbling past Lumen into the host with no boundary to\n * stop it.\n *\n * On catch it renders nothing, runs the cleanup the now-unmounted sheet can no\n * longer do (release the body scroll-lock + `data-lumen-open` flag), surfaces an\n * apology toast, and asks the provider to reset so the user can try again.\n */\nexport class LumenErrorBoundary extends React.Component<\n LumenErrorBoundaryProps,\n LumenErrorBoundaryState\n> {\n override state: LumenErrorBoundaryState = { hasError: false };\n\n static getDerivedStateFromError(): LumenErrorBoundaryState {\n return { hasError: true };\n }\n\n override componentDidCatch(error: unknown, info: React.ErrorInfo): void {\n // The CaptureModal sets these on document.documentElement / body while open\n // and restores them in effect cleanups. When the modal unmounts via a throw,\n // those cleanups still run — but if the error came from elsewhere in the\n // subtree we clear them defensively so the page can never be left\n // unscrollable or flagged open.\n if (typeof document !== \"undefined\") {\n const html = document.documentElement;\n html.style.overflow = \"\";\n html.style.paddingRight = \"\";\n document.body.removeAttribute(\"data-lumen-open\");\n }\n\n // eslint-disable-next-line no-console\n console.error(\"[lumen] recovered from a widget error:\", error);\n toast.error(\"Feedback widget hit a snag and was reset. Please try again.\");\n\n // Best-effort telemetry: report the real exception + component stack so we\n // can see (not guess) why the widget crashes in production. Wrapped so a\n // telemetry hiccup can never break the recovery below.\n try {\n const err = error instanceof Error ? error : null;\n this.props.onError?.({\n message: err?.message ?? String(error),\n name: err?.name ?? \"Error\",\n stack: err?.stack,\n componentStack: info?.componentStack ?? undefined,\n });\n } catch {\n // ignore\n }\n\n // Reset on a microtask so this commit-phase handler finishes first; the\n // provider closes the sheet and remounts this boundary with a fresh key.\n Promise.resolve().then(() => this.props.onReset());\n }\n\n override render(): React.ReactNode {\n if (this.state.hasError) return null;\n return this.props.children;\n }\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { VideoRecordingState } from \"./context\";\n\n/**\n * Floating recording control that persists while the sheet is closed during a\n * screen recording. Portaled to the body (outside the sheet) so it survives\n * the modal being unmounted. Stop returns the sheet with the clip attached;\n * the timer counts toward the max-duration cap.\n *\n * Note: on web, getDisplayMedia records the visible screen/tab, so this HUD\n * may appear in the recording when the user shares the same tab. That's an\n * inherent browser limitation — the alternative is the browser's own \"Stop\n * sharing\" bar, which also funnels through to reopen the sheet.\n *\n * The `starting`/`processing` phases only occur on the custom/native\n * `record.provider` path (consent window before the clip starts; encode +\n * transfer window after Stop). The browser path only ever renders `recording`.\n */\nexport function RecordingHud({\n state,\n portalTarget,\n onStop,\n onCancel,\n}: {\n state: VideoRecordingState;\n portalTarget?: HTMLElement;\n onStop: () => void;\n onCancel: () => void;\n}) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (!mounted || typeof document === \"undefined\") return null;\n\n const target = portalTarget ?? document.body;\n\n if (state.phase === \"recording\") {\n return createPortal(\n <RecordingControl\n startedAt={state.startedAt}\n maxSeconds={state.maxSeconds}\n onStop={onStop}\n onCancel={onCancel}\n />,\n target,\n );\n }\n\n // Provider-only transient phases: a compact status pill with no timer. During\n // `starting` the native consent dialog is on screen; during `processing` the\n // clip is encoding/transferring. Discard stays available so the user is never\n // trapped if a native step hangs.\n return createPortal(\n <div\n className=\"lumen-rec-hud lumen-rec-hud-pending\"\n role=\"status\"\n aria-live=\"polite\"\n data-lumen-root=\"true\"\n data-lumen-capture-ignore=\"true\"\n >\n <span className=\"lumen-rec-hud-spinner\" aria-hidden=\"true\" />\n <span className=\"lumen-rec-hud-time\">\n {state.phase === \"starting\" ? \"Starting…\" : \"Processing…\"}\n </span>\n <button\n type=\"button\"\n className=\"lumen-rec-hud-cancel\"\n onClick={onCancel}\n aria-label=\"Discard recording\"\n >\n Discard\n </button>\n </div>,\n target,\n );\n}\n\n/** The live-recording control — markup unchanged from the original HUD so the\n * browser recording experience is byte-identical. */\nfunction RecordingControl({\n startedAt,\n maxSeconds,\n onStop,\n onCancel,\n}: {\n startedAt: number;\n maxSeconds: number;\n onStop: () => void;\n onCancel: () => void;\n}) {\n const [elapsed, setElapsed] = useState(0);\n\n useEffect(() => {\n const tick = () =>\n setElapsed(\n Math.min(maxSeconds, Math.max(0, Math.floor((Date.now() - startedAt) / 1000))),\n );\n tick();\n const id = window.setInterval(tick, 250);\n return () => window.clearInterval(id);\n }, [startedAt, maxSeconds]);\n\n const fmt = (s: number) =>\n `${Math.floor(s / 60)}:${String(s % 60).padStart(2, \"0\")}`;\n\n return (\n <div\n className=\"lumen-rec-hud\"\n role=\"status\"\n aria-live=\"polite\"\n data-lumen-root=\"true\"\n data-lumen-capture-ignore=\"true\"\n >\n <span className=\"lumen-rec-hud-dot\" aria-hidden=\"true\" />\n <span className=\"lumen-rec-hud-time\">\n {fmt(elapsed)} <span className=\"lumen-rec-hud-max\">/ {fmt(maxSeconds)}</span>\n </span>\n <button\n type=\"button\"\n className=\"lumen-rec-hud-cancel\"\n onClick={onCancel}\n aria-label=\"Discard recording\"\n >\n Discard\n </button>\n <button\n type=\"button\"\n className=\"lumen-rec-hud-stop\"\n onClick={onStop}\n aria-label=\"Stop recording and return to feedback\"\n >\n <span className=\"lumen-rec-hud-square\" aria-hidden=\"true\" />\n Stop\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { ScreenCaptureState } from \"./context\";\nimport { IconMonitor } from \"./icons\";\n\n/**\n * Floating control for \"Capture exact screen\". After the browser surface picker\n * resolves, the Send-feedback sheet hides and this bar takes over: the user can\n * scroll/arrange the live page, then press Capture to grab the exact pixels.\n *\n * Portaled to the body (outside the sheet) and tagged `data-lumen-root` +\n * `data-lumen-capture-ignore` so the core capture conceals it — along with the\n * rest of Lumen's chrome — at the moment the frame is drawn. That's why the bar\n * itself never ends up in the screenshot, even though the grab records real\n * screen pixels (which the DOM ignore-attribute alone can't exclude).\n */\nexport function ScreenCaptureHud({\n state,\n portalTarget,\n onCapture,\n onCancel,\n}: {\n state: ScreenCaptureState;\n portalTarget?: HTMLElement;\n onCapture: () => void;\n onCancel: () => void;\n}) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => setMounted(true), []);\n\n if (!mounted || typeof document === \"undefined\") return null;\n\n const target = portalTarget ?? document.body;\n const grabbing = state.phase === \"grabbing\";\n\n return createPortal(\n <div\n className=\"lumen-cap-hud\"\n role=\"status\"\n aria-live=\"polite\"\n data-lumen-root=\"true\"\n data-lumen-capture-ignore=\"true\"\n >\n {grabbing ? (\n <span className=\"lumen-cap-hud-spinner\" aria-hidden=\"true\" />\n ) : (\n <span className=\"lumen-cap-hud-ico\" aria-hidden=\"true\">\n <IconMonitor />\n </span>\n )}\n <span className=\"lumen-cap-hud-text\">\n {grabbing ? \"Capturing…\" : \"Arrange the screen, then capture\"}\n </span>\n <button\n type=\"button\"\n className=\"lumen-cap-hud-cancel\"\n onClick={onCancel}\n disabled={grabbing}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"lumen-cap-hud-capture\"\n onClick={onCapture}\n disabled={grabbing}\n aria-label=\"Capture this screen and return to feedback\"\n >\n Capture\n </button>\n </div>,\n target,\n );\n}\n","/**\n * Pure capability resolution for the Record tab. Kept framework-free so it can\n * be unit-tested without a DOM. Mirrors the precedence rules in the SDK spec:\n *\n * - The Record tab is usable when\n * (a record provider is set AND its `isAvailable()` did not return false)\n * OR `getDisplayMedia` exists.\n * - A set, available provider takes precedence over `getDisplayMedia`.\n * - `isAvailable` defaults to \"available\" when omitted, so a not-yet-probed\n * provider (`providerAvailable === null`) is treated as available.\n */\nexport interface RecordCapabilityInput {\n /** Whether a `record.provider` was supplied to <LumenProvider>. */\n hasProvider: boolean;\n /**\n * Result of `record.isAvailable?.()`. `null` means \"not probed / omitted\" —\n * which defaults to available when a provider is set.\n */\n providerAvailable: boolean | null;\n /** Whether `navigator.mediaDevices.getDisplayMedia` exists. */\n hasGetDisplayMedia: boolean;\n}\n\nexport interface RecordCapability {\n /** Whether the Record tab should be offered at all. */\n canRecord: boolean;\n /**\n * Which path a record attempt should take. `true` → call `record.provider`;\n * `false` → use the browser `getDisplayMedia` recorder.\n */\n usingProvider: boolean;\n}\n\nexport function resolveRecordCapability(\n input: RecordCapabilityInput,\n): RecordCapability {\n const providerUsable = input.hasProvider && input.providerAvailable !== false;\n return {\n canRecord: providerUsable || input.hasGetDisplayMedia,\n usingProvider: providerUsable,\n };\n}\n","import {\n type LumenRecordProvider,\n type LumenRecordingResult,\n type LumenRecordingSession,\n} from \"@lumen-stack/core\";\n\n/**\n * Framework-free orchestrator for a custom/native record provider. All of the\n * lifecycle branching lives here (start window, cancel-during-start, manual\n * stop vs. provider auto-stop, RECORDER_STOPPED swallowing) so the React glue\n * can be nothing but `setState`, and so the behavior is unit-testable without a\n * DOM.\n *\n * Lifecycle → callback mapping:\n * onStarting — provider invoked, awaiting the session (native consent window)\n * onActive — session is live (stream may be null for native hosts)\n * onProcessing— manual stop requested, awaiting the encoded clip\n * onResult — clip arrived (manual stop OR provider auto-stop at the cap)\n * onCancelled — cancelled at start or mid-recording (RECORDER_STOPPED swallowed)\n * onError — provider failed to start, or the clip failed to arrive\n *\n * Exactly one terminal callback (onResult | onCancelled | onError) fires.\n */\nexport interface RecordSessionCallbacks {\n onStarting(): void;\n onActive(session: LumenRecordingSession): void;\n onProcessing(): void;\n onResult(result: LumenRecordingResult): void;\n onCancelled(): void;\n onError(error: Error): void;\n}\n\nexport interface RecordSessionControl {\n /** Stop and keep the clip; it arrives via onResult after onProcessing. */\n stop(): void;\n /** Abort and discard; resolves to onCancelled. */\n cancel(): void;\n}\n\nfunction isRecorderStopped(err: unknown): boolean {\n return (\n typeof err === \"object\" &&\n err !== null &&\n (err as { code?: unknown }).code === \"RECORDER_STOPPED\"\n );\n}\n\nfunction asError(err: unknown): Error {\n return err instanceof Error ? err : new Error(String(err));\n}\n\nexport function driveRecordSession(\n provider: LumenRecordProvider,\n options: { maxDurationSeconds: number },\n cb: RecordSessionCallbacks,\n): RecordSessionControl {\n let cancelled = false;\n let settled = false; // a terminal callback has fired\n let stopRequested = false;\n let session: LumenRecordingSession | null = null;\n\n function finishCancelled() {\n if (settled) return;\n settled = true;\n cb.onCancelled();\n }\n function finishResult(result: LumenRecordingResult) {\n if (settled) return;\n settled = true;\n cb.onResult(result);\n }\n function finishError(error: Error) {\n if (settled) return;\n settled = true;\n cb.onError(error);\n }\n\n cb.onStarting();\n\n Promise.resolve()\n .then(() => provider(options))\n .then((s) => {\n session = s;\n if (cancelled) {\n // Cancelled during the start window — abort the freshly-made session.\n try {\n s.cancel();\n } catch {\n /* ignore */\n }\n finishCancelled();\n return;\n }\n cb.onActive(s);\n // Honor a stop that landed before the session resolved (rare).\n if (stopRequested) {\n cb.onProcessing();\n try {\n s.stop();\n } catch {\n /* ignore */\n }\n }\n // Single funnel: manual stop, provider auto-stop at the cap, and cancel\n // all arrive here. A RECORDER_STOPPED rejection is a cancel, not an error.\n Promise.resolve(s.result)\n .then((result) => {\n if (cancelled) finishCancelled();\n else finishResult(result);\n })\n .catch((err) => {\n if (cancelled || isRecorderStopped(err)) finishCancelled();\n else finishError(asError(err));\n });\n })\n .catch((err) => {\n // Provider threw/rejected at start.\n if (cancelled || isRecorderStopped(err)) finishCancelled();\n else finishError(asError(err));\n });\n\n return {\n stop() {\n if (settled || cancelled || stopRequested) return;\n stopRequested = true;\n if (session) {\n cb.onProcessing();\n try {\n session.stop();\n } catch {\n /* ignore */\n }\n }\n // If still starting, the start funnel applies stopRequested on resolve.\n },\n cancel() {\n if (settled && cancelled) return;\n cancelled = true;\n if (session) {\n try {\n session.cancel();\n } catch {\n /* ignore */\n }\n }\n // Idempotent via `settled`; the session.result rejection that follows a\n // provider cancel() is a no-op once we've already finished here.\n finishCancelled();\n },\n };\n}\n","/**\n * Heuristic floor detector. Returns the height (px) of the tallest\n * full-width fixed element anchored near the bottom of the viewport\n * (e.g. a tab bar). 0 if nothing matches.\n *\n * Cheap by design: probes `elementsFromPoint` at three x positions,\n * walks up parents, dedupes. O(small constant) — the spec's literal\n * `querySelectorAll('*')` would be O(DOM) per measurement.\n */\nexport function detectBottomFloor(): number {\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n return 0;\n }\n const w = window.innerWidth;\n const h = window.innerHeight;\n if (w === 0 || h === 0) return 0;\n\n const probeY = h - 4;\n const probeXs = [Math.round(w * 0.1), Math.round(w * 0.5), Math.round(w * 0.9)];\n const seen = new Set<Element>();\n let tallest = 0;\n\n for (const x of probeXs) {\n const stack = document.elementsFromPoint(x, probeY);\n for (const el of stack) {\n if (seen.has(el)) continue;\n seen.add(el);\n const cs = window.getComputedStyle(el);\n if (cs.position !== \"fixed\" && cs.position !== \"sticky\") continue;\n const rect = el.getBoundingClientRect();\n // Anchored at bottom: rect.bottom is within ~8px of viewport bottom.\n if (rect.bottom < h - 8) continue;\n if (rect.bottom > h + 8) continue;\n // Full-width-ish: at least 60% of the viewport.\n if (rect.width < w * 0.6) continue;\n if (rect.height > tallest) tallest = rect.height;\n }\n }\n return tallest;\n}\n\n/**\n * Measure the bottom-overlap of every node matching the given selectors.\n * Returns the tallest overlap.\n */\nexport function measureExplicitAvoid(selectors: string[]): number {\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n return 0;\n }\n const h = window.innerHeight;\n let tallest = 0;\n for (const selector of selectors) {\n let nodes: NodeListOf<Element>;\n try {\n nodes = document.querySelectorAll(selector);\n } catch {\n continue;\n }\n for (const node of Array.from(nodes)) {\n const rect = node.getBoundingClientRect();\n if (rect.height === 0 || rect.width === 0) continue;\n // Bottom-overlap = how far the node extends above the bottom edge,\n // assuming it's anchored to the bottom (rect.bottom near h).\n if (rect.bottom < h - 8) continue;\n const overlap = Math.max(0, h - rect.top);\n if (overlap > tallest) tallest = overlap;\n }\n }\n return tallest;\n}\n\n/**\n * Same idea as measureExplicitAvoid but for any of the four edges.\n * Returns inset to add for the given side.\n */\nexport function measureExplicitAvoidForSide(\n selectors: string[],\n side: \"top\" | \"bottom\" | \"left\" | \"right\",\n): number {\n if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n return 0;\n }\n const w = window.innerWidth;\n const h = window.innerHeight;\n let tallest = 0;\n for (const selector of selectors) {\n let nodes: NodeListOf<Element>;\n try {\n nodes = document.querySelectorAll(selector);\n } catch {\n continue;\n }\n for (const node of Array.from(nodes)) {\n const rect = node.getBoundingClientRect();\n if (rect.height === 0 || rect.width === 0) continue;\n let overlap = 0;\n switch (side) {\n case \"bottom\":\n if (rect.bottom < h - 8) break;\n overlap = Math.max(0, h - rect.top);\n break;\n case \"top\":\n if (rect.top > 8) break;\n overlap = Math.max(0, rect.bottom);\n break;\n case \"left\":\n if (rect.left > 8) break;\n overlap = Math.max(0, rect.right);\n break;\n case \"right\":\n if (rect.right < w - 8) break;\n overlap = Math.max(0, w - rect.left);\n break;\n }\n if (overlap > tallest) tallest = overlap;\n }\n }\n return tallest;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport {\n detectBottomFloor,\n measureExplicitAvoidForSide,\n} from \"./autoDetectAvoid\";\nimport type { ResolvedFloatingConfig } from \"./types\";\n\nexport interface CollisionInsets {\n bottom: number;\n right: number;\n left: number;\n top: number;\n}\n\n/**\n * Computes the inset (px, before safe-area) the floating trigger needs\n * for its anchored corner. Subscribes to:\n * - ResizeObserver on documentElement\n * - MutationObserver on document.body (childList/attributes)\n * - visualViewport resize/scroll\n *\n * All callbacks coalesce into a single rAF measure to avoid feedback\n * loops where our CSS-var write triggers the next observer fire.\n */\nexport function useCollisionInsets(\n config: ResolvedFloatingConfig,\n): CollisionInsets {\n const [insets, setInsets] = useState<CollisionInsets>(() => ({\n bottom: config.offset.y,\n right: config.offset.x,\n left: config.offset.x,\n top: config.offset.y,\n }));\n\n // Hold the latest insets in a ref so the rAF body can compare without\n // capturing stale state.\n const lastRef = useRef(insets);\n\n // Stable identifier for the avoid array so the effect doesn't re-run\n // every render when callers pass an inline array.\n const avoidKey = avoidToKey(config.avoid);\n const placement = config.placement;\n const offsetX = config.offset.x;\n const offsetY = config.offset.y;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n let raf = 0;\n let cancelled = false;\n\n const measure = () => {\n raf = 0;\n if (cancelled) return;\n\n const side = placement[0] === \"b\" ? \"bottom\" : \"top\";\n const xSide = placement[1] === \"r\" ? \"right\" : \"left\";\n\n let yExtra = 0;\n let xExtra = 0;\n if (config.avoid === \"auto\" && side === \"bottom\") {\n yExtra = detectBottomFloor();\n } else if (Array.isArray(config.avoid)) {\n yExtra = measureExplicitAvoidForSide(config.avoid, side);\n xExtra = measureExplicitAvoidForSide(config.avoid, xSide);\n }\n\n const next: CollisionInsets = {\n bottom: side === \"bottom\" ? offsetY + yExtra : 0,\n top: side === \"top\" ? offsetY + yExtra : 0,\n right: xSide === \"right\" ? offsetX + xExtra : 0,\n left: xSide === \"left\" ? offsetX + xExtra : 0,\n };\n const prev = lastRef.current;\n if (\n next.bottom !== prev.bottom ||\n next.top !== prev.top ||\n next.right !== prev.right ||\n next.left !== prev.left\n ) {\n lastRef.current = next;\n setInsets(next);\n }\n };\n\n const schedule = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(measure);\n };\n\n schedule();\n\n const ro =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(schedule)\n : null;\n ro?.observe(document.documentElement);\n\n const mo =\n typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(schedule)\n : null;\n mo?.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\"],\n });\n\n window.addEventListener(\"resize\", schedule);\n const vv = window.visualViewport;\n vv?.addEventListener(\"resize\", schedule);\n vv?.addEventListener(\"scroll\", schedule);\n\n return () => {\n cancelled = true;\n if (raf) window.cancelAnimationFrame(raf);\n ro?.disconnect();\n mo?.disconnect();\n window.removeEventListener(\"resize\", schedule);\n vv?.removeEventListener(\"resize\", schedule);\n vv?.removeEventListener(\"scroll\", schedule);\n };\n // `config.avoid` is captured via avoidKey; safe to ignore in deps.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [placement, offsetX, offsetY, avoidKey]);\n\n return insets;\n}\n\nfunction avoidToKey(avoid: string[] | false | \"auto\"): string {\n if (avoid === false) return \"false\";\n if (avoid === \"auto\") return \"auto\";\n return avoid.join(\"|\");\n}\n","\"use client\";\n\nimport { useCallback, useRef } from \"react\";\n\nexport interface TriggerActivationOptions {\n /** Pointer-down on the trigger (Lumen uses it to pre-warm the open flow). */\n onPointerDown?: (event: PointerEvent) => void;\n /** Activation (tap / Enter / Space) — opens the sheet. */\n onClick: (event: MouseEvent) => void;\n /**\n * Stop the trigger's own pointer/click events from bubbling into host\n * outside-click handlers (Silk/Vaul/Radix) so a host bottom sheet stays open\n * when the user taps the trigger. Default `true`.\n */\n isolate?: boolean;\n}\n\n/** Stop-only on these so a host's outside-click layer never sees the tap. */\nconst STOP_ONLY_EVENTS = [\"mousedown\", \"touchstart\"] as const;\n\n/**\n * Drive a trigger button's activation from NATIVE DOM listeners instead of\n * React synthetic handlers, and (by default) stop those events at the button.\n *\n * Why native: React 18 delegates events at the tree root, so calling\n * `stopPropagation()` from a synthetic handler runs *after* the host's\n * document-level dismiss listener already fired. Binding on the button itself\n * means our listener runs first and the event never reaches the host — which is\n * what keeps an open host bottom sheet from dismissing on a Lumen tap. It's also\n * strictly more robust than synthetic delegation for a portaled button.\n *\n * Returns a ref callback to put on the button. The callback identity is stable,\n * so listeners attach once; the latest handlers are read through refs.\n */\nexport function useTriggerActivation(\n options: TriggerActivationOptions,\n): (el: HTMLElement | null) => void {\n const pdRef = useRef(options.onPointerDown);\n pdRef.current = options.onPointerDown;\n const clickRef = useRef(options.onClick);\n clickRef.current = options.onClick;\n const isolateRef = useRef(options.isolate ?? true);\n isolateRef.current = options.isolate ?? true;\n const cleanupRef = useRef<(() => void) | null>(null);\n\n return useCallback((el: HTMLElement | null) => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n if (!el) return;\n\n const onPointerDown = (event: PointerEvent) => {\n if (isolateRef.current) event.stopPropagation();\n pdRef.current?.(event);\n };\n const onClick = (event: MouseEvent) => {\n if (isolateRef.current) event.stopPropagation();\n clickRef.current(event);\n };\n const stopOnly = (event: Event) => {\n if (isolateRef.current) event.stopPropagation();\n };\n\n el.addEventListener(\"pointerdown\", onPointerDown);\n el.addEventListener(\"click\", onClick);\n for (const type of STOP_ONLY_EVENTS) {\n el.addEventListener(\n type,\n stopOnly,\n type === \"touchstart\" ? { passive: true } : undefined,\n );\n }\n\n cleanupRef.current = () => {\n el.removeEventListener(\"pointerdown\", onPointerDown);\n el.removeEventListener(\"click\", onClick);\n for (const type of STOP_ONLY_EVENTS) {\n el.removeEventListener(type, stopOnly);\n }\n };\n }, []);\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport * as React from \"react\";\n\nimport { useCollisionInsets } from \"./useCollisionInsets\";\nimport { useKeyboardInset } from \"./useKeyboardInset\";\nimport { useTriggerActivation } from \"./useTriggerActivation\";\nimport type { ResolvedFloatingConfig } from \"./types\";\n\nexport interface FloatingTriggerProps {\n config: ResolvedFloatingConfig;\n portalTarget?: HTMLElement;\n hidden: boolean;\n onPointerDown?: (event: PointerEvent) => void;\n onClick: (event: MouseEvent) => void;\n /** Stop trigger taps from leaking into host outside-click handlers. */\n isolateEvents?: boolean;\n /** Explicit keyboard inset override (px) for same-process WebView hosts. */\n keyboardInset?: number;\n}\n\nexport function FloatingTrigger({\n config,\n portalTarget,\n hidden,\n onPointerDown,\n onClick,\n isolateEvents = true,\n keyboardInset,\n}: FloatingTriggerProps) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const insets = useCollisionInsets(config);\n const keyboard = useKeyboardInset(config.keyboard !== \"off\", keyboardInset);\n\n const activate = useTriggerActivation({\n onPointerDown,\n onClick,\n isolate: isolateEvents,\n });\n const setButton = useCallback(\n (el: HTMLButtonElement | null) => {\n buttonRef.current = el;\n activate(el);\n },\n [activate],\n );\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n setTarget(portalTarget ?? document.body);\n }, [portalTarget]);\n\n const placement = config.placement;\n const sideY = placement[0] === \"b\" ? \"bottom\" : \"top\";\n const sideX = placement[1] === \"r\" ? \"right\" : \"left\";\n const placementBottom = sideY === \"bottom\";\n\n // Lift the trigger above the keyboard when we know how tall it is (incl.\n // WebView hosts that inject the inset); only a bottom-anchored trigger is\n // ever covered. Fall back to fading it out when the height is unknown or\n // \"hide\" was requested.\n const liftPx =\n keyboard.open &&\n placementBottom &&\n (config.keyboard === \"lift\" ||\n (config.keyboard === \"auto\" && keyboard.inset > 0))\n ? keyboard.inset\n : 0;\n const hideForKeyboard =\n keyboard.open &&\n (config.keyboard === \"hide\" ||\n (config.keyboard === \"auto\" && placementBottom && keyboard.inset <= 0));\n\n useOcclusionWarning(buttonRef, !hidden && !hideForKeyboard);\n\n if (!target) return null;\n\n const yPx = sideY === \"bottom\" ? insets.bottom : insets.top;\n const xPx = sideX === \"right\" ? insets.right : insets.left;\n const concealed = hidden || hideForKeyboard;\n\n const style: React.CSSProperties = {\n position: \"fixed\",\n [sideY]: config.safeArea\n ? `calc(${yPx}px + env(safe-area-inset-${sideY}, 0px))`\n : `${yPx}px`,\n [sideX]: config.safeArea\n ? `calc(${xPx}px + env(safe-area-inset-${sideX}, 0px))`\n : `${xPx}px`,\n zIndex: config.zIndex,\n transform: liftPx ? `translateY(-${liftPx}px)` : undefined,\n opacity: concealed ? 0 : 1,\n pointerEvents: concealed ? \"none\" : \"auto\",\n transition:\n \"opacity 160ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1)\",\n };\n\n return createPortal(\n <button\n ref={setButton}\n type=\"button\"\n className=\"lumen-btn lumen-btn-primary lumen-btn-floating\"\n style={style}\n aria-label={config.label}\n aria-hidden={concealed ? true : undefined}\n tabIndex={concealed ? -1 : 0}\n data-lumen-trigger=\"\"\n data-lumen-capture-ignore=\"true\"\n >\n {config.icon}\n <span>{config.label}</span>\n </button>,\n target,\n );\n}\n\n/**\n * Dev-only: after the first stable measurement, sample the trigger's\n * center point and warn once if a higher-z-index element overlaps it.\n */\nfunction useOcclusionWarning(\n ref: React.RefObject<HTMLButtonElement | null>,\n active: boolean,\n) {\n const warnedRef = useRef(false);\n\n useEffect(() => {\n if (process.env.NODE_ENV === \"production\") return;\n if (!active) return;\n if (warnedRef.current) return;\n if (typeof window === \"undefined\") return;\n\n const t = window.setTimeout(() => {\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return;\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n const stack = document.elementsFromPoint(cx, cy);\n const ourZ = parseZ(window.getComputedStyle(el).zIndex);\n for (const candidate of stack) {\n if (candidate === el || el.contains(candidate)) continue;\n const cz = parseZ(window.getComputedStyle(candidate).zIndex);\n if (cz > ourZ) {\n warnedRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\"[lumen] trigger is occluded by\", candidate);\n break;\n }\n }\n }, 250);\n return () => window.clearTimeout(t);\n }, [active, ref]);\n}\n\nfunction parseZ(z: string): number {\n const n = parseInt(z, 10);\n return Number.isNaN(n) ? 0 : n;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { ReactNode, RefObject } from \"react\";\n\nimport { useTriggerActivation } from \"./useTriggerActivation\";\n\nexport interface InlineTriggerProps {\n mount: HTMLElement | RefObject<HTMLElement | null>;\n label: string;\n icon?: ReactNode;\n onPointerDown?: (event: PointerEvent) => void;\n onClick: (event: MouseEvent) => void;\n /** Stop trigger taps from leaking into host outside-click handlers. */\n isolateEvents?: boolean;\n}\n\nexport function InlineTrigger({\n mount,\n label,\n icon,\n onPointerDown,\n onClick,\n isolateEvents = true,\n}: InlineTriggerProps) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n const setButton = useTriggerActivation({\n onPointerDown,\n onClick,\n isolate: isolateEvents,\n });\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const el =\n mount instanceof HTMLElement ? mount : (mount.current ?? null);\n setTarget(el);\n }, [mount]);\n\n if (!target) return null;\n\n return createPortal(\n <button\n ref={setButton}\n type=\"button\"\n className=\"lumen-btn lumen-btn-primary\"\n aria-label={label}\n data-lumen-trigger=\"\"\n data-lumen-capture-ignore=\"true\"\n >\n {icon}\n <span>{label}</span>\n </button>,\n target,\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { useTriggerActivation } from \"./useTriggerActivation\";\nimport type { ResolvedNotchConfig } from \"./types\";\n\nexport interface NotchTriggerProps {\n config: ResolvedNotchConfig;\n portalTarget?: HTMLElement;\n hidden: boolean;\n onPointerDown?: (event: PointerEvent) => void;\n onClick: (event: MouseEvent | PointerEvent) => void;\n /** Stop trigger taps from leaking into host outside-click handlers. */\n isolateEvents?: boolean;\n}\n\n/**\n * Edge-anchored notch. The resting state is a small tab on a screen\n * edge; on hover/tap it expands and opens the capture modal. A short\n * drag away from the edge (>16px) also opens, mimicking the iOS\n * Dynamic-Island pull gesture.\n *\n * Top edge → drag down. Right edge → drag left. Etc.\n */\nexport function NotchTrigger({\n config,\n portalTarget,\n hidden,\n onPointerDown: onActivatePointerDown,\n onClick,\n isolateEvents = true,\n}: NotchTriggerProps) {\n const [target, setTarget] = useState<HTMLElement | null>(null);\n const [expanded, setExpanded] = useState(false);\n const dragStartRef = useRef<{ x: number; y: number } | null>(null);\n\n // pointerdown + click run natively so the tap can be stopped from leaking\n // into host outside-click handlers; pointer-move/up stay React-synthetic for\n // the drag-open gesture.\n const setButton = useTriggerActivation({\n onPointerDown: (event) => {\n onActivatePointerDown?.(event);\n dragStartRef.current = { x: event.clientX, y: event.clientY };\n setExpanded(true);\n const el = event.currentTarget as HTMLElement | null;\n try {\n el?.setPointerCapture?.(event.pointerId);\n } catch {\n // setPointerCapture can throw if the pointer is already released.\n }\n },\n onClick,\n isolate: isolateEvents,\n });\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n setTarget(portalTarget ?? document.body);\n }, [portalTarget]);\n\n if (!target) return null;\n\n const className = `lumen-notch lumen-notch-${config.edge}${\n expanded ? \" lumen-notch-expanded\" : \"\"\n }`;\n\n function onPointerMove(e: React.PointerEvent<HTMLButtonElement>) {\n const start = dragStartRef.current;\n if (!start) return;\n const dx = e.clientX - start.x;\n const dy = e.clientY - start.y;\n const triggered =\n (config.edge === \"top\" && dy > 16) ||\n (config.edge === \"bottom\" && dy < -16) ||\n (config.edge === \"right\" && dx < -16) ||\n (config.edge === \"left\" && dx > 16);\n if (triggered) {\n dragStartRef.current = null;\n onClick(e.nativeEvent);\n }\n }\n function onPointerUp() {\n dragStartRef.current = null;\n setExpanded(false);\n }\n function onPointerCancel() {\n dragStartRef.current = null;\n setExpanded(false);\n }\n\n return createPortal(\n <button\n ref={setButton}\n type=\"button\"\n className={className}\n style={{\n zIndex: config.zIndex,\n opacity: hidden ? 0 : 1,\n pointerEvents: hidden ? \"none\" : \"auto\",\n }}\n aria-label={config.label}\n aria-hidden={hidden ? true : undefined}\n tabIndex={hidden ? -1 : 0}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerCancel}\n onMouseEnter={() => setExpanded(true)}\n onMouseLeave={() => setExpanded(false)}\n data-lumen-trigger=\"\"\n data-lumen-capture-ignore=\"true\"\n >\n <span className=\"lumen-notch-handle\" aria-hidden=\"true\" />\n <span className=\"lumen-notch-label\">{config.icon}{config.label}</span>\n </button>,\n target,\n );\n}\n","import type { ReactNode, RefObject } from \"react\";\n\nexport type LumenTriggerPlacement = \"br\" | \"bl\" | \"tr\" | \"tl\";\n\nexport interface FloatingTriggerConfig {\n kind: \"floating\";\n placement?: LumenTriggerPlacement;\n offset?: { x?: number; y?: number };\n safeArea?: boolean;\n /** Selectors to clear; pass `false` to disable auto-detect entirely. */\n avoid?: string | string[] | false;\n /**\n * What the floating trigger does when the soft keyboard opens:\n * - `\"auto\"` (default) — lift the trigger above the keyboard when its height\n * is known (incl. WebView hosts that inject it), else hide it.\n * - `\"lift\"` — always lift by the keyboard inset.\n * - `\"hide\"` — fade out (the pre-0.10 behavior).\n * Booleans are accepted for back-compat: `true` → `\"hide\"`, `false` → off.\n */\n hideOnKeyboard?: boolean | \"auto\" | \"lift\" | \"hide\";\n zIndex?: number;\n label?: string;\n icon?: ReactNode;\n}\n\nexport type NotchEdge = \"top\" | \"right\" | \"bottom\" | \"left\";\n\nexport interface NotchTriggerConfig {\n kind: \"notch\";\n edge?: NotchEdge;\n label?: string;\n icon?: ReactNode;\n /** z-index for the notch tab. Default 2147483600. */\n zIndex?: number;\n}\n\nexport interface ResolvedNotchConfig {\n kind: \"notch\";\n edge: NotchEdge;\n label: string;\n icon: ReactNode | undefined;\n zIndex: number;\n}\n\nexport function resolveNotchConfig(\n cfg: NotchTriggerConfig,\n): ResolvedNotchConfig {\n return {\n kind: \"notch\",\n edge: cfg.edge ?? \"top\",\n label: cfg.label ?? \"Feedback\",\n icon: cfg.icon,\n zIndex: cfg.zIndex ?? 2147483600,\n };\n}\n\nexport interface HeadlessTriggerConfig {\n kind: \"headless\";\n}\n\nexport interface InlineTriggerConfig {\n kind: \"inline\";\n mount: HTMLElement | RefObject<HTMLElement | null>;\n label?: string;\n icon?: ReactNode;\n}\n\nexport type LumenTrigger =\n | FloatingTriggerConfig\n | NotchTriggerConfig\n | HeadlessTriggerConfig\n | InlineTriggerConfig;\n\nexport type LumenTheme =\n | \"auto\"\n | \"light\"\n | \"dark\"\n | {\n background?: string;\n foreground?: string;\n accent?: string;\n radius?: string;\n /**\n * Force a colour scheme alongside the custom tokens. Lets a project set\n * a brand accent *and* pin light/dark at once (e.g. from the dashboard\n * brand config). Omit / \"auto\" to follow the host's prefers-color-scheme.\n */\n scheme?: \"auto\" | \"light\" | \"dark\";\n };\n\n/** Resolved keyboard behavior for the floating trigger. */\nexport type KeyboardBehavior = \"auto\" | \"lift\" | \"hide\" | \"off\";\n\nexport interface ResolvedFloatingConfig {\n kind: \"floating\";\n placement: LumenTriggerPlacement;\n offset: { x: number; y: number };\n safeArea: boolean;\n avoid: string[] | false | \"auto\";\n keyboard: KeyboardBehavior;\n zIndex: number;\n label: string;\n icon: ReactNode | undefined;\n}\n\n/** Map the (back-compat) `hideOnKeyboard` prop to a resolved behavior. */\nexport function resolveKeyboardBehavior(\n value: FloatingTriggerConfig[\"hideOnKeyboard\"],\n): KeyboardBehavior {\n if (value === false) return \"off\";\n if (value === true) return \"hide\"; // back-compat: explicit `true` kept hide\n if (value === \"auto\" || value === \"lift\" || value === \"hide\") return value;\n return \"auto\"; // new default: lift above the keyboard when its height is known\n}\n\nexport function resolveFloatingConfig(\n cfg: FloatingTriggerConfig,\n): ResolvedFloatingConfig {\n return {\n kind: \"floating\",\n placement: cfg.placement ?? \"br\",\n offset: { x: cfg.offset?.x ?? 16, y: cfg.offset?.y ?? 16 },\n safeArea: cfg.safeArea ?? true,\n avoid:\n cfg.avoid === false\n ? false\n : cfg.avoid == null\n ? \"auto\"\n : Array.isArray(cfg.avoid)\n ? cfg.avoid\n : [cfg.avoid],\n keyboard: resolveKeyboardBehavior(cfg.hideOnKeyboard),\n zIndex: cfg.zIndex ?? 2147483600,\n label: cfg.label ?? \"Feedback\",\n icon: cfg.icon,\n };\n}\n","\"use client\";\n\nimport { useEffect, useId } from \"react\";\nimport type { LumenTheme } from \"./types\";\n\nconst VAR_MAP: Record<string, keyof Extract<LumenTheme, object>> = {\n \"--lumen-bg\": \"background\",\n \"--lumen-fg\": \"foreground\",\n \"--lumen-radius\": \"radius\",\n};\n\n/**\n * Applies the theme by writing CSS variables to <html> (so they reach\n * the portaled CaptureModal) and toggling a data attribute for explicit\n * light/dark. Cleanup restores prior values on unmount.\n *\n * The instance id scopes attribute cleanup so two providers don't\n * stomp each other.\n */\nexport function useApplyTheme(theme: LumenTheme | undefined): void {\n const instanceId = useId();\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n const attr = `data-lumen-theme-${slug(instanceId)}`;\n const previous: Record<string, string | null> = {};\n\n const setVar = (cssVar: string, value: string) => {\n previous[cssVar] = root.style.getPropertyValue(cssVar) || null;\n root.style.setProperty(cssVar, value);\n };\n\n if (theme === \"auto\" || theme == null) {\n // Default: rely on prefers-color-scheme already in styles.css.\n root.removeAttribute(\"data-lumen-theme\");\n } else if (theme === \"light\" || theme === \"dark\") {\n previous[\"data-lumen-theme\"] = root.getAttribute(\"data-lumen-theme\");\n root.setAttribute(\"data-lumen-theme\", theme);\n } else {\n for (const [cssVar, key] of Object.entries(VAR_MAP)) {\n const v = theme[key as keyof typeof theme];\n if (typeof v === \"string\" && v.length > 0) {\n setVar(cssVar, v);\n }\n }\n // Accent drives the button/focus/stepper, which read --lumen-accent\n // (--lumen-primary is only a back-compat alias). Set both, and pin a\n // legible on-accent foreground — dashboard accents are saturated, so\n // white reads correctly; advanced hosts can still override via CSS.\n if (typeof theme.accent === \"string\" && theme.accent.length > 0) {\n setVar(\"--lumen-accent\", theme.accent);\n setVar(\"--lumen-primary\", theme.accent);\n setVar(\"--lumen-accent-fg\", \"#ffffff\");\n }\n // Optional forced scheme alongside the custom tokens.\n if (theme.scheme === \"light\" || theme.scheme === \"dark\") {\n previous[\"data-lumen-theme\"] = root.getAttribute(\"data-lumen-theme\");\n root.setAttribute(\"data-lumen-theme\", theme.scheme);\n }\n }\n root.setAttribute(attr, \"\");\n\n return () => {\n root.removeAttribute(attr);\n for (const [k, v] of Object.entries(previous)) {\n if (k.startsWith(\"--\")) {\n if (v) root.style.setProperty(k, v);\n else root.style.removeProperty(k);\n } else if (v == null) {\n root.removeAttribute(k);\n } else {\n root.setAttribute(k, v);\n }\n }\n };\n }, [theme, instanceId]);\n}\n\nfunction slug(s: string): string {\n return s.replace(/[^a-zA-Z0-9]/g, \"\");\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst PATCH_FLAG = Symbol.for(\"lumen.history.patched\");\nconst EVENT_NAME = \"lumen:locationchange\";\n\ninterface PatchedWindow extends Window {\n [PATCH_FLAG]?: true;\n}\n\n/**\n * Idempotent global patch: monkey-patches pushState/replaceState exactly\n * once per window so any number of LumenProvider instances (and React\n * StrictMode double-mounts) can subscribe without stacking patches.\n */\nfunction ensureHistoryPatch(): void {\n if (typeof window === \"undefined\") return;\n const w = window as PatchedWindow;\n if (w[PATCH_FLAG]) return;\n w[PATCH_FLAG] = true;\n\n const dispatch = () => window.dispatchEvent(new Event(EVENT_NAME));\n\n const origPush = history.pushState;\n history.pushState = function (...args: Parameters<History[\"pushState\"]>) {\n const r = origPush.apply(this, args);\n dispatch();\n return r;\n };\n const origReplace = history.replaceState;\n history.replaceState = function (\n ...args: Parameters<History[\"replaceState\"]>\n ) {\n const r = origReplace.apply(this, args);\n dispatch();\n return r;\n };\n window.addEventListener(\"popstate\", dispatch);\n}\n\n/**\n * Returns true when `predicate(location)` returns true for the current\n * location. Re-evaluates on history changes.\n */\nexport function useHideOn(\n predicate: ((location: { pathname: string }) => boolean) | undefined,\n): boolean {\n const [hidden, setHidden] = useState(false);\n\n useEffect(() => {\n if (!predicate) {\n setHidden(false);\n return;\n }\n if (typeof window === \"undefined\") return;\n ensureHistoryPatch();\n\n const evaluate = () => {\n try {\n setHidden(!!predicate({ pathname: window.location.pathname }));\n } catch {\n setHidden(false);\n }\n };\n evaluate();\n window.addEventListener(EVENT_NAME, evaluate);\n window.addEventListener(\"popstate\", evaluate);\n return () => {\n window.removeEventListener(EVENT_NAME, evaluate);\n window.removeEventListener(\"popstate\", evaluate);\n };\n }, [predicate]);\n\n return hidden;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst NATIVE_UA_TOKENS = [\n \"wv\", // generic Android WebView\n \"Capacitor\",\n \"Cordova\",\n \"Expo\",\n \"FBAN\",\n \"FBAV\",\n \"Instagram\",\n \"Line/\",\n \"Twitter\",\n];\n\n/**\n * Best-effort detection of a native shell (RN WebView, Capacitor,\n * Cordova, social-app webviews). Reported via context so hosts can\n * branch their own UI; we never auto-hide based on it.\n */\nexport function useNativeShell(): boolean {\n const [native, setNative] = useState(false);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const w = window as unknown as Record<string, unknown>;\n if (w.ReactNativeWebView) {\n setNative(true);\n return;\n }\n const wk = w.webkit as { messageHandlers?: unknown } | undefined;\n if (wk && wk.messageHandlers) {\n setNative(true);\n return;\n }\n const ua = navigator.userAgent || \"\";\n if (NATIVE_UA_TOKENS.some((t) => ua.includes(t))) {\n setNative(true);\n }\n }, []);\n\n return native;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport type { LumenTrigger, NotchEdge, LumenTriggerPlacement } from \"./types\";\n\nconst STORAGE_PREFIX = \"lumen.config.v1.\";\nconst STORAGE_TTL_MS = 60 * 60 * 1000; // 1h\n\n/**\n * Brand/appearance from the dashboard (`projects.brandConfig`). Mirrors\n * `brandConfigSchema` in @lumen/shared but typed locally so the SDK keeps\n * zero workspace deps. Applied via `useApplyTheme` in LumenProvider.\n */\nexport interface RemoteBrand {\n /** 6-digit hex accent colour, e.g. \"#3a2fe6\". */\n accent: string;\n /** Forced colour scheme, or \"auto\" to follow the host. */\n mode: \"auto\" | \"light\" | \"dark\";\n /** Corner radius in px. */\n radius: number;\n}\n\ninterface CachedEntry {\n fetchedAt: number;\n trigger: LumenTrigger;\n shake: boolean;\n brand: RemoteBrand | null;\n}\n\nexport interface RemoteConfigState {\n /** Trigger from the remote config; null while loading and no cache. */\n trigger: LumenTrigger | null;\n /** Whether the SDK should render any trigger at all. */\n enabled: boolean;\n /**\n * Shake-to-open toggle from the dashboard. Independent of `enabled` so a\n * project can keep the visible widget hidden but still open on shake.\n */\n shakeToOpen: boolean;\n /**\n * Brand/appearance from the dashboard; null when absent or malformed (the\n * caller then leaves the widget's built-in theme in place).\n */\n brand: RemoteBrand | null;\n /** True until either localStorage or the network has answered. */\n loading: boolean;\n}\n\n/**\n * Fetches `/api/v1/sdk/config?apiKey=…` and caches the result in\n * localStorage so the trigger can render instantly on subsequent loads.\n *\n * Returns immediately from the cache, then revalidates in the\n * background. Falls back to `null` (caller will use its built-in\n * default) on every error path so a flaky config endpoint can never\n * break the host page.\n */\nexport function useRemoteConfig(\n apiKey: string,\n apiUrl: string,\n): RemoteConfigState {\n const [state, setState] = useState<RemoteConfigState>(() => ({\n trigger: null,\n enabled: true,\n shakeToOpen: false,\n brand: null,\n loading: true,\n }));\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const cached = readCache(apiKey);\n if (cached) {\n setState({\n trigger: cached.trigger,\n enabled: triggerEnabled(cached.trigger),\n shakeToOpen: cached.shake,\n brand: cached.brand,\n loading: false,\n });\n }\n\n const controller = new AbortController();\n // Hard timeout: the SDK can't hold its loading state hostage to a\n // slow or hung /sdk/config endpoint. After 5s we abort and resolve\n // to a sensible default so the host page never sees a broken widget.\n const timeoutId = window.setTimeout(() => controller.abort(), 5000);\n const url = `${apiUrl.replace(/\\/$/, \"\")}/api/v1/sdk/config?apiKey=${encodeURIComponent(apiKey)}`;\n fetch(url, {\n method: \"GET\",\n mode: \"cors\",\n credentials: \"omit\",\n signal: controller.signal,\n })\n .then(async (res) => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {\n trigger?: unknown;\n brand?: unknown;\n };\n const trigger = parseTrigger(body.trigger);\n if (!trigger) throw new Error(\"Malformed config response\");\n const shake = parseShake(body.trigger);\n const brand = parseBrand(body.brand);\n writeCache(apiKey, trigger, shake, brand);\n setState({\n trigger,\n enabled: triggerEnabled(trigger),\n shakeToOpen: shake,\n brand,\n loading: false,\n });\n })\n .catch(() => {\n // Network/parse errors fall through to defaults — never block.\n setState((prev) =>\n prev.loading\n ? {\n trigger: null,\n enabled: true,\n shakeToOpen: false,\n brand: null,\n loading: false,\n }\n : prev,\n );\n })\n .finally(() => window.clearTimeout(timeoutId));\n\n return () => {\n window.clearTimeout(timeoutId);\n controller.abort();\n };\n }, [apiKey, apiUrl]);\n\n return state;\n}\n\nfunction triggerEnabled(t: LumenTrigger): boolean {\n // The SDK type doesn't carry `enabled` directly because hosts that\n // build a trigger inline would never need it; the *remote* type does\n // ship it as the on/off toggle and we encode that here as the\n // headless variant.\n return t.kind !== \"headless\";\n}\n\nconst VALID_PLACEMENTS: readonly LumenTriggerPlacement[] = [\n \"br\",\n \"bl\",\n \"tr\",\n \"tl\",\n];\nconst VALID_EDGES: readonly NotchEdge[] = [\"top\", \"right\", \"bottom\", \"left\"];\n\n/**\n * Defensive parser for the remote config payload. Exported for tests;\n * the hook uses it internally. Returns null when the shape is bad so\n * the caller can fall back to defaults instead of rendering garbage.\n */\nexport function parseTrigger(raw: unknown): LumenTrigger | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n\n // The dashboard ships `enabled` as the on/off toggle — when off,\n // collapse to a headless trigger so the SDK renders nothing.\n if (r.enabled === false) return { kind: \"headless\" };\n\n const label = typeof r.label === \"string\" ? r.label : \"Feedback\";\n\n if (r.kind === \"floating\") {\n const placement =\n VALID_PLACEMENTS.find((p) => p === r.placement) ?? \"br\";\n return { kind: \"floating\", placement, label };\n }\n if (r.kind === \"notch\") {\n const edge = VALID_EDGES.find((e) => e === r.edge) ?? \"top\";\n return { kind: \"notch\", edge, label };\n }\n return null;\n}\n\n/**\n * Read the dashboard's `shake` toggle off the raw config payload. Kept\n * separate from `parseTrigger` because that collapses a disabled widget to\n * `headless` (dropping every field) — but shake must survive an off widget.\n */\nexport function parseShake(raw: unknown): boolean {\n if (!raw || typeof raw !== \"object\") return false;\n return (raw as Record<string, unknown>).shake === true;\n}\n\nconst HEX6 = /^#[0-9a-fA-F]{6}$/;\nconst VALID_MODES: readonly RemoteBrand[\"mode\"][] = [\"auto\", \"light\", \"dark\"];\n\n/**\n * Defensive parser for the `brand` block. Returns null when absent or\n * malformed so the SDK keeps its built-in theme rather than applying a\n * half-valid one. Exported for tests.\n */\nexport function parseBrand(raw: unknown): RemoteBrand | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n const accent =\n typeof r.accent === \"string\" && HEX6.test(r.accent) ? r.accent : null;\n if (!accent) return null;\n const mode = VALID_MODES.find((m) => m === r.mode) ?? \"auto\";\n const radius =\n typeof r.radius === \"number\" && Number.isFinite(r.radius)\n ? Math.min(20, Math.max(0, Math.round(r.radius)))\n : 10;\n return { accent, mode, radius };\n}\n\nfunction readCache(apiKey: string): CachedEntry | null {\n try {\n const raw = window.localStorage.getItem(STORAGE_PREFIX + apiKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as CachedEntry;\n if (\n typeof parsed?.fetchedAt !== \"number\" ||\n Date.now() - parsed.fetchedAt > STORAGE_TTL_MS\n ) {\n return null;\n }\n const trigger = parseTrigger(parsed.trigger);\n return trigger\n ? {\n fetchedAt: parsed.fetchedAt,\n trigger,\n shake: parsed.shake === true,\n brand: parseBrand(parsed.brand),\n }\n : null;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(\n apiKey: string,\n trigger: LumenTrigger,\n shake: boolean,\n brand: RemoteBrand | null,\n): void {\n try {\n window.localStorage.setItem(\n STORAGE_PREFIX + apiKey,\n JSON.stringify({ fetchedAt: Date.now(), trigger, shake, brand }),\n );\n } catch {\n // Quota / private mode — fail silent.\n }\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { LUMEN_SHAKE_MESSAGE } from \"@lumen-stack/core\";\n\n/**\n * True when a bridge message (`window.postMessage` data) is a Lumen shake\n * event. Accepts both a parsed object and the JSON string react-native-webview\n * delivers. Exported for tests.\n */\nexport function isShakeMessage(data: unknown): boolean {\n if (data && typeof data === \"object\") {\n return (data as { type?: unknown }).type === LUMEN_SHAKE_MESSAGE;\n }\n if (typeof data === \"string\") {\n try {\n return (JSON.parse(data) as { type?: unknown }).type === LUMEN_SHAKE_MESSAGE;\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport interface MotionShakeOptions {\n /** Jerk (sum of |Δx|+|Δy|+|Δz|) above which a sample counts as a jolt. */\n threshold?: number;\n /** Distinct jolts needed within `windowMs` to call it a shake. */\n neededHits?: number;\n /** Sliding window the jolts must fall inside. */\n windowMs?: number;\n /** Minimum gap between processed samples (throttle). */\n throttleMs?: number;\n}\n\nexport interface MotionShakeDetector {\n /** Feed one accelerometer sample; returns true when a shake completes. */\n push: (x: number, y: number, z: number, now: number) => boolean;\n}\n\n/**\n * Pure accelerometer shake detector. A shake is several large jerks in a\n * short window; the first sample only primes the baseline. Framework-free so\n * it can be unit-tested without a DOM. Exported for tests.\n */\nexport function createMotionShakeDetector(\n options: MotionShakeOptions = {},\n): MotionShakeDetector {\n const threshold = options.threshold ?? 18;\n const neededHits = options.neededHits ?? 3;\n const windowMs = options.windowMs ?? 700;\n const throttleMs = options.throttleMs ?? 60;\n\n let last: { x: number; y: number; z: number; t: number } | null = null;\n let hits: number[] = [];\n\n return {\n push(x, y, z, now) {\n if (!last) {\n last = { x, y, z, t: now };\n return false;\n }\n if (now - last.t < throttleMs) return false;\n const delta =\n Math.abs(x - last.x) + Math.abs(y - last.y) + Math.abs(z - last.z);\n last = { x, y, z, t: now };\n if (delta < threshold) return false;\n hits = hits.filter((t) => now - t < windowMs);\n hits.push(now);\n if (hits.length >= neededHits) {\n hits = [];\n return true;\n }\n return false;\n },\n };\n}\n\n/**\n * Open the Lumen sheet when the user shakes their device.\n *\n * Two independent sources, both gated by `enabled`:\n *\n * 1. **Native bridge (primary).** A native Expo / react-native-webview host\n * detects the shake (e.g. `expo-sensors`, iOS `motionEnded`, Android\n * sensor) and posts a `{ \"type\": \"lumen:shake\" }` message into the WebView.\n * This is the reliable path on real devices.\n *\n * 2. **Web DeviceMotion (best-effort fallback).** For mobile web / PWAs the\n * SDK listens to `devicemotion` directly. This works on Android Chrome and\n * any context where motion permission is already granted; iOS Safari needs\n * `DeviceMotionEvent.requestPermission()` from a user gesture, which the\n * SDK can't trigger on its own — so on iOS the native bridge is required.\n *\n * A cooldown stops a single shake (many motion samples) from opening the\n * sheet more than once, and `onShake` is skipped while already open.\n */\nexport function useShakeToOpen(\n enabled: boolean,\n onShake: () => void,\n isOpen: boolean,\n): void {\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n\n let lastFire = 0;\n const COOLDOWN_MS = 1500;\n\n function fire() {\n const now = Date.now();\n if (isOpen || now - lastFire < COOLDOWN_MS) return;\n lastFire = now;\n onShake();\n }\n\n // ── Source 1: native bridge message ──────────────────────────────────\n const onMessage = (event: MessageEvent) => {\n if (isShakeMessage(event.data)) fire();\n };\n window.addEventListener(\"message\", onMessage);\n // react-native-webview delivers postMessage on `document` on Android.\n document.addEventListener(\"message\", onMessage as EventListener);\n\n // ── Source 2: web DeviceMotion shake detection ───────────────────────\n const detector = createMotionShakeDetector();\n const onMotion = (e: DeviceMotionEvent) => {\n const a = e.accelerationIncludingGravity ?? e.acceleration;\n if (!a || a.x == null || a.y == null || a.z == null) return;\n if (detector.push(a.x, a.y, a.z, Date.now())) fire();\n };\n // Don't auto-attach where an explicit permission gate exists (iOS): the\n // listener would never fire and just burns a slot. The native bridge\n // covers iOS instead.\n const hasMotion =\n typeof window.DeviceMotionEvent !== \"undefined\" &&\n typeof (\n window.DeviceMotionEvent as unknown as { requestPermission?: unknown }\n ).requestPermission !== \"function\";\n if (hasMotion) window.addEventListener(\"devicemotion\", onMotion);\n\n return () => {\n window.removeEventListener(\"message\", onMessage);\n document.removeEventListener(\"message\", onMessage as EventListener);\n if (hasMotion) window.removeEventListener(\"devicemotion\", onMotion);\n };\n }, [enabled, onShake, isOpen]);\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport * as React from \"react\";\nimport { Toaster, toast } from \"sonner\";\nimport {\n installRuntimeCapture,\n LumenClient,\n recordVideo,\n startDisplayMediaCapture,\n type AmplitudeIdentity,\n type CaptureResult,\n type DisplayMediaCaptureSession,\n type LumenRecordProvider,\n type LumenUser,\n type ScreenshotCaptureOptions,\n} from \"@lumen-stack/core\";\nimport { captureScreen } from \"@lumen-stack/core\";\n\nimport {\n LumenContext,\n type LumenContextValue,\n type PendingVideo,\n type ScreenCaptureState,\n type VideoRecordingState,\n} from \"./context\";\nimport { CaptureModal } from \"./CaptureModal\";\nimport { LumenErrorBoundary } from \"./LumenErrorBoundary\";\nimport { RecordingHud } from \"./RecordingHud\";\nimport { ScreenCaptureHud } from \"./ScreenCaptureHud\";\nimport { posterFromStream } from \"./video-poster\";\nimport { resolveRecordCapability } from \"./record-availability\";\nimport {\n driveRecordSession,\n type RecordSessionControl,\n} from \"./record-session\";\nimport { FloatingTrigger } from \"./trigger/FloatingTrigger\";\nimport { InlineTrigger } from \"./trigger/InlineTrigger\";\nimport { NotchTrigger } from \"./trigger/NotchTrigger\";\nimport {\n resolveFloatingConfig,\n resolveNotchConfig,\n type LumenTheme,\n type LumenTrigger,\n} from \"./trigger/types\";\nimport { useApplyTheme } from \"./trigger/theme\";\nimport { useHideOn } from \"./trigger/useHideOn\";\nimport { useNativeShell } from \"./trigger/useNativeShell\";\nimport {\n useRemoteConfig,\n type RemoteBrand,\n} from \"./trigger/useRemoteConfig\";\nimport { useShakeToOpen } from \"./trigger/useShakeToOpen\";\n\nconst DEFAULT_API_URL = \"https://shakebugs.vercel.app\";\nconst VIDEO_MAX_SECONDS = 60;\n\nfunction hasGetDisplayMedia(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n !!navigator.mediaDevices &&\n typeof navigator.mediaDevices.getDisplayMedia === \"function\"\n );\n}\n\nexport interface LumenProviderProps {\n apiKey: string;\n /** Override the dashboard origin. Defaults to https://shakebugs.vercel.app. */\n apiUrl?: string;\n user?: LumenUser;\n /**\n * Amplitude analytics identity for the current user. When set and the\n * project has the Amplitude integration enabled, Lumen pulls this user's\n * recent event timeline at enrichment time so the AI triage understands\n * what they did before reporting. Pass what your Amplitude instance holds:\n * `amplitude={{ userId: amp.getUserId(), deviceId: amp.getDeviceId(), sessionId: String(amp.getSessionId()) }}`.\n */\n amplitude?: AmplitudeIdentity;\n /**\n * @deprecated Use `trigger` instead. `floatingButton={false}` is\n * equivalent to `trigger={{ kind: \"headless\" }}`.\n */\n floatingButton?: boolean;\n /**\n * Trigger configuration. When omitted the SDK fetches the dashboard's\n * widget config from `/api/v1/sdk/config` and renders that. Pass a\n * value here to override the dashboard config locally.\n */\n trigger?: LumenTrigger;\n /** Hide the trigger on certain routes. Modal stays open if already open. */\n hideOn?: (location: { pathname: string }) => boolean;\n theme?: LumenTheme;\n /** Where to portal the floating trigger. Defaults to document.body. */\n portalTarget?: HTMLElement;\n /** Screenshot capture behavior and optional native/custom provider. */\n capture?: ScreenshotCaptureOptions;\n /**\n * Screen-recording behavior. By default the Record tab uses the browser\n * `getDisplayMedia` recorder (unavailable on iOS). Set `provider` to delegate\n * recording to a native/custom recorder — e.g. an iOS WebView host using\n * ReplayKit over its postMessage bridge — mirroring `capture.provider`.\n */\n record?: {\n /** When set (and available), the Record tab delegates to this factory instead of getDisplayMedia. */\n provider?: LumenRecordProvider;\n /** Optional availability probe, evaluated when the sheet opens. Defaults to true when provider is set. */\n isAvailable?: () => boolean | Promise<boolean>;\n };\n /**\n * Open the feedback sheet when the user shakes their device. When omitted\n * the SDK uses the dashboard's shake setting from `/api/v1/sdk/config`;\n * pass a boolean to force it on/off locally. Works via the native bridge\n * (a `lumen:shake` postMessage from an Expo/WebView host) and a best-effort\n * web DeviceMotion fallback.\n */\n shakeToOpen?: boolean;\n /**\n * Called exactly once whenever the Lumen sheet opens (`true`) or closes\n * (`false`). Never fires on the initial mount. Correct across all trigger\n * types. No spurious `false` during the 3-step capture wizard — `isOpen`\n * stays `true` throughout.\n *\n * Use this to hide/show native UI in a WebView host. Two complementary\n * approaches work together:\n *\n * **Option A — React prop (same-process host):**\n * ```tsx\n * <LumenProvider\n * onOpenChange={(open) => tabBarRef.current?.setVisible(!open)}\n * >\n * ```\n *\n * **Option B — MutationObserver (injected JS from native shell):**\n * While Lumen is open, `document.body` carries `data-lumen-open=\"true\"`.\n * Observe it from React Native / Capacitor / Electron:\n * ```tsx\n * // React Native (App.tsx)\n * <WebView\n * injectedJavaScript={`\n * const obs = new MutationObserver(() => {\n * const open = document.body.hasAttribute('data-lumen-open');\n * window.ReactNativeWebView.postMessage(\n * JSON.stringify({ type: 'lumen:openChange', open })\n * );\n * });\n * obs.observe(document.body, {\n * attributes: true,\n * attributeFilter: ['data-lumen-open'],\n * });\n * `}\n * onMessage={(e) => {\n * const { type, open } = JSON.parse(e.nativeEvent.data);\n * if (type === 'lumen:openChange') setTabBarVisible(!open);\n * }}\n * />\n * ```\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called before Lumen starts its capture/open flow. Hosts can use this to\n * suppress outside-click dismissal in their own overlay stack.\n */\n beforeOpen?: (event?: Event) => void | Promise<void>;\n /**\n * Alias for hosts that want trigger-specific coordination.\n * Runs after `beforeOpen` and before the pre-open screenshot.\n */\n onTriggerActivate?: (event?: Event) => void | Promise<void>;\n /**\n * Stop the trigger's own pointer/click events from bubbling into host\n * outside-click handlers (Silk/Vaul/Radix), so a host bottom sheet/dialog\n * stays open when the user taps the Lumen trigger. Default `true`. Hosts that\n * listen in the capture phase should still guard with `isLumenEventTarget`.\n */\n isolateEvents?: boolean;\n /**\n * Soft-keyboard height (CSS px) for WebView hosts where\n * `window.visualViewport` does NOT shrink (iOS WKWebView). When set, the\n * trigger lifts above the keyboard and the modal keeps its focused input\n * visible. Prefer `setLumenKeyboardInset()` from injected JS for a native\n * shell; this prop is for same-process hosts that already track the height.\n */\n keyboardInset?: number;\n /**\n * Hide the floating/notch trigger while a host overlay owns the screen (the\n * host's own modal, a full-screen route, etc.). The sheet stays openable\n * programmatically via `useLumen().open()`. Default `false`.\n */\n suppressTrigger?: boolean;\n children: React.ReactNode;\n}\n\nexport function LumenProvider({\n apiKey,\n apiUrl,\n user,\n amplitude,\n floatingButton = true,\n trigger,\n hideOn,\n theme,\n portalTarget,\n capture,\n record,\n shakeToOpen,\n onOpenChange,\n beforeOpen,\n onTriggerActivate,\n isolateEvents = true,\n keyboardInset,\n suppressTrigger = false,\n children,\n}: LumenProviderProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [isOpening, setIsOpening] = useState(false);\n const [initialCapture, setInitialCapture] = useState<CaptureResult | null>(\n null,\n );\n const [initialCaptureError, setInitialCaptureError] =\n useState<Error | null>(null);\n const [isSubmitting] = useState(false);\n const [error] = useState<Error | null>(null);\n const openingRef = useRef(false);\n const triggerPreparedRef = useRef(false);\n const triggerPreparePromiseRef = useRef<Promise<void> | null>(null);\n\n const client = useMemo(\n () => new LumenClient({ apiKey, apiUrl, user, amplitude }),\n [\n apiKey,\n apiUrl,\n user?.id,\n user?.email,\n user?.name,\n amplitude?.userId,\n amplitude?.deviceId,\n amplitude?.sessionId,\n ],\n );\n\n // Patches console + fetch + XHR on mount. Idempotent — safe under\n // Strict Mode double-invocation, and a no-op on the server.\n useEffect(() => {\n installRuntimeCapture({\n ignoreUrlPrefix: (apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, \"\"),\n });\n }, [apiUrl]);\n\n // ── onOpenChange + data-lumen-open DOM attribute ─────────────────────────\n // Kept in two separate effects so the DOM attribute (which needs a cleanup\n // to survive Strict-Mode's fake-unmount cycle) and the callback (which must\n // fire exactly once per transition) stay independent.\n\n // Stable ref so inline callbacks never cause stale-closure problems.\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n // DOM attribute — readable by MutationObserver from injected WebView JS.\n // cleanup runs on Strict-Mode teardown AND real unmount, so the attribute\n // is always removed when this effect version is discarded.\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n if (isOpen) {\n document.body.setAttribute(\"data-lumen-open\", \"true\");\n } else {\n document.body.removeAttribute(\"data-lumen-open\");\n }\n return () => {\n document.body.removeAttribute(\"data-lumen-open\");\n };\n }, [isOpen]);\n\n // Callback — fires exactly once per real open/close transition.\n // prevIsOpenRef starts as null so the initial false on mount is skipped.\n // The `=== isOpen` guard prevents double-fire under Strict-Mode re-runs.\n const prevIsOpenRef = useRef<boolean | null>(null);\n useEffect(() => {\n if (prevIsOpenRef.current === isOpen) return;\n const prev = prevIsOpenRef.current;\n prevIsOpenRef.current = isOpen;\n if (prev === null) return; // initial mount — no transition yet\n onOpenChangeRef.current?.(isOpen);\n }, [isOpen]);\n // ─────────────────────────────────────────────────────────────────────────\n\n const beforeOpenRef = useRef(beforeOpen);\n beforeOpenRef.current = beforeOpen;\n const onTriggerActivateRef = useRef(onTriggerActivate);\n onTriggerActivateRef.current = onTriggerActivate;\n\n const prepareTriggerOpen = useCallback((event: Event) => {\n triggerPreparedRef.current = true;\n triggerPreparePromiseRef.current = Promise.resolve()\n .then(() => beforeOpenRef.current?.(event))\n .then(() => onTriggerActivateRef.current?.(event))\n .then(() => undefined);\n }, []);\n\n const open = useCallback(\n (event?: Event) => {\n // Ignore trigger-initiated opens while a recording is in progress —\n // the sheet only comes back via the HUD's Stop (which avoids a fresh\n // capture clobbering the clip). Covers the provider start/encode windows\n // too, not just the browser recorder.\n if (\n openingRef.current ||\n isOpen ||\n recordingBusyRef.current ||\n screenCaptureBusyRef.current\n )\n return;\n openingRef.current = true;\n setIsOpening(true);\n setInitialCapture(null);\n setInitialCaptureError(null);\n\n void (async () => {\n try {\n if (triggerPreparedRef.current) {\n await triggerPreparePromiseRef.current;\n } else {\n await beforeOpenRef.current?.(event);\n await onTriggerActivateRef.current?.(event);\n }\n\n if (capture?.mode === \"manual\") {\n setInitialCapture(null);\n setInitialCaptureError(null);\n } else if (capture?.provider) {\n // Native/custom providers conceal Lumen's own UI during capture\n // (see createNativeCaptureProvider's concealSelector). They do NOT\n // need the pre-open shot to keep chrome out — and capturing before\n // the wizard mounts was dropping host overlays (e.g. native iOS\n // overlays) from the screenshot. Defer to the wizard, which grabs\n // the shot from a settled frame with Lumen UI concealed.\n setInitialCapture(null);\n setInitialCaptureError(null);\n } else {\n const result = await captureScreen({\n ...capture,\n mode: capture?.mode ?? \"auto\",\n target: capture?.target ?? document.documentElement,\n });\n setInitialCapture(result);\n }\n } catch (e) {\n setInitialCaptureError(\n e instanceof Error ? e : new Error(String(e)),\n );\n } finally {\n triggerPreparedRef.current = false;\n triggerPreparePromiseRef.current = null;\n openingRef.current = false;\n setIsOpening(false);\n setIsOpen(true);\n }\n })();\n },\n [capture, isOpen],\n );\n const close = useCallback(() => {\n setIsOpen(false);\n // Drop the prior screenshot so its PNG Blob/canvas isn't retained across\n // the closed window into the next open — every open captures fresh.\n setInitialCapture(null);\n setInitialCaptureError(null);\n }, []);\n const submit = useCallback(client.submit.bind(client), [client]);\n\n // Bumped when the error boundary catches a widget crash, so the Lumen UI\n // subtree remounts clean and the user can reopen. Closing the sheet here too\n // means the remounted subtree lands on a fresh, non-throwing state.\n const [boundaryKey, setBoundaryKey] = useState(0);\n const resetAfterCrash = useCallback(() => {\n openingRef.current = false;\n setIsOpening(false);\n setIsOpen(false);\n setInitialCapture(null);\n setInitialCaptureError(null);\n setBoundaryKey((k) => k + 1);\n }, []);\n\n // ── Video recording session ──────────────────────────────────────────\n // The recorder (browser MediaRecorder + stream, or a custom provider's\n // session) is a plain JS object that keeps running after the modal unmounts;\n // lifting the session here lets recording survive the sheet being closed and\n // reopened.\n const [recording, setRecording] = useState<VideoRecordingState | null>(null);\n // Probed from `record.isAvailable` when the sheet opens. null = not yet known\n // (treated as available when a provider is set — the spec's default-true).\n const [providerAvailable, setProviderAvailable] = useState<boolean | null>(\n null,\n );\n const activeRecorderRef = useRef<import(\"@lumen-stack/core\").VideoRecorderHandle | null>(\n null,\n ); // browser path\n const providerControlRef = useRef<RecordSessionControl | null>(null); // provider path\n // True across the whole record lifecycle (provider start window included), on\n // either path. Gates trigger re-opens while a recording is busy.\n const recordingBusyRef = useRef(false);\n const posterRef = useRef<Blob | null>(null);\n const pendingVideoRef = useRef<PendingVideo | null>(null);\n // Consume-once error from a failed provider start; surfaced on the Record\n // step when the sheet reopens.\n const recordStartErrorRef = useRef<string | null>(null);\n\n const finalizeVideo = useCallback(\n (rec: { blob: Blob; durationMs: number } | null, fromProvider = false) => {\n activeRecorderRef.current = null;\n providerControlRef.current = null;\n recordingBusyRef.current = false;\n setRecording(null);\n if (!rec) {\n posterRef.current = null;\n return;\n }\n pendingVideoRef.current = {\n blob: rec.blob,\n durationMs: rec.durationMs,\n poster: posterRef.current,\n // Provider clips have no stream-derived poster; let the modal derive\n // one from the blob. Never set on the browser path → unchanged there.\n deriveBlobPoster: fromProvider,\n };\n posterRef.current = null;\n // Reopen the sheet directly — NOT via open(), which runs a fresh\n // screenshot capture and would clobber the just-recorded clip.\n setIsOpen(true);\n },\n [],\n );\n\n // Probe provider availability when the sheet opens. Depends on the stable\n // provider/isAvailable identities (not the `record` object literal, which the\n // host typically re-creates each render).\n useEffect(() => {\n if (!isOpen) return;\n if (!record?.provider) {\n setProviderAvailable(null);\n return;\n }\n const probe = record.isAvailable;\n if (!probe) {\n setProviderAvailable(true);\n return;\n }\n let cancelled = false;\n Promise.resolve()\n .then(() => probe())\n .then((ok) => {\n if (!cancelled) setProviderAvailable(ok);\n })\n .catch(() => {\n if (!cancelled) setProviderAvailable(false);\n });\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, record?.provider, record?.isAvailable]);\n\n const canRecordScreen = resolveRecordCapability({\n hasProvider: !!record?.provider,\n providerAvailable,\n hasGetDisplayMedia: hasGetDisplayMedia(),\n }).canRecord;\n\n const startVideoSession = useCallback(async () => {\n if (recordingBusyRef.current) return;\n recordStartErrorRef.current = null;\n\n const usingProvider = resolveRecordCapability({\n hasProvider: !!record?.provider,\n providerAvailable,\n hasGetDisplayMedia: hasGetDisplayMedia(),\n }).usingProvider;\n\n if (usingProvider && record?.provider) {\n // Provider path: close the sheet FIRST (a native host must not capture\n // the Lumen sheet, and the consent dialog appears over the app), then\n // start. All lifecycle branching lives in driveRecordSession; these\n // callbacks are pure setState.\n recordingBusyRef.current = true;\n posterRef.current = null;\n setIsOpen(false);\n providerControlRef.current = driveRecordSession(\n record.provider,\n { maxDurationSeconds: VIDEO_MAX_SECONDS },\n {\n onStarting: () => setRecording({ phase: \"starting\" }),\n onActive: (session) => {\n setRecording({\n phase: \"recording\",\n stream: session.stream ?? null,\n startedAt: Date.now(),\n maxSeconds: VIDEO_MAX_SECONDS,\n });\n // Live poster only when a stream is exposed (native hosts omit it).\n if (session.stream) {\n void posterFromStream(session.stream)\n .then((p) => {\n posterRef.current = p;\n })\n .catch(() => undefined);\n }\n },\n onProcessing: () => setRecording({ phase: \"processing\" }),\n onResult: (result) =>\n finalizeVideo(\n { blob: result.blob, durationMs: result.durationMs },\n true,\n ),\n onCancelled: () => {\n providerControlRef.current = null;\n recordingBusyRef.current = false;\n posterRef.current = null;\n setRecording(null);\n // Return to the sheet at the method picker, no clip.\n setInitialCapture(null);\n setInitialCaptureError(null);\n setIsOpen(true);\n },\n onError: (err) => {\n providerControlRef.current = null;\n recordingBusyRef.current = false;\n posterRef.current = null;\n setRecording(null);\n recordStartErrorRef.current =\n err.message || \"Screen recording could not start.\";\n setIsOpen(true);\n },\n },\n );\n return;\n }\n\n // Browser path — behavior unchanged from before the provider extension.\n if (activeRecorderRef.current) return;\n // recordVideo() must run from the click's user activation; it throws\n // SCREEN_DENIED if the picker is dismissed (the modal surfaces it).\n const handle = await recordVideo(VIDEO_MAX_SECONDS);\n activeRecorderRef.current = handle;\n recordingBusyRef.current = true;\n posterRef.current = null;\n setRecording({\n phase: \"recording\",\n stream: handle.stream,\n startedAt: Date.now(),\n maxSeconds: VIDEO_MAX_SECONDS,\n });\n setIsOpen(false);\n // Poster from the live first frame (best-effort), grabbed off the hot\n // path so the sheet closes immediately.\n void posterFromStream(handle.stream)\n .then((p) => {\n posterRef.current = p;\n })\n .catch(() => undefined);\n // Single funnel: resolves on manual stop, the browser's \"Stop sharing\",\n // or the 60s cap — all reopen the sheet with the clip.\n handle.result.then((rec) => finalizeVideo(rec)).catch(() => finalizeVideo(null));\n }, [finalizeVideo, record?.provider, providerAvailable]);\n\n const stopVideoSession = useCallback(() => {\n if (providerControlRef.current) providerControlRef.current.stop();\n else activeRecorderRef.current?.stop();\n }, []);\n\n const cancelVideoSession = useCallback(() => {\n if (providerControlRef.current) {\n // The drive's onCancelled callback resets state and reopens the sheet.\n providerControlRef.current.cancel();\n return;\n }\n // Browser path — behavior unchanged.\n const handle = activeRecorderRef.current;\n activeRecorderRef.current = null;\n recordingBusyRef.current = false;\n posterRef.current = null;\n setRecording(null);\n handle?.cancel();\n // Reopen the sheet so Discard returns the user to the picker rather than\n // dumping them out of the flow. Clear any stale pre-open screenshot so\n // the modal lands on the method picker (method === null).\n setInitialCapture(null);\n setInitialCaptureError(null);\n setIsOpen(true);\n }, []);\n\n const consumePendingVideo = useCallback((): PendingVideo | null => {\n const p = pendingVideoRef.current;\n pendingVideoRef.current = null;\n return p;\n }, []);\n\n const consumeRecordStartError = useCallback((): string | null => {\n const e = recordStartErrorRef.current;\n recordStartErrorRef.current = null;\n return e;\n }, []);\n\n // Clear any unconsumed provider-start error when the sheet closes, so a later\n // trigger-open never lands on a stale Record-step error.\n useEffect(() => {\n if (!isOpen) recordStartErrorRef.current = null;\n }, [isOpen]);\n\n // ── \"Capture exact screen\" session (getDisplayMedia) ──────────────────\n // The live stream is held here (not in the modal) so the sheet can hide and\n // the user can scroll/arrange the page before the frame is grabbed — and so\n // the Lumen UI is never in the real-pixel shot.\n const [screenCapture, setScreenCapture] =\n useState<ScreenCaptureState | null>(null);\n const screenSessionRef = useRef<DisplayMediaCaptureSession | null>(null);\n const pendingScreenshotRef = useRef<CaptureResult | null>(null);\n // Gates trigger re-opens while a screen-capture session is live (mirrors\n // recordingBusyRef), so a stray trigger tap can't run a fresh capture.\n const screenCaptureBusyRef = useRef(false);\n\n const cancelScreenCaptureSession = useCallback(() => {\n const session = screenSessionRef.current;\n screenSessionRef.current = null;\n screenCaptureBusyRef.current = false;\n session?.stop();\n setScreenCapture(null);\n // Return to the sheet unchanged (the prior DOM shot is still seeded).\n setIsOpen(true);\n }, []);\n\n const grabScreenCaptureFrame = useCallback(() => {\n const session = screenSessionRef.current;\n if (!session) return;\n setScreenCapture({ phase: \"grabbing\" });\n void (async () => {\n try {\n const result = await session.grab();\n // If the session was torn down mid-grab (e.g. the user hit the\n // browser's \"Stop sharing\", which already reopened the sheet), drop\n // the frame so it can't surface as a stale screenshot on next open.\n if (screenSessionRef.current !== session) return;\n pendingScreenshotRef.current = result;\n screenSessionRef.current = null;\n screenCaptureBusyRef.current = false;\n session.stop();\n setScreenCapture(null);\n // Reopen directly — NOT via open(), which would run a fresh capture\n // and clobber the just-grabbed exact-screen shot.\n setIsOpen(true);\n } catch {\n if (screenSessionRef.current !== session) return;\n screenSessionRef.current = null;\n screenCaptureBusyRef.current = false;\n session.stop();\n setScreenCapture(null);\n toast.error(\"Could not capture the screen. Please try again.\");\n setIsOpen(true);\n }\n })();\n }, []);\n\n const startScreenCaptureSession = useCallback(async () => {\n if (screenCaptureBusyRef.current) return;\n // getDisplayMedia must run from the click's user activation; it rejects if\n // the surface picker is dismissed — in which case we simply stay on the\n // open sheet with the existing DOM screenshot (no session, no error).\n let session: DisplayMediaCaptureSession;\n try {\n session = await startDisplayMediaCapture({ ...capture });\n } catch {\n return;\n }\n screenSessionRef.current = session;\n screenCaptureBusyRef.current = true;\n session.onEnded(() => cancelScreenCaptureSession());\n setScreenCapture({ phase: \"live\" });\n // Hide the sheet so the page is fully usable while the user arranges it.\n setIsOpen(false);\n }, [capture, cancelScreenCaptureSession]);\n\n const consumePendingScreenshot = useCallback((): CaptureResult | null => {\n const r = pendingScreenshotRef.current;\n pendingScreenshotRef.current = null;\n return r;\n }, []);\n\n // Never leave a screen-capture stream live if the provider unmounts mid-\n // session (e.g. the host tears down Lumen while the picker bar is up).\n useEffect(\n () => () => {\n screenSessionRef.current?.stop();\n screenSessionRef.current = null;\n },\n [],\n );\n\n const isNativeShell = useNativeShell();\n const hideTrigger = useHideOn(hideOn);\n\n // Remote config: only fetched when the host hasn't pinned a trigger.\n // Passing the same apiUrl the LumenClient resolves to keeps the two\n // calls in lockstep.\n const remote = useRemoteConfig(\n trigger ? \"\" : apiKey,\n apiUrl ?? DEFAULT_API_URL,\n );\n\n // Theme precedence: an explicit `theme` prop in host code always wins;\n // otherwise apply the dashboard brand config; otherwise \"auto\" (follow the\n // host's prefers-color-scheme via styles.css).\n useApplyTheme(theme ?? brandToTheme(remote.brand));\n\n // Shake-to-open: explicit prop wins; otherwise honor the dashboard setting.\n // `open` is stable (useCallback), so the listener isn't re-bound per render.\n const effectiveShake = shakeToOpen ?? remote.shakeToOpen;\n useShakeToOpen(effectiveShake, open, isOpen);\n\n const value = useMemo<LumenContextValue>(\n () => ({\n client,\n user,\n isOpen,\n isSubmitting,\n error,\n open,\n close,\n openCapture: open,\n closeCapture: close,\n submit,\n isNativeShell,\n capture,\n initialCapture,\n initialCaptureError,\n isOpening,\n startVideoSession,\n stopVideoSession,\n cancelVideoSession,\n recording,\n consumePendingVideo,\n canRecordScreen,\n consumeRecordStartError,\n startScreenCaptureSession,\n grabScreenCaptureFrame,\n cancelScreenCaptureSession,\n screenCapture,\n consumePendingScreenshot,\n isolateEvents,\n keyboardInset,\n }),\n [\n client,\n user,\n isOpen,\n isSubmitting,\n error,\n open,\n close,\n submit,\n isNativeShell,\n capture,\n initialCapture,\n initialCaptureError,\n startVideoSession,\n stopVideoSession,\n cancelVideoSession,\n recording,\n consumePendingVideo,\n canRecordScreen,\n consumeRecordStartError,\n startScreenCaptureSession,\n grabScreenCaptureFrame,\n cancelScreenCaptureSession,\n screenCapture,\n consumePendingScreenshot,\n isOpening,\n isolateEvents,\n keyboardInset,\n ],\n );\n\n const effectiveTrigger = resolveEffectiveTrigger({\n explicit: trigger,\n remote: remote.trigger,\n remoteLoading: remote.loading,\n floatingButton,\n });\n\n return (\n <LumenContext.Provider value={value}>\n {children}\n {/* Lumen's own UI is isolated behind an error boundary so a widget crash\n (e.g. an iOS out-of-memory throw from capture) can never take down the\n host app's tree. `key` remounts it clean after a recovered crash. */}\n <LumenErrorBoundary\n key={boundaryKey}\n onReset={resetAfterCrash}\n onError={(report) =>\n client.reportClientError({\n ...report,\n // Provider-level state at crash time — tells us whether a capture\n // was in flight and at what method/scale (the OOM-theory signal).\n context: {\n open: isOpen,\n opening: isOpening,\n screenCapturePhase: screenCapture?.phase,\n recordingPhase: recording?.phase,\n initialCaptureMethod: initialCapture?.method,\n initialCapturePixelRatio: initialCapture?.pixelRatio,\n initialCaptureViewport: initialCapture?.viewport,\n hadInitialCaptureError: initialCaptureError != null,\n },\n })\n }\n >\n {effectiveTrigger?.kind === \"floating\" ? (\n <FloatingTrigger\n config={resolveFloatingConfig(effectiveTrigger)}\n portalTarget={portalTarget}\n hidden={\n hideTrigger ||\n suppressTrigger ||\n isOpening ||\n recording != null ||\n screenCapture != null\n }\n onPointerDown={prepareTriggerOpen}\n onClick={(event) => open(event)}\n isolateEvents={isolateEvents}\n keyboardInset={keyboardInset}\n />\n ) : null}\n {effectiveTrigger?.kind === \"notch\" ? (\n <NotchTrigger\n config={resolveNotchConfig(effectiveTrigger)}\n portalTarget={portalTarget}\n hidden={\n hideTrigger ||\n suppressTrigger ||\n isOpening ||\n recording != null ||\n screenCapture != null\n }\n onPointerDown={prepareTriggerOpen}\n onClick={(event) => open(event)}\n isolateEvents={isolateEvents}\n />\n ) : null}\n {effectiveTrigger?.kind === \"inline\" ? (\n <InlineTrigger\n mount={effectiveTrigger.mount}\n label={effectiveTrigger.label ?? \"Feedback\"}\n icon={effectiveTrigger.icon}\n onPointerDown={prepareTriggerOpen}\n onClick={(event) => open(event)}\n isolateEvents={isolateEvents}\n />\n ) : null}\n {screenCapture ? (\n <ScreenCaptureHud\n state={screenCapture}\n portalTarget={portalTarget}\n onCapture={grabScreenCaptureFrame}\n onCancel={cancelScreenCaptureSession}\n />\n ) : null}\n {recording ? (\n <RecordingHud\n state={recording}\n portalTarget={portalTarget}\n onStop={stopVideoSession}\n onCancel={cancelVideoSession}\n />\n ) : null}\n <CaptureModal />\n </LumenErrorBoundary>\n <SdkToaster />\n </LumenContext.Provider>\n );\n}\n\n/**\n * The SDK reports every user-facing error (submit failure, mic denied,\n * file rejected, capture warnings) via sonner's `toast()`, which renders\n * nothing unless a `<Toaster />` is mounted somewhere. Hosts can't be\n * expected to mount one, so the provider brings its own — but skips it\n * when the host app already renders a sonner Toaster, since every mounted\n * Toaster displays every toast and we'd duplicate them.\n */\nfunction SdkToaster() {\n const [shouldRender, setShouldRender] = useState(false);\n useEffect(() => {\n // Deferred to an effect so the host's own Toaster (anywhere in its\n // tree) has committed to the DOM before we look for it. The decision\n // is made once — re-checking on later renders would find *our*\n // Toaster and unmount it.\n setShouldRender(!document.querySelector(\"[data-sonner-toaster]\"));\n }, []);\n if (!shouldRender) return null;\n // Above the capture sheet (z-index 2147483647); later-in-DOM wins ties.\n return <Toaster position=\"top-center\" style={{ zIndex: 2147483647 }} />;\n}\n\n/**\n * Trigger resolution precedence:\n * 1. Explicit `trigger` prop wins (host opt-out from remote).\n * 2. `floatingButton={false}` → headless (legacy escape hatch).\n * 3. Remote config from /api/v1/sdk/config.\n * 4. While remote is still loading without a cached value, render\n * nothing (avoids a flash of the default in the wrong place).\n * 5. If remote ultimately fails, fall back to the floating default\n * so the host always has *something*.\n */\nfunction resolveEffectiveTrigger(args: {\n explicit: LumenTrigger | undefined;\n remote: LumenTrigger | null;\n remoteLoading: boolean;\n floatingButton: boolean;\n}): LumenTrigger | null {\n if (args.explicit) return args.explicit;\n if (args.floatingButton === false) return { kind: \"headless\" };\n if (args.remote) return args.remote;\n if (args.remoteLoading) return null;\n return { kind: \"floating\" };\n}\n\n/**\n * Map the dashboard brand config to a custom LumenTheme object. Returns\n * undefined when there's no brand (so useApplyTheme falls back to \"auto\").\n * Background/foreground are intentionally left out — they stay host-adaptive.\n */\nfunction brandToTheme(brand: RemoteBrand | null): LumenTheme | undefined {\n if (!brand) return undefined;\n return {\n accent: brand.accent,\n radius: `${brand.radius}px`,\n scheme: brand.mode,\n };\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useLumen } from \"./context\";\n\nexport interface FeedbackButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"default\" | \"ghost\" | \"outline\";\n /** Render fixed in the bottom-right corner. */\n floating?: boolean;\n}\n\nexport function FeedbackButton({\n variant = \"default\",\n floating = false,\n className,\n children = \"Feedback\",\n onClick,\n ...rest\n}: FeedbackButtonProps) {\n const { openCapture } = useLumen();\n const cls = [\n \"lumen-btn\",\n variant === \"default\" ? \"lumen-btn-primary\" : null,\n variant === \"ghost\" ? \"lumen-btn-ghost\" : null,\n variant === \"outline\" ? \"lumen-btn-outline\" : null,\n floating ? \"lumen-btn-floating\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n type=\"button\"\n className={cls}\n data-lumen-trigger=\"\"\n onClick={(e) => {\n onClick?.(e);\n if (!e.defaultPrevented) openCapture(e.nativeEvent);\n }}\n {...rest}\n >\n {children}\n </button>\n );\n}\n"]}
|