@zerohive/hive-viewer 0.2.7 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/DocumentViewer.tsx","../src/editors/RichTextEditor.tsx","../src/utils/sanitize.ts","../src/editors/SpreadsheetEditor.tsx","../src/utils/fileSource.ts","../src/renderers/ImageRenderer.tsx","../src/renderers/PdfRenderer.tsx","../src/renderers/PptxRenderer.tsx","../src/utils/locale.ts","../src/components/SignaturePanel.tsx","../src/components/ThumbnailsSidebar.tsx","../src/components/Toolbar.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n RichTextEditor,\n type RichTextEditorHandle,\n} from \"../editors/RichTextEditor\";\nimport {\n SpreadsheetEditor,\n type SpreadsheetEditorHandle,\n} from \"../editors/SpreadsheetEditor\";\nimport { ImageRenderer } from \"../renderers/ImageRenderer\";\nimport { PdfRenderer } from \"../renderers/PdfRenderer\";\nimport { PptxRenderer } from \"../renderers/PptxRenderer\";\nimport type {\n DocumentMode,\n DocumentViewerProps,\n DocumentViewerSaveMeta,\n PageLayout,\n Signature,\n SupportedFileType,\n} from \"../types\";\nimport { resolveSource } from \"../utils/fileSource\";\nimport { defaultLocale } from \"../utils/locale\";\nimport { SignaturePanel } from \"./SignaturePanel\";\nimport { ThumbnailsSidebar, type Thumbnail } from \"./ThumbnailsSidebar\";\nimport { Toolbar } from \"./Toolbar\";\n\ninterface SigPlacement {\n page: number;\n x: number;\n y: number;\n w: number;\n h: number;\n signatureImageUrl: string;\n}\n\ntype EditorHandle = (RichTextEditorHandle | SpreadsheetEditorHandle) & {\n save: (exportPdf?: boolean) => Promise<void>;\n};\n\nexport function DocumentViewer(props: DocumentViewerProps) {\n const mode: DocumentMode = props.mode ?? \"view\";\n const theme = props.theme ?? \"light\";\n const locale = useMemo(\n () => ({ ...defaultLocale, ...(props.locale ?? {}) }),\n [props.locale],\n );\n\n const [layout, setLayout] = useState<PageLayout>(\n props.defaultLayout ?? \"single\",\n );\n const [showThumbnails, setShowThumbnails] = useState(true);\n const [showSignatures, setShowSignatures] = useState(true);\n const [headerFooterEnabled, setHeaderFooterEnabled] = useState(true);\n\n const allowSigning = props.allowSigning ?? false;\n const [signingBusy, setSigningBusy] = useState(false);\n\n const [resolved, setResolved] = useState<{\n fileType: SupportedFileType;\n fileName: string;\n url?: string;\n arrayBuffer?: ArrayBuffer;\n } | null>(null);\n const [error, setError] = useState<string>(\"\");\n const [pageCount, setPageCount] = useState(1);\n const [currentPage, setCurrentPage] = useState(1);\n const [thumbs, setThumbs] = useState<Array<string | undefined>>([]);\n\n const [localSignatures, setLocalSignatures] = useState<Signature[]>(\n props.signatures ?? [],\n );\n useEffect(\n () => setLocalSignatures(props.signatures ?? []),\n [props.signatures],\n );\n\n const [sigPlacements, setSigPlacements] = useState<SigPlacement[]>([]);\n const [armedSignatureUrl, setArmedSignatureUrl] = useState<string | null>(\n null,\n );\n\n const editorRef = useRef<EditorHandle | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n setError(\"\");\n setResolved(null);\n setThumbs([]);\n setPageCount(1);\n setCurrentPage(1);\n setSigPlacements([]);\n setArmedSignatureUrl(null);\n\n if (mode === \"create\") {\n const ft = (props.fileType ?? \"docx\") as SupportedFileType;\n setResolved({\n fileType: ft,\n fileName: props.fileName ?? `Untitled.${ft}`,\n });\n return;\n }\n\n try {\n const res = await resolveSource({\n fileUrl: props.fileUrl,\n base64: props.base64,\n blob: props.blob,\n fileName: props.fileName,\n fileType: props.fileType,\n });\n if (cancelled) {\n return;\n }\n setResolved({\n fileType: res.fileType,\n fileName: res.fileName,\n url: res.url,\n arrayBuffer: res.arrayBuffer,\n });\n } catch (e) {\n if (cancelled) {\n return;\n }\n setError(e instanceof Error ? e.message : String(e));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [\n mode,\n props.fileUrl,\n props.base64,\n props.blob,\n props.fileName,\n props.fileType,\n ]);\n\n const thumbnails: Thumbnail[] = useMemo(() => {\n const n = Math.max(1, pageCount);\n return Array.from({ length: n }, (_, i) => ({\n id: `p-${i + 1}`,\n label: `${locale[\"thumbnails.page\"] ?? \"Page\"} ${i + 1}`,\n dataUrl: thumbs[i],\n }));\n }, [pageCount, thumbs, locale]);\n\n async function handleSignRequest() {\n if (!allowSigning || signingBusy || !props.onSignRequest) {\n return;\n }\n setSigningBusy(true);\n try {\n const sig = await props.onSignRequest();\n setLocalSignatures((prev: Signature[]) => [...prev, sig]);\n setArmedSignatureUrl(sig.signatureImageUrl);\n } finally {\n setSigningBusy(false);\n }\n }\n\n function placeSignature(p: {\n page: number;\n x: number;\n y: number;\n w: number;\n h: number;\n }) {\n if (!armedSignatureUrl) {\n return;\n }\n setSigPlacements((prev: SigPlacement[]) => [\n ...prev,\n { ...p, signatureImageUrl: armedSignatureUrl },\n ]);\n setArmedSignatureUrl(null);\n }\n\n async function handleSave(exportPdf?: boolean) {\n if (editorRef.current) {\n await editorRef.current.save(!!exportPdf);\n return;\n }\n if (!resolved?.arrayBuffer) {\n return;\n }\n const b64 = arrayBufferToBase64(resolved.arrayBuffer);\n props.onSave?.(b64, {\n fileName: resolved.fileName,\n fileType: resolved.fileType,\n annotations: { sigPlacements },\n });\n }\n\n const canSave = mode === \"edit\" || mode === \"create\";\n const canExportPdf =\n (mode === \"edit\" || mode === \"create\") &&\n (resolved?.fileType === \"docx\" ||\n resolved?.fileType === \"md\" ||\n resolved?.fileType === \"txt\" ||\n resolved?.fileType === \"xlsx\");\n\n return (\n <div className={`hv-root`} data-hv-theme={theme}>\n <Toolbar\n locale={locale}\n mode={mode}\n fileType={resolved?.fileType}\n layout={layout}\n onChangeLayout={setLayout}\n showThumbnails={showThumbnails}\n onToggleThumbnails={() => setShowThumbnails((v: boolean) => !v)}\n showSignatures={showSignatures}\n onToggleSignatures={() => setShowSignatures((v: boolean) => !v)}\n onSign={() => void handleSignRequest()}\n allowSigning={allowSigning}\n signingDisabled={signingBusy || !props.onSignRequest}\n canSave={canSave}\n onSave={() => void handleSave(false)}\n canExportPdf={canExportPdf}\n onExportPdf={() => void handleSave(true)}\n headerFooterEnabled={headerFooterEnabled}\n showHeaderFooterToggle={\n (props.enableHeaderFooterToggle ?? true) && mode === \"create\"\n }\n onToggleHeaderFooter={() => setHeaderFooterEnabled((v: boolean) => !v)}\n />\n\n {error ? (\n <div className=\"hv-error\" role=\"alert\">\n <div className=\"hv-error-title\">\n {locale[\"error.title\"] ?? \"Error\"}\n </div>\n <div className=\"hv-error-body\">{error}</div>\n </div>\n ) : null}\n\n {!resolved && !error ? (\n <div className=\"hv-loading\" aria-busy=\"true\">\n {locale.loading ?? \"Loading…\"}\n </div>\n ) : null}\n\n {resolved ? (\n <div className=\"hv-shell\">\n {mode !== \"create\" ? (\n <ThumbnailsSidebar\n locale={locale}\n thumbnails={thumbnails}\n currentPage={currentPage}\n collapsed={!showThumbnails}\n onToggle={() => setShowThumbnails((v: boolean) => !v)}\n onSelectPage={setCurrentPage}\n />\n ) : null}\n\n <main className=\"hv-main\">\n {resolved.fileType === \"pdf\" ? (\n <PdfRenderer\n url={resolved.url}\n arrayBuffer={resolved.arrayBuffer}\n layout={layout}\n currentPage={currentPage}\n onCurrentPageChange={setCurrentPage}\n onPageCount={(n) => {\n setPageCount(n);\n setThumbs((prev) =>\n prev.length === n\n ? prev\n : Array.from({ length: n }, (_, i) => prev[i]),\n );\n }}\n onThumbs={(t) => setThumbs(t)}\n signatureStamp={\n armedSignatureUrl\n ? {\n imageUrl: armedSignatureUrl,\n armed: true,\n onPlaced: placeSignature,\n }\n : undefined\n }\n />\n ) : null}\n\n {resolved.fileType === \"docx\" ||\n resolved.fileType === \"md\" ||\n resolved.fileType === \"txt\" ? (\n <RichTextEditor\n ref={editorRef as any}\n mode={mode}\n fileType={resolved.fileType}\n fileName={resolved.fileName}\n arrayBuffer={resolved.arrayBuffer}\n headerComponent={props.headerComponent}\n footerComponent={props.footerComponent}\n headerFooterEnabled={headerFooterEnabled}\n locale={locale}\n signatures={localSignatures}\n signaturePlacements={sigPlacements}\n onPageCount={(n: number) => {\n setPageCount(n);\n setThumbs((prev) =>\n prev.length === n\n ? prev\n : Array.from({ length: n }, (_, i) => prev[i]),\n );\n }}\n onSave={(b64: string, meta: DocumentViewerSaveMeta) =>\n props.onSave?.(b64, meta)\n }\n armedSignatureUrl={armedSignatureUrl}\n onPlaceSignature={placeSignature}\n />\n ) : null}\n\n {resolved.fileType === \"xlsx\" ? (\n <SpreadsheetEditor\n ref={editorRef as any}\n mode={mode}\n fileName={resolved.fileName}\n arrayBuffer={resolved.arrayBuffer}\n locale={locale}\n onSave={(b64, meta) => props.onSave?.(b64, meta)}\n />\n ) : null}\n\n {resolved.fileType === \"pptx\" ? (\n <PptxRenderer\n arrayBuffer={resolved.arrayBuffer}\n layout={layout}\n currentPage={currentPage}\n onCurrentPageChange={setCurrentPage}\n onSlideCount={(n) => {\n setPageCount(n);\n setThumbs((prev) =>\n prev.length === n\n ? prev\n : Array.from({ length: n }, (_, i) => prev[i]),\n );\n }}\n onThumbs={(t) => setThumbs(t)}\n />\n ) : null}\n\n {resolved.fileType === \"png\" ||\n resolved.fileType === \"jpg\" ||\n resolved.fileType === \"svg\" ? (\n <ImageRenderer\n arrayBuffer={resolved.arrayBuffer}\n fileType={resolved.fileType}\n fileName={resolved.fileName}\n />\n ) : null}\n </main>\n\n {mode !== \"create\" && localSignatures.length ? (\n <SignaturePanel\n locale={locale}\n signatures={localSignatures}\n collapsed={!showSignatures}\n onToggle={() => setShowSignatures((v: boolean) => !v)}\n />\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction arrayBufferToBase64(ab: ArrayBuffer): string {\n const bytes = new Uint8Array(ab);\n let binary = \"\";\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n","\"use client\";\n\nimport html2canvas from \"html2canvas\";\nimport mammoth from \"mammoth\";\nimport MarkdownIt from \"markdown-it\";\nimport React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { DocumentMode, Signature, SupportedFileType } from \"../types\";\nimport { sanitizeHtml } from \"../utils/sanitize\";\n\nconst PAGE_H = 1122;\n\nexport interface RichTextEditorHandle {\n save: (exportPdf?: boolean) => Promise<void>;\n requestThumbnail: (index: number) => Promise<string | undefined>;\n}\n\nexport const RichTextEditor = forwardRef<RichTextEditorHandle, any>(\n (props, ref) => {\n const readOnly = props.mode === \"view\";\n\n const md = useMemo(\n () => new MarkdownIt({ html: false, linkify: true, breaks: true }),\n [],\n );\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n const editorRef = useRef<HTMLDivElement>(null);\n const captureRef = useRef<HTMLDivElement>(null);\n\n const initialized = useRef(false);\n\n /** ----------------------------------------\n * Load document ONCE\n * ---------------------------------------- */\n useEffect(() => {\n if (initialized.current) return;\n\n (async () => {\n if (props.mode === \"create\") {\n editorRef.current!.innerHTML = \"<p><br/></p>\";\n initialized.current = true;\n return;\n }\n\n if (!props.arrayBuffer) return;\n\n if (props.fileType === \"docx\") {\n const res = await mammoth.convertToHtml({\n arrayBuffer: props.arrayBuffer,\n });\n editorRef.current!.innerHTML = sanitizeHtml(\n res.value || \"<p><br/></p>\",\n );\n } else {\n const text = new TextDecoder().decode(props.arrayBuffer);\n editorRef.current!.innerHTML =\n props.fileType === \"md\"\n ? sanitizeHtml(md.render(text))\n : `<pre>${escapeHtml(text)}</pre>`;\n }\n\n initialized.current = true;\n })();\n }, [props.arrayBuffer, props.fileType, props.mode, md]);\n\n /** ----------------------------------------\n * Page count observer\n * ---------------------------------------- */\n useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n\n const recompute = () =>\n props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));\n\n recompute();\n const ro = new ResizeObserver(recompute);\n ro.observe(el);\n return () => ro.disconnect();\n }, [props.headerFooterEnabled]);\n\n function exec(cmd: string) {\n if (readOnly) return;\n document.execCommand(cmd);\n editorRef.current?.focus();\n }\n\n function onClickPage(e: React.MouseEvent) {\n if (!props.armedSignatureUrl) return;\n const scroller = scrollerRef.current;\n if (!scroller) return;\n\n const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();\n const absY = scroller.scrollTop + (e.clientY - rect.top);\n const page = Math.floor(absY / PAGE_H) + 1;\n\n props.onPlaceSignature({\n page,\n x: (e.clientX - rect.left) / rect.width,\n y: (absY % PAGE_H) / PAGE_H,\n w: 0.25,\n h: 0.1,\n });\n }\n\n async function requestThumbnail(index: number) {\n const scroller = scrollerRef.current;\n const capture = captureRef.current;\n if (!scroller || !capture) return;\n\n const old = scroller.scrollTop;\n scroller.scrollTop = index * PAGE_H;\n await new Promise((r) => requestAnimationFrame(r));\n\n try {\n const canvas = await html2canvas(capture, {\n scale: 0.25,\n useCORS: true,\n });\n return canvas.toDataURL(\"image/png\");\n } finally {\n scroller.scrollTop = old;\n }\n }\n\n async function save(exportPdf?: boolean) {\n const html = editorRef.current?.innerHTML ?? \"\";\n const stitched = `<!doctype html><html><body>${html}</body></html>`;\n const b64 = btoa(unescape(encodeURIComponent(stitched)));\n\n props.onSave(b64, {\n fileName: props.fileName,\n fileType: props.fileType,\n exportedAsPdf: exportPdf,\n annotations: { signaturePlacements: props.signaturePlacements },\n });\n }\n\n useImperativeHandle(ref, () => ({\n save,\n requestThumbnail,\n }));\n\n return (\n <div className=\"hv-root\">\n <div className=\"hv-toolbar\">\n <button onClick={() => exec(\"bold\")} disabled={readOnly}>\n B\n </button>\n <button onClick={() => exec(\"italic\")} disabled={readOnly}>\n I\n </button>\n <button onClick={() => exec(\"underline\")} disabled={readOnly}>\n U\n </button>\n\n {props.armedSignatureUrl && (\n <span className=\"hv-hint\">Click page to place signature</span>\n )}\n </div>\n\n <div className=\"hv-scroll\" ref={scrollerRef} onClick={onClickPage}>\n <div className=\"hv-pageStage\" ref={captureRef}>\n <div\n ref={editorRef}\n className={`hv-editor ${readOnly ? \"ro\" : \"\"}`}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n />\n </div>\n </div>\n </div>\n );\n },\n);\n\nfunction escapeHtml(s: string) {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\");\n}\n","import DOMPurify from 'dompurify';\n\n/**\n * Sanitize HTML using DOMPurify for safe rendering.\n * @param html - The HTML string to sanitize\n * @returns Safe HTML string\n */\nexport function sanitizeHtml(html: string): string {\n // DOMPurify is safe to call in the browser. For SSR, callers should only run after mount.\n return DOMPurify.sanitize(html, {\n USE_PROFILES: { html: true },\n ADD_ATTR: ['target', 'rel'],\n });\n}\n","'use client';\n\nimport React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';\nimport * as XLSX from 'xlsx';\nimport type { DocumentMode, SupportedFileType } from '../types';\nimport { arrayBufferToBase64 } from '../utils/fileSource';\n\nexport interface SpreadsheetEditorHandle {\n save: (exportPdf?: boolean) => Promise<void>;\n requestThumbnails: (index: number) => Promise<void>;\n}\n\nexport const SpreadsheetEditor = forwardRef<SpreadsheetEditorHandle, {\n mode: DocumentMode;\n fileName: string;\n arrayBuffer?: ArrayBuffer;\n locale: Record<string, string>;\n onSave: (base64: string, meta: { fileName: string; fileType: SupportedFileType; exportedAsPdf?: boolean }) => void;\n}>(function SpreadsheetEditor(props, ref) {\n const readonly = props.mode === 'view';\n const [grid, setGrid] = useState<string[][]>(() => Array.from({ length: 30 }, () => Array.from({ length: 12 }, () => '')));\n\n useEffect(() => {\n if (!props.arrayBuffer) { return; }\n try {\n const wb = XLSX.read(props.arrayBuffer, { type: 'array' });\n const name = wb.SheetNames[0];\n const ws = wb.Sheets[name];\n const aoa = XLSX.utils.sheet_to_json(ws, { header: 1, raw: true }) as any[][];\n const rows = Math.max(30, aoa.length);\n const cols = Math.max(12, Math.max(...aoa.map((r) => (r?.length ?? 0)), 0));\n const next = Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => {\n const v = aoa[r]?.[c];\n return v == null ? '' : String(v);\n }));\n setGrid(next);\n } catch {\n // ignore\n }\n }, [props.arrayBuffer]);\n\n async function save(exportPdf?: boolean) {\n const ws = XLSX.utils.aoa_to_sheet(grid);\n const wb = XLSX.utils.book_new();\n XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');\n const out = XLSX.write(wb, { type: 'array', bookType: 'xlsx' }) as ArrayBuffer;\n const b64 = arrayBufferToBase64(out);\n props.onSave(b64, { fileName: ensureExt(props.fileName, 'xlsx'), fileType: 'xlsx', exportedAsPdf: !!exportPdf });\n }\n\n useImperativeHandle(ref, () => ({\n save,\n requestThumbnails: async () => undefined,\n }));\n\n const cols = useMemo(() => Array.from({ length: grid[0]?.length ?? 0 }, (_, i) => String.fromCharCode(65 + (i % 26))), [grid]);\n\n return (\n <div className=\"hv-sheet\">\n <div className=\"hv-sheetbar\">\n <div className=\"hv-sheetbar-title\">{props.fileName}</div>\n {!readonly ? <button className=\"hv-btn\" type=\"button\" onClick={() => void save(false)}>{props.locale['toolbar.save'] ?? 'Save'}</button> : null}\n </div>\n <div className=\"hv-sheetgrid\" role=\"table\" aria-label=\"Spreadsheet\">\n <div className=\"hv-sheetrow hv-sheetrow--header\" role=\"row\">\n <div className=\"hv-sheetcell hv-sheetcell--corner\" role=\"columnheader\" />\n {cols.map((c, i) => <div key={i} className=\"hv-sheetcell hv-sheetcell--header\" role=\"columnheader\">{c}</div>)}\n </div>\n {grid.map((row, r) => (\n <div key={r} className=\"hv-sheetrow\" role=\"row\">\n <div className=\"hv-sheetcell hv-sheetcell--header\" role=\"rowheader\">{r + 1}</div>\n {row.map((val, c) => (\n <div\n key={c}\n className=\"hv-sheetcell\"\n role=\"cell\"\n contentEditable={!readonly}\n suppressContentEditableWarning\n onInput={(e) => {\n const text = (e.currentTarget.textContent ?? '');\n setGrid((prev) => {\n const next = prev.map((rr) => rr.slice());\n next[r][c] = text;\n return next;\n });\n }}\n >{val}</div>\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n});\n\nfunction ensureExt(name: string, ext: string) {\n const base = name.includes('.') ? name.slice(0, name.lastIndexOf('.')) : name;\n return `${base}.${ext}`;\n}\n","import type { SupportedFileType } from '../types';\n\n/**\n * Guess the file type from a file name or explicit type.\n * @param name - The file name (optional)\n * @param explicit - Explicit file type (optional)\n * @returns SupportedFileType\n */\nexport function guessFileType(\n name?: string,\n explicit?: SupportedFileType,\n): SupportedFileType {\n if (explicit) { return explicit; }\n const ext = (name?.split('.').pop() || '').toLowerCase();\n const allowed: SupportedFileType[] = [\n 'pdf',\n 'md',\n 'docx',\n 'xlsx',\n 'pptx',\n 'txt',\n 'png',\n 'jpg',\n 'svg',\n ];\n return (allowed as string[]).includes(ext)\n ? (ext as SupportedFileType)\n : 'txt';\n}\n\n/**\n * Convert an ArrayBuffer to a base64 string.\n * @param buf - The ArrayBuffer to convert\n * @returns base64-encoded string\n */\nexport function arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n\n/**\n * Convert a base64 string to an ArrayBuffer.\n * @param b64 - The base64 string\n * @returns Promise<ArrayBuffer>\n */\nexport async function base64ToArrayBuffer(b64: string): Promise<ArrayBuffer> {\n const bin = atob(b64);\n const len = bin.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) { bytes[i] = bin.charCodeAt(i); }\n return bytes.buffer;\n}\n\n/**\n * Resolve a file source from a URL, base64, or Blob, with progress callback.\n * @param args - fileUrl, base64, or Blob, plus optional fileName, fileType, and onProgress\n * @returns Promise<{ fileType, fileName, arrayBuffer, url? }>\n */\nexport async function resolveSource(args: {\n fileUrl?: string;\n base64?: string;\n blob?: Blob;\n fileName?: string;\n fileType?: SupportedFileType;\n onProgress?: (loaded: number, total?: number) => void;\n}): Promise<{\n fileType: SupportedFileType;\n fileName: string;\n arrayBuffer: ArrayBuffer;\n url?: string;\n}> {\n const fileType = guessFileType(args.fileName, args.fileType);\n const fileName = args.fileName ?? `document.${fileType}`;\n\n if (args.blob) {\n const ab = await args.blob.arrayBuffer();\n const url = URL.createObjectURL(args.blob);\n return { fileType, fileName, arrayBuffer: ab, url };\n }\n\n if (args.base64) {\n const ab = await base64ToArrayBuffer(args.base64);\n return { fileType, fileName, arrayBuffer: ab };\n }\n\n if (!args.fileUrl) {\n throw new Error('No file source provided. Use fileUrl, blob, or base64.');\n }\n\n const res = await fetch(args.fileUrl);\n if (!res.ok) { throw new Error(`Failed to fetch file (${res.status})`); }\n\n const total = Number(res.headers.get('content-length') || '') || undefined;\n if (!res.body) {\n const ab = await res.arrayBuffer();\n args.onProgress?.(ab.byteLength, total);\n return { fileType, fileName, arrayBuffer: ab, url: args.fileUrl };\n }\n\n const reader = res.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) { break; }\n if (value) {\n chunks.push(value);\n loaded += value.length;\n args.onProgress?.(loaded, total);\n }\n }\n const out = new Uint8Array(loaded);\n let offset = 0;\n for (const c of chunks) {\n out.set(c, offset);\n offset += c.length;\n }\n return { fileType, fileName, arrayBuffer: out.buffer, url: args.fileUrl };\n}\n","'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport type { SupportedFileType } from '../types';\n\n/**\n * Image renderer for DocumentViewer.\n * Supports PNG, JPG, SVG, etc. with zoom controls.\n */\nexport function ImageRenderer({\n arrayBuffer,\n fileType,\n fileName,\n}: {\n /** Image file as ArrayBuffer (optional) */\n arrayBuffer?: ArrayBuffer;\n /** File type (e.g. 'png', 'jpg', 'svg') */\n fileType: SupportedFileType;\n /** File name for display */\n fileName: string;\n}) {\n const [zoom, setZoom] = useState(1);\n const url = useMemo(() => {\n if (!arrayBuffer) { return undefined; }\n const mime =\n fileType === 'svg'\n ? 'image/svg+xml'\n : fileType === 'png'\n ? 'image/png'\n : 'image/jpeg';\n return URL.createObjectURL(new Blob([arrayBuffer], { type: mime }));\n }, [arrayBuffer, fileType]);\n\n useEffect(() => {\n return () => {\n if (url) { URL.revokeObjectURL(url); }\n };\n }, [url]);\n\n return (\n <div className=\"hv-doc\">\n <div className=\"hv-mini-toolbar\">\n <div className=\"hv-title\">{fileName}</div>\n <div className=\"hv-spacer\" />\n <button\n type=\"button\"\n className=\"hv-btn\"\n onClick={() => setZoom((z) => Math.max(0.25, z - 0.25))}\n >\n -\n </button>\n <div className=\"hv-zoom\">{Math.round(zoom * 100)}%</div>\n <button\n type=\"button\"\n className=\"hv-btn\"\n onClick={() => setZoom((z) => Math.min(4, z + 0.25))}\n >\n +\n </button>\n </div>\n <div className=\"hv-center\">\n {!arrayBuffer && (\n <div className=\"hv-error\">No image data provided.</div>\n )}\n {arrayBuffer && !url && (\n <div className=\"hv-error\">Failed to load image.</div>\n )}\n {url && (\n <img\n src={url}\n alt={fileName}\n style={{ transform: `scale(${zoom})` }}\n className=\"hv-image\"\n />\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport {\n getDocument,\n GlobalWorkerOptions,\n type PDFDocumentProxy,\n} from \"pdfjs-dist\";\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport type { PageLayout } from \"../types\";\n\n/**\n * PDF document renderer for DocumentViewer.\n * Handles loading, error, and signature placement.\n */\nexport function PdfRenderer(props: {\n /** PDF file URL (optional) */\n url?: string;\n /** PDF file as ArrayBuffer (optional) */\n arrayBuffer?: ArrayBuffer;\n /** Page layout mode */\n layout: PageLayout;\n /** Current page number (1-based) */\n currentPage: number;\n /** Callback when current page changes */\n onCurrentPageChange: (p: number) => void;\n /** Callback when page count is determined */\n onPageCount: (n: number) => void;\n /** Callback for thumbnail images */\n onThumbs: (thumbs: Array<string | undefined>) => void;\n /** Signature stamp for placement (optional) */\n signatureStamp?: {\n imageUrl: string;\n armed: boolean;\n onPlaced: (placement: {\n page: number;\n x: number;\n y: number;\n w: number;\n h: number;\n }) => void;\n };\n}) {\n const { url, arrayBuffer } = props;\n const [doc, setDoc] = useState<PDFDocumentProxy | null>(null);\n const [pageCount, setPageCount] = useState(0);\n const [rendered, setRendered] = useState<Map<number, HTMLCanvasElement>>(\n new Map(),\n );\n const [thumbs, setThumbs] = useState<Array<string | undefined>>([]);\n const [size, setSize] = useState({ w: 840, h: 1188 });\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n try {\n GlobalWorkerOptions.workerSrc = new URL(\n \"pdfjs-dist/build/pdf.worker.min.mjs\",\n import.meta.url,\n ).toString();\n } catch {}\n }, []);\n\n useEffect(() => {\n let cancel = false;\n setError(null);\n setLoading(true);\n (async () => {\n setDoc(null);\n setRendered(new Map());\n setThumbs([]);\n if (!url && !arrayBuffer) {\n setError(\"No PDF source provided.\");\n setLoading(false);\n return;\n }\n try {\n const task = getDocument(\n url ? { url, rangeChunkSize: 512 * 1024 } : { data: arrayBuffer! },\n );\n const pdf = await task.promise;\n if (cancel) {\n return;\n }\n setDoc(pdf);\n setPageCount(pdf.numPages);\n props.onPageCount(pdf.numPages);\n\n // Get first page to determine aspect ratio and main render size\n const p1 = await pdf.getPage(1);\n const base = p1.getViewport({ scale: 1 });\n const w = Math.min(980, Math.max(640, base.width));\n const s = w / base.width;\n const vp = p1.getViewport({ scale: s });\n setSize({ w: Math.round(vp.width), h: Math.round(vp.height) });\n\n // Generate all thumbnails up front\n const thumbWidth = 56; // px, matches CSS .hv-thumbimg\n const thumbsArr: Array<string | undefined> = [];\n for (let i = 1; i <= pdf.numPages; i++) {\n const page = await pdf.getPage(i);\n const pageBase = page.getViewport({ scale: 1 });\n const thumbScale = thumbWidth / pageBase.width;\n const thumbVp = page.getViewport({ scale: thumbScale });\n const thumbCanvas = document.createElement(\"canvas\");\n thumbCanvas.width = Math.round(thumbVp.width);\n thumbCanvas.height = Math.round(thumbVp.height);\n const thumbCtx = thumbCanvas.getContext(\"2d\", { alpha: false });\n if (thumbCtx) {\n await page.render({ canvasContext: thumbCtx, viewport: thumbVp })\n .promise;\n thumbsArr.push(thumbCanvas.toDataURL(\"image/png\"));\n } else {\n thumbsArr.push(undefined);\n }\n }\n setThumbs(thumbsArr);\n } catch (e) {\n setError(\n \"Failed to load PDF. \" + (e instanceof Error ? e.message : \"\"),\n );\n } finally {\n setLoading(false);\n }\n })();\n return () => {\n cancel = true;\n };\n }, [url, arrayBuffer]);\n\n useEffect(() => {\n props.onThumbs(thumbs);\n }, [thumbs]);\n\n const pagesToShow = useMemo(() => {\n if (props.layout === \"side-by-side\" && pageCount > 1) {\n const left = Math.max(1, Math.min(props.currentPage, pageCount));\n const right = Math.max(1, Math.min(left + 1, pageCount));\n return left === right ? [left] : [left, right];\n }\n return [Math.max(1, Math.min(props.currentPage, pageCount))];\n }, [props.currentPage, props.layout, pageCount]);\n\n useEffect(() => {\n if (!doc) {\n return;\n }\n let cancel = false;\n (async () => {\n for (const p of pagesToShow) {\n if (rendered.has(p)) {\n continue;\n }\n try {\n const page = await doc.getPage(p);\n if (cancel) {\n return;\n }\n const base = page.getViewport({ scale: 1 });\n const vp = page.getViewport({ scale: size.w / base.width });\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.round(vp.width);\n canvas.height = Math.round(vp.height);\n const ctx = canvas.getContext(\"2d\", { alpha: false });\n if (!ctx) {\n continue;\n }\n await page.render({ canvasContext: ctx, viewport: vp }).promise;\n if (cancel) {\n return;\n }\n setRendered((prev) => {\n const next = new Map(prev);\n next.set(p, canvas);\n return next;\n });\n } catch {}\n }\n })();\n return () => {\n cancel = true;\n };\n }, [doc, pagesToShow, size.w, rendered]);\n\n function onWheel(e: React.WheelEvent) {\n if (!pageCount) {\n return;\n }\n if (Math.abs(e.deltaY) < 10) {\n return;\n }\n const dir = e.deltaY > 0 ? 1 : -1;\n const step = props.layout === \"side-by-side\" ? 2 : 1;\n const next = Math.max(\n 1,\n Math.min(pageCount, props.currentPage + dir * step),\n );\n props.onCurrentPageChange(next);\n }\n\n function clickPlace(e: React.MouseEvent, page: number) {\n const stamp = props.signatureStamp;\n if (!stamp?.armed) {\n return;\n }\n const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = (e.clientY - rect.top) / rect.height;\n stamp.onPlaced({ page, x, y, w: 0.22, h: 0.08 });\n }\n\n return (\n <div className=\"hv-doc\" ref={containerRef} onWheel={onWheel}>\n {!doc ? <div className=\"hv-loading\">Loading PDF…</div> : null}\n {doc ? (\n <div\n className={\n props.layout === \"side-by-side\"\n ? \"hv-pages hv-pages--two\"\n : \"hv-pages\"\n }\n >\n {pagesToShow.map((p) => {\n const c = rendered.get(p);\n return (\n <div\n key={p}\n className=\"hv-page\"\n style={{ width: size.w, height: size.h }}\n onClick={(e) => clickPlace(e, p)}\n >\n {c ? (\n <canvas\n className=\"hv-canvas\"\n width={c.width}\n height={c.height}\n ref={(node) => {\n if (!node) {\n return;\n }\n const ctx = node.getContext(\"2d\");\n if (ctx) {\n ctx.drawImage(c, 0, 0);\n }\n }}\n />\n ) : (\n <div className=\"hv-loading\">Rendering…</div>\n )}\n </div>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport JSZip from \"jszip\";\nimport type { PageLayout } from \"../types\";\n\ntype Slide = { index: number; text: string };\n\nfunction decodeXml(s: string): string {\n return s\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n}\n\nfunction extractText(xml: string) {\n return [...xml.matchAll(/<a:t>(.*?)<\\/a:t>/g)]\n .map((m) => decodeXml(m[1] || \"\"))\n .join(\" \")\n .trim();\n}\n\n/**\n * PowerPoint (.pptx) renderer for DocumentViewer.\n * Extracts and displays slide text, handles errors and loading.\n */\nexport function PptxRenderer(props: {\n /** PPTX file as ArrayBuffer (optional) */\n arrayBuffer?: ArrayBuffer;\n /** Page layout mode */\n layout: PageLayout;\n /** Current slide number (1-based) */\n currentPage: number;\n /** Callback when current slide changes */\n onCurrentPageChange: (p: number) => void;\n /** Callback when slide count is determined */\n onSlideCount: (n: number) => void;\n /** Callback for slide thumbnails */\n onThumbs: (thumbs: (string | undefined)[]) => void;\n}) {\n const [slides, setSlides] = useState<Slide[]>([]);\n const [thumbs, setThumbs] = useState<(string | undefined)[]>([]);\n\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n useEffect(() => {\n let cancel = false;\n setError(null);\n setLoading(true);\n (async () => {\n setSlides([]);\n setThumbs([]);\n if (!props.arrayBuffer) {\n setError(\"No PPTX source provided.\");\n setLoading(false);\n return;\n }\n try {\n // Load PPTX and extract slides (existing logic)\n const zip = await JSZip.loadAsync(props.arrayBuffer);\n const slidePaths = Object.keys(zip.files)\n .filter((p) => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(p))\n .sort();\n const slidesOut: Slide[] = [];\n for (let i = 0; i < slidePaths.length; i++) {\n const xml = await zip.files[slidePaths[i]].async(\"string\");\n slidesOut.push({ index: i + 1, text: extractText(xml) });\n }\n if (cancel) return;\n setSlides(\n slidesOut.length ? slidesOut : [{ index: 1, text: \"(empty)\" }],\n );\n props.onSlideCount(slidesOut.length || 1);\n\n // Generate all thumbnails up front (SVG placeholder for now)\n const thumbWidth = 56;\n const thumbsArr: (string | undefined)[] = [];\n for (let i = 0; i < (slidesOut.length || 1); i++) {\n thumbsArr.push(\n `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgThumb(i + 1))}`,\n );\n }\n setThumbs(thumbsArr);\n } catch (e) {\n setSlides([\n { index: 1, text: \"Unable to render this .pptx in-browser.\" },\n ]);\n setThumbs([undefined]);\n setError(\n \"Failed to load PPTX. \" + (e instanceof Error ? e.message : \"\"),\n );\n } finally {\n setLoading(false);\n }\n })();\n return () => {\n cancel = true;\n };\n }, [props.arrayBuffer]);\n // (removed unreachable/duplicate code after useEffect)\n\n useEffect(() => {\n props.onThumbs(thumbs);\n }, [thumbs]);\n\n const pagesToShow = useMemo(() => {\n const total = slides.length;\n if (props.layout === \"side-by-side\" && total > 1) {\n const left = Math.max(1, Math.min(props.currentPage, total));\n const right = Math.max(1, Math.min(left + 1, total));\n return left === right ? [left] : [left, right];\n }\n return [Math.max(1, Math.min(props.currentPage, total))];\n }, [props.currentPage, props.layout, slides.length]);\n\n return (\n <div className=\"hv-doc\">\n {loading && <div className=\"hv-loading\">Loading PPTX…</div>}\n {error && <div className=\"hv-error\">{error}</div>}\n {!loading && !error && (!slides || slides.length === 0) && (\n <div className=\"hv-error\">No slides to display.</div>\n )}\n {!error && slides && slides.length > 0 && (\n <div\n className={\n props.layout === \"side-by-side\"\n ? \"hv-pages hv-pages--two\"\n : \"hv-pages\"\n }\n >\n {pagesToShow.map((p) => {\n const s = slides[p - 1];\n return (\n <div\n key={p}\n className=\"hv-slide\"\n tabIndex={0}\n onFocus={() => props.onCurrentPageChange(p)}\n >\n <div className=\"hv-slide-title\">Slide {p}</div>\n <div className=\"hv-slide-text\">{s?.text || \"\"}</div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\nfunction svgThumb(n: number) {\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"180\" height=\"100\"><rect width=\"100%\" height=\"100%\" rx=\"12\" fill=\"#111827\"/><text x=\"50%\" y=\"54%\" font-size=\"18\" fill=\"#e5e7eb\" text-anchor=\"middle\">${n}</text></svg>`;\n}\n","/**\n * Default locale strings for the viewer UI.\n * You can override these by passing a `locale` prop to DocumentViewer.\n */\nexport const defaultLocale: Record<string, string> = {\n 'loading': 'Loading…',\n 'error.title': 'Error',\n 'toolbar.layout.single': 'Single page',\n 'toolbar.layout.two': 'Side-by-side',\n 'toolbar.thumbs': 'Thumbnails',\n 'toolbar.signatures': 'Signatures',\n 'toolbar.sign': 'Sign Document',\n 'toolbar.save': 'Save',\n 'toolbar.exportPdf': 'Export as PDF',\n 'thumbnails.title': 'Thumbnails',\n 'thumbnails.page': 'Page',\n 'signatures.title': 'Signatures',\n 'signatures.empty': 'No signatures',\n 'signatures.placeHint': 'Click on the document to place the signature.',\n 'a11y.viewer': 'Document viewer',\n 'a11y.ribbon': 'Ribbon',\n 'a11y.editor': 'Document editor',\n};\n","\"use client\";\n\nimport React from \"react\";\nimport type { Signature } from \"../types\";\n\nexport function SignaturePanel(props: {\n locale: Record<string, string>;\n signatures: Signature[];\n collapsed: boolean;\n onToggle: () => void;\n}) {\n const title = props.locale[\"signatures.title\"] ?? \"Signatures\";\n // Deduplicate signatures by signedBy, dateSigned, and image URL\n const deduped = React.useMemo(() => {\n const seen = new Set();\n return props.signatures.filter((s) => {\n const key = `${s.signedBy}|${s.dateSigned}|${s.signatureImageUrl}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n }, [props.signatures]);\n\n return (\n <aside\n className={props.collapsed ? \"hv-side hv-side--collapsed\" : \"hv-side\"}\n aria-label={title}\n >\n <div className=\"hv-sidebar-header\">\n <button\n type=\"button\"\n className=\"hv-icon\"\n onClick={props.onToggle}\n aria-label={props.locale[\"toolbar.signatures\"] ?? \"Signatures\"}\n >\n <span aria-hidden>✍</span>\n </button>\n <div className=\"hv-sidebar-title\">{title}</div>\n </div>\n <div className=\"hv-sidebar-body\">\n {deduped.length === 0 && (\n <div className=\"hv-signature-empty\" aria-live=\"polite\">\n {props.locale[\"signatures.empty\"] ?? \"No signatures yet.\"}\n </div>\n )}\n {deduped.map((s, idx) => (\n <div\n key={`${s.signedBy}-${s.dateSigned}-${s.signatureImageUrl}`}\n className=\"hv-signature-card\"\n tabIndex={0}\n aria-label={`Signature by ${s.signedBy}`}\n >\n <img\n src={s.signatureImageUrl}\n alt={\n props.locale[\"signatures.imgAlt\"]\n ? props.locale[\"signatures.imgAlt\"].replace(\n \"{name}\",\n s.signedBy,\n )\n : `Signature by ${s.signedBy}`\n }\n className=\"hv-signature-img\"\n />\n <div className=\"hv-signature-meta\">\n <div className=\"hv-signature-name\">{s.signedBy}</div>\n <div className=\"hv-signature-date\">\n {new Date(s.dateSigned).toLocaleString()}\n </div>\n {s.comment ? (\n <div className=\"hv-signature-comment\">{s.comment}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </aside>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\n\nexport interface Thumbnail {\n id: string;\n label: string;\n dataUrl?: string;\n}\n\nexport function ThumbnailsSidebar(props: {\n locale: Record<string, string>;\n thumbnails: Thumbnail[];\n currentPage: number;\n collapsed: boolean;\n onToggle: () => void;\n onSelectPage: (p: number) => void;\n}) {\n const t = props.locale[\"thumbnails.title\"] ?? \"Thumbnails\";\n return (\n <aside\n className={\n props.collapsed ? \"hv-thumbs hv-thumbs--collapsed\" : \"hv-thumbs\"\n }\n aria-label={t}\n >\n <div className=\"hv-thumbs-header\">\n <button\n type=\"button\"\n className=\"hv-thumbs-toggle\"\n onClick={props.onToggle}\n aria-label={\n props.collapsed\n ? (props.locale[\"thumbnails.open\"] ?? \"Open thumbnails\")\n : (props.locale[\"thumbnails.close\"] ?? \"Close thumbnails\")\n }\n >\n <span className=\"hv-thumbs-toggle-icon\">\n {props.collapsed ? \"▸\" : \"▾\"}\n </span>\n </button>\n {!props.collapsed && <div className=\"hv-thumbs-title\">{t}</div>}\n </div>\n {!props.collapsed && (\n <div className=\"hv-thumbs-list\" role=\"list\">\n {props.thumbnails.map((th, idx) => {\n const p = idx + 1;\n const active = p === props.currentPage;\n return (\n <button\n key={th.id}\n type=\"button\"\n role=\"listitem\"\n className={active ? \"hv-thumb hv-thumb--active\" : \"hv-thumb\"}\n onClick={() => props.onSelectPage(p)}\n aria-current={active ? \"page\" : undefined}\n tabIndex={0}\n >\n <div className=\"hv-thumb-img\" aria-hidden>\n {th.dataUrl ? (\n <img src={th.dataUrl} alt=\"\" />\n ) : (\n <div className=\"hv-thumb-placeholder\" />\n )}\n </div>\n <div className=\"hv-thumb-label\">{th.label}</div>\n </button>\n );\n })}\n </div>\n )}\n </aside>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport type { DocumentMode, PageLayout, SupportedFileType } from \"../types\";\n\nexport function Toolbar(props: {\n locale: Record<string, string>;\n mode: DocumentMode;\n fileType?: SupportedFileType;\n layout: PageLayout;\n onChangeLayout: (l: PageLayout) => void;\n showThumbnails: boolean;\n onToggleThumbnails: () => void;\n showSignatures: boolean;\n onToggleSignatures: () => void;\n allowSigning: boolean;\n signingDisabled: boolean;\n onSign: () => void;\n canSave: boolean;\n onSave: () => void;\n canExportPdf: boolean;\n onExportPdf: () => void;\n showHeaderFooterToggle: boolean;\n headerFooterEnabled: boolean;\n onToggleHeaderFooter: () => void;\n}) {\n const t = (k: string, fallback: string) => props.locale[k] ?? fallback;\n\n return (\n <div\n className=\"hv-toolbar\"\n role=\"toolbar\"\n aria-label={t(\"a11y.toolbar\", \"Document toolbar\")}\n >\n {/* LEFT */}\n <div className=\"hv-toolbar__group\">\n <button\n className={`hv-btn ${props.showThumbnails ? \"hv-btn--active\" : \"\"}`}\n onClick={props.onToggleThumbnails}\n aria-pressed={props.showThumbnails}\n >\n Thumbnails\n </button>\n\n {props.mode !== \"create\" && (\n <button\n className={`hv-btn ${props.showSignatures ? \"hv-btn--active\" : \"\"}`}\n onClick={props.onToggleSignatures}\n aria-pressed={props.showSignatures}\n >\n Signatures\n </button>\n )}\n </div>\n\n {/* CENTER */}\n <div className=\"hv-toolbar__group hv-segment\">\n <button\n className={`hv-btn ${props.layout === \"single\" ? \"hv-btn--active\" : \"\"}`}\n onClick={() => props.onChangeLayout(\"single\")}\n >\n Single page\n </button>\n <button\n className={`hv-btn ${props.layout === \"side-by-side\" ? \"hv-btn--active\" : \"\"}`}\n onClick={() => props.onChangeLayout(\"side-by-side\")}\n >\n Side-by-side\n </button>\n </div>\n\n {/* RIGHT */}\n <div className=\"hv-toolbar__group hv-toolbar__actions\">\n {props.showHeaderFooterToggle && (\n <label className=\"hv-switch\">\n <input\n type=\"checkbox\"\n checked={props.headerFooterEnabled}\n onChange={props.onToggleHeaderFooter}\n />\n <span className=\"hv-switch__slider\" />\n <span className=\"hv-switch__label\">\n {t(\"toolbar.letterhead\", \"Letterhead\")}\n </span>\n </label>\n )}\n\n {props.allowSigning && (\n <button\n className=\"hv-btn hv-btn--primary\"\n onClick={props.onSign}\n disabled={props.signingDisabled}\n >\n Sign document\n </button>\n )}\n\n {props.canExportPdf && (\n <button className=\"hv-btn\" onClick={props.onExportPdf}>\n Export PDF\n </button>\n )}\n\n {props.canSave && (\n <button className=\"hv-btn hv-btn--primary\" onClick={props.onSave}>\n Save\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useMemo","useRef","useState","forwardRef","useEffect","useImperativeHandle","useMemo","useState","jsx","jsxs","forwardRef","SpreadsheetEditor","useState","useEffect","cols","_","useImperativeHandle","useMemo","useEffect","useMemo","useState","jsx","jsxs","useEffect","useMemo","useRef","useState","jsx","jsxs","useEffect","useMemo","useState","jsx","jsxs","React","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","useMemo","useState","useEffect","useRef","arrayBufferToBase64"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/components/DocumentViewer.tsx","../src/editors/RichTextEditor.tsx","../src/utils/sanitize.ts","../src/editors/SpreadsheetEditor.tsx","../src/renderers/ImageRenderer.tsx","../src/renderers/PdfRenderer.tsx","../src/renderers/PptxRenderer.tsx","../src/utils/fileSource.ts","../src/components/ThumbnailsSidebar.tsx","../src/components/Toolbar.tsx","../src/components/SignaturePanel.tsx"],"sourcesContent":["export { DocumentViewer } from './components/DocumentViewer';\nexport type { DocumentViewerProps, DocumentMode, PageLayout, Signature, SupportedFileType, DocumentViewerSaveMeta } from './types';\n","\"use client\";\r\n\r\nimport React, { useEffect, useState } from \"react\";\r\nimport { RichTextEditor } from \"../editors/RichTextEditor\";\r\nimport { SpreadsheetEditor } from \"../editors/SpreadsheetEditor\";\r\nimport { ImageRenderer } from \"../renderers/ImageRenderer\";\r\nimport { PdfRenderer } from \"../renderers/PdfRenderer\";\r\nimport { PptxRenderer } from \"../renderers/PptxRenderer\";\r\nimport type {\r\n DocumentMode,\r\n DocumentViewerProps,\r\n SupportedFileType,\r\n Signature, // Import Signature from here\r\n} from \"../types\";\r\nimport { resolveSource } from \"../utils/fileSource\";\r\n\r\n// Components\r\nimport { ThumbnailsSidebar } from \"./ThumbnailsSidebar\";\r\nimport { Toolbar } from \"./Toolbar\";\r\nimport { SignaturePanel } from \"./SignaturePanel\";\r\n\r\nexport function DocumentViewer(props: DocumentViewerProps) {\r\n // --- State & Config ---\r\n const mode: DocumentMode = props.mode ?? \"view\";\r\n const theme = props.theme ?? \"light\";\r\n\r\n // Layout State\r\n const [layout, setLayout] = useState<\"single\" | \"side-by-side\">(\r\n props.defaultLayout ?? \"single\",\r\n );\r\n const [showThumbnails, setShowThumbnails] = useState(\r\n props.defaultShowThumbnails ?? true,\r\n );\r\n const [showSignatures, setShowSignatures] = useState(false); // [2] New State for Right Sidebar\r\n\r\n // Data Loading State\r\n const [resolved, setResolved] = useState<{\r\n fileType: SupportedFileType;\r\n fileName: string;\r\n url?: string;\r\n arrayBuffer?: ArrayBuffer;\r\n } | null>(null);\r\n\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string>(\"\");\r\n\r\n // Viewer Context (Page Counts, etc)\r\n const [pageCount, setPageCount] = useState(1);\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [thumbnails, setThumbnails] = useState<string[]>([]);\r\n\r\n // --- Effects ---\r\n\r\n // 1. Resolve File Source\r\n useEffect(() => {\r\n let active = true;\r\n\r\n const loadFile = async () => {\r\n setLoading(true);\r\n setError(\"\");\r\n setResolved(null);\r\n\r\n try {\r\n if (mode === \"create\") {\r\n // Handle creation mode\r\n setResolved({\r\n fileType: (props.fileType ?? \"docx\") as SupportedFileType,\r\n fileName: props.fileName ?? \"Untitled\",\r\n });\r\n } else {\r\n // Handle view/edit mode\r\n const res = await resolveSource({\r\n fileUrl: props.fileUrl,\r\n base64: props.base64,\r\n blob: props.blob,\r\n fileName: props.fileName,\r\n fileType: props.fileType,\r\n });\r\n if (active) setResolved(res);\r\n }\r\n } catch (err: any) {\r\n if (active) setError(err.message || \"Failed to load document\");\r\n } finally {\r\n if (active) setLoading(false);\r\n }\r\n };\r\n\r\n loadFile();\r\n return () => {\r\n active = false;\r\n };\r\n }, [props.fileUrl, props.base64, props.blob, mode]);\r\n\r\n // --- Signature Handler [3] ---\r\n const handleSignatureSelect = (sig: Signature) => {\r\n // Return value to user via prop if available\r\n if (props.onSign) {\r\n props.onSign(sig);\r\n }\r\n\r\n // Logic to place signature on document would go here\r\n console.log(\"Signature selected:\", sig);\r\n\r\n // Optional: Auto-close sidebar after selection\r\n // setShowSignatures(false);\r\n };\r\n\r\n // --- Render Helpers ---\r\n\r\n const renderContent = () => {\r\n if (error) {\r\n return (\r\n <div className=\"hv-error-banner\">\r\n <strong>Error loading document</strong>\r\n <p>{error}</p>\r\n </div>\r\n );\r\n }\r\n\r\n if (loading || !resolved) {\r\n return (\r\n <div className=\"hv-loader\">\r\n <div className=\"hv-spinner\" />\r\n <span>Loading Document...</span>\r\n </div>\r\n );\r\n }\r\n\r\n const commonProps = {\r\n arrayBuffer: resolved.arrayBuffer,\r\n fileName: resolved.fileName,\r\n fileType: resolved.fileType,\r\n layout,\r\n currentPage,\r\n onPageCount: setPageCount,\r\n onCurrentPageChange: setCurrentPage,\r\n onThumbs: setThumbnails,\r\n };\r\n\r\n switch (resolved.fileType) {\r\n case \"pdf\":\r\n return <PdfRenderer url={resolved.url} {...commonProps} />;\r\n\r\n case \"docx\":\r\n case \"doc\":\r\n case \"rtf\":\r\n case \"txt\":\r\n case \"md\":\r\n return <RichTextEditor mode={mode} {...commonProps} />;\r\n\r\n case \"xlsx\":\r\n case \"csv\":\r\n case \"xls\":\r\n return <SpreadsheetEditor mode={mode} {...commonProps} />;\r\n\r\n case \"pptx\":\r\n case \"ppt\":\r\n return <PptxRenderer {...commonProps} />;\r\n\r\n case \"jpg\":\r\n case \"jpeg\":\r\n case \"png\":\r\n case \"gif\":\r\n case \"bmp\":\r\n case \"svg\":\r\n return <ImageRenderer {...commonProps} fileType={resolved.fileType} />;\r\n\r\n default:\r\n return (\r\n <div className=\"hv-error-banner\">\r\n Unsupported file type: {resolved.fileType}\r\n </div>\r\n );\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"hv-root\" data-hv-theme={theme}>\r\n {/* 1. Toolbar */}\r\n <Toolbar\r\n fileName={resolved?.fileName}\r\n pageCount={pageCount}\r\n currentPage={currentPage}\r\n onPageChange={setCurrentPage}\r\n layout={layout}\r\n onLayoutChange={setLayout}\r\n // Left Sidebar (Thumbnails)\r\n showThumbnails={showThumbnails}\r\n onToggleThumbnails={() => setShowThumbnails(!showThumbnails)}\r\n // Right Sidebar (Signatures) - [4] Replaced Download with Signature Toggle\r\n showSignatures={showSignatures}\r\n onToggleSignatures={() => setShowSignatures(!showSignatures)}\r\n disableSigning={props.disableSigning}\r\n />\r\n\r\n <div className=\"hv-shell\">\r\n {/* 2. Left Sidebar (Thumbnails) */}\r\n <ThumbnailsSidebar\r\n isOpen={showThumbnails}\r\n thumbnails={thumbnails}\r\n currentPage={currentPage}\r\n onSelectPage={setCurrentPage}\r\n />\r\n\r\n {/* 3. Main Stage */}\r\n <main className=\"hv-main\">{renderContent()}</main>\r\n\r\n {/* 4. Right Sidebar (Signatures) - [5] Added Component */}\r\n <SignaturePanel\r\n isOpen={showSignatures}\r\n onClose={() => setShowSignatures(false)}\r\n onSelectSignature={handleSignatureSelect}\r\n externalSignatures={props.signatures}\r\n onSignRequest={props.onSignRequest}\r\n />\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport mammoth from \"mammoth\";\r\nimport React, { useEffect, useRef, useState } from \"react\";\r\nimport MarkdownIt from \"markdown-it\";\r\nimport type { DocumentMode, SupportedFileType } from \"../types\";\r\nimport { sanitizeHtml } from \"../utils/sanitize\";\r\n\r\ninterface RichTextEditorProps {\r\n mode: DocumentMode;\r\n arrayBuffer?: ArrayBuffer;\r\n fileName: string;\r\n // We need fileType to know how to parse (md vs docx)\r\n fileType?: SupportedFileType;\r\n layout: \"single\" | \"side-by-side\";\r\n currentPage: number;\r\n onPageCount: (n: number) => void;\r\n onCurrentPageChange: (p: number) => void;\r\n onThumbs: (thumbs: string[]) => void;\r\n}\r\n\r\nexport function RichTextEditor(props: RichTextEditorProps) {\r\n const editorRef = useRef<HTMLDivElement>(null);\r\n const [contentHtml, setContentHtml] = useState<string>(\"\");\r\n const [loading, setLoading] = useState(false);\r\n\r\n // Initialize Markdown parser once\r\n const mdParser = useRef(new MarkdownIt({ html: true, linkify: true }));\r\n\r\n useEffect(() => {\r\n const loadDoc = async () => {\r\n if (!props.arrayBuffer) return;\r\n setLoading(true);\r\n\r\n try {\r\n // 1. Handle DOCX\r\n if (props.fileName.endsWith(\".docx\") || props.fileType === \"docx\") {\r\n const result = await mammoth.convertToHtml({\r\n arrayBuffer: props.arrayBuffer,\r\n });\r\n setContentHtml(sanitizeHtml(result.value));\r\n }\r\n // 2. Handle Markdown / Text\r\n else {\r\n // Decode the buffer to string\r\n const decoder = new TextDecoder(\"utf-8\");\r\n const text = decoder.decode(props.arrayBuffer);\r\n\r\n if (props.fileName.endsWith(\".md\") || props.fileType === \"md\") {\r\n // Render Markdown to HTML\r\n const html = mdParser.current.render(text);\r\n setContentHtml(sanitizeHtml(html));\r\n } else {\r\n // Plain text: wrap in pre/p\r\n setContentHtml(\r\n `<pre style=\"white-space: pre-wrap; font-family: monospace;\">${text}</pre>`,\r\n );\r\n }\r\n }\r\n\r\n props.onPageCount(1);\r\n } catch (err) {\r\n console.error(\"Doc Conversion failed\", err);\r\n setContentHtml(\"<p style='color:red'>Error parsing document.</p>\");\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n loadDoc();\r\n }, [props.arrayBuffer, props.fileName, props.fileType]);\r\n\r\n return (\r\n <div className=\"hv-view-single\">\r\n <div className=\"hv-page-container\">\r\n {loading ? (\r\n <div className=\"p-12 text-center text-gray-400\">\r\n Processing text...\r\n </div>\r\n ) : (\r\n <div\r\n ref={editorRef}\r\n className=\"hv-docx-content\"\r\n contentEditable={props.mode === \"edit\" || props.mode === \"create\"}\r\n dangerouslySetInnerHTML={{ __html: contentHtml }}\r\n suppressContentEditableWarning\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import DOMPurify from 'dompurify';\n\n/**\n * Sanitize HTML using DOMPurify for safe rendering.\n * @param html - The HTML string to sanitize\n * @returns Safe HTML string\n */\nexport function sanitizeHtml(html: string): string {\n // DOMPurify is safe to call in the browser. For SSR, callers should only run after mount.\n return DOMPurify.sanitize(html, {\n USE_PROFILES: { html: true },\n ADD_ATTR: ['target', 'rel'],\n });\n}\n","\"use client\";\n\nimport React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from \"react\";\nimport * as XLSX from \"xlsx\";\nimport type { DocumentMode, SupportedFileType } from \"../types\";\n\nexport interface SpreadsheetEditorHandle {\n save: (exportPdf?: boolean) => Promise<void>;\n}\n\ninterface SpreadsheetEditorProps {\n mode: DocumentMode;\n fileName: string;\n arrayBuffer?: ArrayBuffer;\n layout?: \"single\" | \"side-by-side\";\n onSave?: (base64: string, meta: any) => void;\n}\n\nexport const SpreadsheetEditor = forwardRef<\n SpreadsheetEditorHandle,\n SpreadsheetEditorProps\n>(function SpreadsheetEditor(props, ref) {\n const readonly = props.mode === \"view\";\n const [data, setData] = useState<string[][]>([]);\n const [cols, setCols] = useState<string[]>([]);\n\n useEffect(() => {\n if (!props.arrayBuffer) return;\n\n try {\n const wb = XLSX.read(props.arrayBuffer, { type: \"array\" });\n const wsName = wb.SheetNames[0];\n const ws = wb.Sheets[wsName];\n\n const jsonData = XLSX.utils.sheet_to_json(ws, {\n header: 1,\n defval: \"\",\n }) as string[][];\n\n const minRows = 40;\n const minCols = 15;\n\n const rows = Math.max(minRows, jsonData.length);\n const colCount = Math.max(minCols, jsonData[0]?.length || 0);\n\n const normalized = Array.from({ length: rows }, (_, r) => {\n const row = jsonData[r] || [];\n return Array.from({ length: colCount }, (_, c) =>\n row[c] !== undefined && row[c] !== null ? String(row[c]) : \"\",\n );\n });\n\n setData(normalized);\n\n const headers = Array.from({ length: colCount }, (_, i) => {\n let letter = \"\";\n let temp = i;\n while (temp >= 0) {\n letter = String.fromCharCode((temp % 26) + 65) + letter;\n temp = Math.floor(temp / 26) - 1;\n }\n return letter;\n });\n setCols(headers);\n } catch (e) {\n console.error(\"Spreadsheet load error:\", e);\n }\n }, [props.arrayBuffer]);\n\n async function save(exportPdf?: boolean) {\n if (!props.onSave) return;\n const ws = XLSX.utils.aoa_to_sheet(data);\n const wb = XLSX.utils.book_new();\n XLSX.utils.book_append_sheet(wb, ws, \"Sheet1\");\n const out = XLSX.write(wb, { type: \"array\", bookType: \"xlsx\" });\n\n const bytes = new Uint8Array(out);\n let binary = \"\";\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n props.onSave(btoa(binary), {\n fileName: props.fileName,\n fileType: \"xlsx\",\n exportedAsPdf: !!exportPdf,\n });\n }\n\n useImperativeHandle(ref, () => ({ save }));\n\n return (\n <div className=\"hv-view-single\">\n <div\n className=\"hv-page-container\"\n style={{\n width: \"auto\",\n maxWidth: \"95vw\",\n minWidth: \"800px\",\n padding: 0,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {/* Toolbar / Formula Bar */}\n <div\n style={{\n background: \"#f8f9fa\",\n borderBottom: \"1px solid #e2e8f0\",\n padding: \"8px 16px\",\n fontSize: \"12px\",\n color: \"#64748b\",\n display: \"flex\",\n gap: \"12px\",\n flexShrink: 0,\n }}\n >\n <span>fx</span>\n <div\n style={{\n background: \"white\",\n border: \"1px solid #cbd5e1\",\n flex: 1,\n height: \"18px\",\n borderRadius: \"2px\",\n }}\n />\n </div>\n\n {/* Main Grid Container */}\n <div\n style={{\n overflow: \"auto\",\n // FIX: Dynamic height ensures bottom isn't cut off on small screens\n maxHeight: \"calc(100vh - 140px)\",\n minHeight: \"400px\",\n position: \"relative\",\n // FIX: Padding prevents border clipping (first row/col edges)\n padding: \"1px\",\n }}\n >\n <table\n style={{\n borderCollapse: \"collapse\",\n minWidth: \"100%\",\n tableLayout: \"fixed\",\n }}\n >\n <thead>\n <tr>\n {/* Corner Cell */}\n <th\n style={{\n width: \"40px\",\n background: \"#f1f5f9\",\n border: \"1px solid #cbd5e1\",\n position: \"sticky\",\n top: 0,\n left: 0,\n zIndex: 30, // Increased zIndex\n }}\n />\n\n {/* Column Headers */}\n {cols.map((col, i) => (\n <th\n key={i}\n style={{\n minWidth: \"100px\",\n background: \"#f1f5f9\",\n border: \"1px solid #cbd5e1\",\n color: \"#475569\",\n fontSize: \"11px\",\n fontWeight: 600,\n padding: \"4px\",\n position: \"sticky\",\n top: 0,\n zIndex: 20, // Increased zIndex\n }}\n >\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((row, r) => (\n <tr key={r}>\n {/* Row Header (1, 2, 3...) */}\n <td\n style={{\n background: \"#f1f5f9\",\n border: \"1px solid #cbd5e1\",\n textAlign: \"center\",\n fontSize: \"11px\",\n color: \"#64748b\",\n position: \"sticky\",\n left: 0,\n zIndex: 20, // Increased zIndex to stay above cells\n }}\n >\n {r + 1}\n </td>\n\n {/* Cells */}\n {row.map((cell, c) => (\n <td\n key={c}\n contentEditable={!readonly}\n suppressContentEditableWarning\n onBlur={(e) => {\n const val = e.currentTarget.innerText;\n setData((prev) => {\n const next = [...prev];\n next[r] = [...next[r]];\n next[r][c] = val;\n return next;\n });\n }}\n style={{\n border: \"1px solid #e2e8f0\",\n padding: \"4px 8px\",\n fontSize: \"13px\",\n color: \"#1e293b\",\n minWidth: \"100px\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n outline: \"none\",\n zIndex: 1,\n }}\n >\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n );\n});\n","\"use client\";\r\n\r\nimport React, { useEffect, useMemo, useState } from \"react\";\r\nimport type { SupportedFileType } from \"../types\";\r\n\r\n/**\r\n * Image renderer for DocumentViewer.\r\n * Supports PNG, JPG, SVG, etc. with zoom controls.\r\n */\r\nexport function ImageRenderer({\r\n arrayBuffer,\r\n fileType,\r\n fileName,\r\n}: {\r\n /** Image file as ArrayBuffer (optional) */\r\n arrayBuffer?: ArrayBuffer;\r\n /** File type (e.g. 'png', 'jpg', 'svg') */\r\n fileType: SupportedFileType;\r\n /** File name for display */\r\n fileName: string;\r\n}) {\r\n const [zoom, setZoom] = useState(1);\r\n const url = useMemo(() => {\r\n if (!arrayBuffer) {\r\n return undefined;\r\n }\r\n const mime =\r\n fileType === \"svg\"\r\n ? \"image/svg+xml\"\r\n : fileType === \"png\"\r\n ? \"image/png\"\r\n : \"image/jpeg\";\r\n return URL.createObjectURL(new Blob([arrayBuffer], { type: mime }));\r\n }, [arrayBuffer, fileType]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (url) {\r\n URL.revokeObjectURL(url);\r\n }\r\n };\r\n }, [url]);\r\n\r\n return (\r\n <div className=\"flex flex-col h-full bg-gray-50\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between px-6 py-4 bg-white border-b border-gray-200\">\r\n <h2 className=\"text-sm font-medium text-gray-700 truncate max-w-md\">\r\n {fileName}\r\n </h2>\r\n\r\n {/* Zoom Controls */}\r\n <div className=\"flex items-center gap-3 bg-gray-100 rounded-lg p-1\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setZoom((z) => Math.max(0.25, z - 0.25))}\r\n className=\"w-9 h-9 flex items-center justify-center rounded-md bg-white hover:bg-gray-50 text-gray-700 transition-all shadow-sm hover:shadow\"\r\n aria-label=\"Zoom out\"\r\n >\r\n <svg\r\n className=\"w-4 h-4\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M20 12H4\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <span className=\"text-sm font-semibold text-gray-700 min-w-[3.5rem] text-center px-2\">\r\n {Math.round(zoom * 100)}%\r\n </span>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => setZoom((z) => Math.min(4, z + 0.25))}\r\n className=\"w-9 h-9 flex items-center justify-center rounded-md bg-white hover:bg-gray-50 text-gray-700 transition-all shadow-sm hover:shadow\"\r\n aria-label=\"Zoom in\"\r\n >\r\n <svg\r\n className=\"w-4 h-4\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M12 4v16m8-8H4\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Image Container */}\r\n <div className=\"flex-1 overflow-auto flex items-center justify-center p-8\">\r\n {!arrayBuffer && (\r\n <div className=\"text-center\">\r\n <div className=\"w-16 h-16 mx-auto mb-3 rounded-full bg-gray-200 flex items-center justify-center\">\r\n <svg\r\n className=\"w-8 h-8 text-gray-400\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\r\n />\r\n </svg>\r\n </div>\r\n <p className=\"text-sm text-gray-500\">No image data provided</p>\r\n </div>\r\n )}\r\n\r\n {arrayBuffer && !url && (\r\n <div className=\"text-center\">\r\n <div className=\"w-16 h-16 mx-auto mb-3 rounded-full bg-red-100 flex items-center justify-center\">\r\n <svg\r\n className=\"w-8 h-8 text-red-500\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\r\n />\r\n </svg>\r\n </div>\r\n <p className=\"text-sm text-gray-600\">Failed to load image</p>\r\n </div>\r\n )}\r\n\r\n {url && (\r\n <div\r\n style={{ transform: `scale(${zoom})` }}\r\n className=\"transition-transform duration-200 origin-center\"\r\n >\r\n <img\r\n src={url}\r\n alt={fileName}\r\n style={{ transform: `scale(${zoom})` }}\r\n className=\"max-w-full h-auto rounded-lg shadow-lg transition-transform duration-200\"\r\n />\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport {\r\n getDocument,\r\n GlobalWorkerOptions,\r\n type PDFDocumentProxy,\r\n} from \"pdfjs-dist\";\r\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\r\nimport type { PageLayout } from \"../types\";\r\n\r\n// FIX 1: Updated version to match the error message (4.10.38)\r\nconst PDF_WORKER_URL =\r\n \"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.10.38/pdf.worker.min.mjs\";\r\n\r\ninterface PdfRendererProps {\r\n url?: string;\r\n arrayBuffer?: ArrayBuffer;\r\n layout: PageLayout;\r\n currentPage: number;\r\n onPageCount: (n: number) => void;\r\n onCurrentPageChange: (p: number) => void;\r\n onThumbs: (thumbs: string[]) => void;\r\n}\r\n\r\nexport function PdfRenderer(props: PdfRendererProps) {\r\n const { url, arrayBuffer, layout, currentPage } = props;\r\n const [doc, setDoc] = useState<PDFDocumentProxy | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n // Ensure worker is set up\r\n if (!GlobalWorkerOptions.workerSrc) {\r\n GlobalWorkerOptions.workerSrc = PDF_WORKER_URL;\r\n }\r\n\r\n let active = true;\r\n\r\n const loadPdf = async () => {\r\n // If no source, do nothing\r\n if (!url && !arrayBuffer) return;\r\n\r\n setError(null);\r\n\r\n try {\r\n // FIX 2: Clone the ArrayBuffer!\r\n // PDF.js transfers the buffer to the worker, which \"detaches\" (empties) the original.\r\n // We pass a slice (copy) so the original data in DocumentViewer remains valid.\r\n const dataSource = arrayBuffer\r\n ? { data: arrayBuffer.slice(0) }\r\n : { url: url! };\r\n\r\n const loadingTask = getDocument(dataSource);\r\n\r\n const pdf = await loadingTask.promise;\r\n\r\n if (active) {\r\n setDoc(pdf);\r\n props.onPageCount(pdf.numPages);\r\n generateThumbnails(pdf);\r\n }\r\n } catch (err: any) {\r\n // Quietly handle errors (e.g. password protected files)\r\n console.error(\"PDF Load Error:\", err);\r\n if (active) setError(err.message || \"Failed to load PDF\");\r\n }\r\n };\r\n\r\n loadPdf();\r\n return () => {\r\n active = false;\r\n };\r\n }, [url, arrayBuffer]); // Re-run if file changes\r\n\r\n const generateThumbnails = async (pdf: PDFDocumentProxy) => {\r\n try {\r\n const thumbs: string[] = [];\r\n const num = Math.min(pdf.numPages, 5);\r\n for (let i = 1; i <= num; i++) {\r\n const page = await pdf.getPage(i);\r\n const viewport = page.getViewport({ scale: 0.2 });\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.width = viewport.width;\r\n canvas.height = viewport.height;\r\n\r\n const ctx = canvas.getContext(\"2d\");\r\n if (ctx) {\r\n await page.render({ canvasContext: ctx, viewport }).promise;\r\n thumbs.push(canvas.toDataURL());\r\n }\r\n }\r\n props.onThumbs(thumbs);\r\n } catch (e) {\r\n /* ignore */\r\n }\r\n };\r\n\r\n const pagesToRender = useMemo(() => {\r\n if (!doc) return [];\r\n const p = Math.max(1, Math.min(currentPage, doc.numPages));\r\n if (layout === \"side-by-side\" && doc.numPages > 1) {\r\n if (p === 1) return [1];\r\n const left = p % 2 === 0 ? p : p - 1;\r\n return left + 1 <= doc.numPages ? [left, left + 1] : [left];\r\n }\r\n return [p];\r\n }, [doc, currentPage, layout]);\r\n\r\n if (error) {\r\n return (\r\n <div\r\n className=\"hv-page-container\"\r\n style={{ padding: \"32px\", textAlign: \"center\", color: \"#dc2626\" }}\r\n >\r\n <strong>Error loading PDF</strong>\r\n <p className=\"text-sm mt-2\">{error}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={`hv-doc-scroll ${layout === \"side-by-side\" ? \"hv-view-double\" : \"hv-view-single\"}`}\r\n >\r\n {pagesToRender.map((page) => (\r\n <PdfPage key={page} doc={doc} pageNum={page} />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction PdfPage({\r\n doc,\r\n pageNum,\r\n}: {\r\n doc: PDFDocumentProxy | null;\r\n pageNum: number;\r\n}) {\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n\r\n useEffect(() => {\r\n if (!doc || !canvasRef.current) return;\r\n let active = true;\r\n\r\n const render = async () => {\r\n try {\r\n const page = await doc.getPage(pageNum);\r\n if (!active) return;\r\n\r\n const scale = 1.5; // High fidelity\r\n const viewport = page.getViewport({ scale });\r\n const canvas = canvasRef.current!;\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return;\r\n\r\n canvas.width = viewport.width;\r\n canvas.height = viewport.height;\r\n\r\n canvas.style.width = `${viewport.width / scale}px`;\r\n canvas.style.height = `${viewport.height / scale}px`;\r\n\r\n await page.render({ canvasContext: ctx, viewport }).promise;\r\n } catch (e) {\r\n console.error(\"Page render error:\", e);\r\n }\r\n };\r\n render();\r\n return () => {\r\n active = false;\r\n };\r\n }, [doc, pageNum]);\r\n\r\n return (\r\n <div\r\n className=\"hv-page-container\"\r\n style={{\r\n minHeight: \"600px\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n }}\r\n >\r\n <canvas ref={canvasRef} className=\"hv-pdf-canvas\" />\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport React, { useEffect, useMemo, useState } from \"react\";\r\nimport JSZip from \"jszip\";\r\nimport type { PageLayout } from \"../types\";\r\n\r\n// --- XML Parsing Helpers (Preserved from your original code) ---\r\nconst NS_P = \"http://schemas.openxmlformats.org/presentationml/2006/main\";\r\nconst NS_A = \"http://schemas.openxmlformats.org/drawingml/2006/main\";\r\n\r\nfunction parseColor(solidFill: Element | null): string | undefined {\r\n if (!solidFill) return undefined;\r\n const srgbClr = solidFill.getElementsByTagNameNS(NS_A, \"srgbClr\")[0];\r\n if (srgbClr) {\r\n const val = srgbClr.getAttribute(\"val\");\r\n return val ? `#${val}` : undefined;\r\n }\r\n const schemeClr = solidFill.getElementsByTagNameNS(NS_A, \"schemeClr\")[0];\r\n if (schemeClr) {\r\n const val = schemeClr.getAttribute(\"val\");\r\n const colorMap: Record<string, string> = {\r\n tx1: \"#000000\",\r\n bg1: \"#FFFFFF\",\r\n tx2: \"#1F1F1F\",\r\n accent1: \"#4472C4\",\r\n accent2: \"#ED7D31\",\r\n accent3: \"#A5A5A5\",\r\n accent4: \"#FFC000\",\r\n accent5: \"#5B9BD5\",\r\n accent6: \"#70AD47\",\r\n };\r\n return colorMap[val || \"\"] || \"#000000\";\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction parseSlideXml(xml: string) {\r\n const parser = new DOMParser();\r\n const doc = parser.parseFromString(xml, \"application/xml\");\r\n\r\n let title: string | undefined;\r\n let titleColor: string | undefined;\r\n let bgColor: string | undefined;\r\n\r\n const body: Array<{\r\n text: string;\r\n color?: string;\r\n isBold?: boolean;\r\n isItalic?: boolean;\r\n }> = [];\r\n\r\n // Background\r\n const bgElements = doc.getElementsByTagNameNS(NS_P, \"bg\");\r\n if (bgElements.length > 0) {\r\n const bgPr = bgElements[0].getElementsByTagNameNS(NS_P, \"bgPr\")[0];\r\n if (bgPr) {\r\n const solidFill = bgPr.getElementsByTagNameNS(NS_A, \"solidFill\")[0];\r\n bgColor = parseColor(solidFill);\r\n }\r\n }\r\n\r\n // Shapes & Text\r\n const shapes = Array.from(doc.getElementsByTagNameNS(NS_P, \"sp\"));\r\n shapes.forEach((shape) => {\r\n const nvSpPr = shape.getElementsByTagNameNS(NS_P, \"nvSpPr\")[0];\r\n const cNvPr = nvSpPr?.getElementsByTagNameNS(NS_P, \"cNvPr\")[0];\r\n const name = cNvPr?.getAttribute(\"name\")?.toLowerCase() || \"\";\r\n\r\n const isTitle = name.includes(\"title\") || name.includes(\"header\");\r\n\r\n const txBody = shape.getElementsByTagNameNS(NS_P, \"txBody\")[0];\r\n if (!txBody) return;\r\n\r\n const paragraphs = Array.from(txBody.getElementsByTagNameNS(NS_A, \"p\"));\r\n paragraphs.forEach((p) => {\r\n const runs = Array.from(p.getElementsByTagNameNS(NS_A, \"r\"));\r\n runs.forEach((run) => {\r\n const textEl = run.getElementsByTagNameNS(NS_A, \"t\")[0];\r\n const text = textEl?.textContent?.trim() || \"\";\r\n if (!text) return;\r\n\r\n const rPr = run.getElementsByTagNameNS(NS_A, \"rPr\")[0];\r\n let color: string | undefined;\r\n let isBold = false;\r\n let isItalic = false;\r\n\r\n if (rPr) {\r\n isBold = rPr.getAttribute(\"b\") === \"1\";\r\n isItalic = rPr.getAttribute(\"i\") === \"1\";\r\n color = parseColor(rPr.getElementsByTagNameNS(NS_A, \"solidFill\")[0]);\r\n }\r\n\r\n if (isTitle && !title) {\r\n title = text;\r\n titleColor = color;\r\n } else {\r\n body.push({ text, color, isBold, isItalic });\r\n }\r\n });\r\n });\r\n });\r\n\r\n return { title, titleColor, body, bgColor };\r\n}\r\n\r\n// --- Main Component ---\r\ninterface PptxRendererProps {\r\n arrayBuffer?: ArrayBuffer;\r\n fileName?: string;\r\n layout: PageLayout;\r\n currentPage: number;\r\n onCurrentPageChange: (p: number) => void;\r\n onPageCount: (n: number) => void;\r\n onThumbs: (thumbs: string[]) => void;\r\n}\r\n\r\nexport function PptxRenderer(props: PptxRendererProps) {\r\n const [slides, setSlides] = useState<any[]>([]);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n if (!props.arrayBuffer) return;\r\n\r\n const loadPptx = async () => {\r\n try {\r\n const zip = await JSZip.loadAsync(props.arrayBuffer!);\r\n const slidePaths = Object.keys(zip.files)\r\n .filter((p) => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(p))\r\n .sort((a, b) => {\r\n // Natural sort (slide1, slide2, slide10)\r\n const numA = parseInt(a.match(/\\d+/)![0]);\r\n const numB = parseInt(b.match(/\\d+/)![0]);\r\n return numA - numB;\r\n });\r\n\r\n const parsedSlides = [];\r\n for (const path of slidePaths) {\r\n const xml = await zip.files[path].async(\"string\");\r\n parsedSlides.push(parseSlideXml(xml));\r\n }\r\n\r\n setSlides(parsedSlides);\r\n props.onPageCount(parsedSlides.length);\r\n\r\n // Generate SVG Thumbs\r\n const thumbs = parsedSlides.map(\r\n (_, i) =>\r\n `data:image/svg+xml;charset=utf-8,${encodeURIComponent(\r\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100\" height=\"56\"><rect width=\"100%\" height=\"100%\" fill=\"#4f46e5\"/><text x=\"50%\" y=\"50%\" fill=\"white\" font-size=\"20\" text-anchor=\"middle\" dy=\".3em\">${i + 1}</text></svg>`,\r\n )}`,\r\n );\r\n props.onThumbs(thumbs);\r\n } catch (err: any) {\r\n setError(err.message || \"Failed to parse PPTX\");\r\n }\r\n };\r\n\r\n loadPptx();\r\n }, [props.arrayBuffer]);\r\n\r\n const pagesToShow = useMemo(() => {\r\n if (slides.length === 0) return [];\r\n const validPage = Math.max(1, Math.min(props.currentPage, slides.length));\r\n\r\n if (props.layout === \"side-by-side\" && slides.length > 1) {\r\n if (validPage === 1) return [1];\r\n const left = validPage % 2 === 0 ? validPage : validPage - 1;\r\n return [left, left + 1].filter((p) => p <= slides.length);\r\n }\r\n return [validPage];\r\n }, [slides.length, props.currentPage, props.layout]);\r\n\r\n if (error) return <div className=\"text-red-500 p-8 text-center\">{error}</div>;\r\n\r\n return (\r\n <div\r\n className={\r\n props.layout === \"side-by-side\" ? \"hv-view-double\" : \"hv-view-single\"\r\n }\r\n >\r\n {pagesToShow.map((p) => {\r\n const slide = slides[p - 1];\r\n if (!slide) return null;\r\n\r\n return (\r\n <div\r\n key={p}\r\n className=\"hv-page-container\"\r\n style={{\r\n width: \"960px\", // Standard HD slide width\r\n aspectRatio: \"16/9\",\r\n padding: \"48px\",\r\n backgroundColor: slide.bgColor || \"#ffffff\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"center\",\r\n position: \"relative\", // For absolute positioning if we added it later\r\n }}\r\n >\r\n {/* Slide Title */}\r\n {slide.title && (\r\n <h1\r\n style={{\r\n fontSize: \"42px\",\r\n marginBottom: \"32px\",\r\n fontWeight: \"bold\",\r\n color: slide.titleColor || \"#1a202c\",\r\n lineHeight: 1.2,\r\n }}\r\n >\r\n {slide.title}\r\n </h1>\r\n )}\r\n\r\n {/* Slide Body */}\r\n <div\r\n style={{ display: \"flex\", flexDirection: \"column\", gap: \"16px\" }}\r\n >\r\n {slide.body.map((item: any, i: number) => (\r\n <div\r\n key={i}\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: \"12px\",\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: \"8px\",\r\n height: \"8px\",\r\n background: item.color || \"#cbd5e1\",\r\n borderRadius: \"50%\",\r\n marginTop: \"12px\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <p\r\n style={{\r\n fontSize: \"24px\",\r\n color: item.color || \"#4a5568\",\r\n fontWeight: item.isBold ? \"bold\" : \"normal\",\r\n fontStyle: item.isItalic ? \"italic\" : \"normal\",\r\n margin: 0,\r\n }}\r\n >\r\n {item.text}\r\n </p>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Slide Footer Number */}\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n bottom: \"20px\",\r\n right: \"30px\",\r\n color: \"#cbd5e1\",\r\n fontWeight: \"bold\",\r\n }}\r\n >\r\n {p}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n","import type { SupportedFileType } from '../types';\n\n/**\n * Guess the file type from a file name or explicit type.\n * @param name - The file name (optional)\n * @param explicit - Explicit file type (optional)\n * @returns SupportedFileType\n */\nexport function guessFileType(\n name?: string,\n explicit?: SupportedFileType,\n): SupportedFileType {\n if (explicit) { return explicit; }\n const ext = (name?.split('.').pop() || '').toLowerCase();\n const allowed: SupportedFileType[] = [\n 'pdf',\n 'md',\n 'docx',\n 'xlsx',\n 'pptx',\n 'txt',\n 'png',\n 'jpg',\n 'svg',\n ];\n return (allowed as string[]).includes(ext)\n ? (ext as SupportedFileType)\n : 'txt';\n}\n\n/**\n * Convert an ArrayBuffer to a base64 string.\n * @param buf - The ArrayBuffer to convert\n * @returns base64-encoded string\n */\nexport function arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return btoa(binary);\n}\n\n/**\n * Convert a base64 string to an ArrayBuffer.\n * @param b64 - The base64 string\n * @returns Promise<ArrayBuffer>\n */\nexport async function base64ToArrayBuffer(b64: string): Promise<ArrayBuffer> {\n const bin = atob(b64);\n const len = bin.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) { bytes[i] = bin.charCodeAt(i); }\n return bytes.buffer;\n}\n\n/**\n * Resolve a file source from a URL, base64, or Blob, with progress callback.\n * @param args - fileUrl, base64, or Blob, plus optional fileName, fileType, and onProgress\n * @returns Promise<{ fileType, fileName, arrayBuffer, url? }>\n */\nexport async function resolveSource(args: {\n fileUrl?: string;\n base64?: string;\n blob?: Blob;\n fileName?: string;\n fileType?: SupportedFileType;\n onProgress?: (loaded: number, total?: number) => void;\n}): Promise<{\n fileType: SupportedFileType;\n fileName: string;\n arrayBuffer: ArrayBuffer;\n url?: string;\n}> {\n const fileType = guessFileType(args.fileName, args.fileType);\n const fileName = args.fileName ?? `document.${fileType}`;\n\n if (args.blob) {\n const ab = await args.blob.arrayBuffer();\n const url = URL.createObjectURL(args.blob);\n return { fileType, fileName, arrayBuffer: ab, url };\n }\n\n if (args.base64) {\n const ab = await base64ToArrayBuffer(args.base64);\n return { fileType, fileName, arrayBuffer: ab };\n }\n\n if (!args.fileUrl) {\n throw new Error('No file source provided. Use fileUrl, blob, or base64.');\n }\n\n const res = await fetch(args.fileUrl);\n if (!res.ok) { throw new Error(`Failed to fetch file (${res.status})`); }\n\n const total = Number(res.headers.get('content-length') || '') || undefined;\n if (!res.body) {\n const ab = await res.arrayBuffer();\n args.onProgress?.(ab.byteLength, total);\n return { fileType, fileName, arrayBuffer: ab, url: args.fileUrl };\n }\n\n const reader = res.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) { break; }\n if (value) {\n chunks.push(value);\n loaded += value.length;\n args.onProgress?.(loaded, total);\n }\n }\n const out = new Uint8Array(loaded);\n let offset = 0;\n for (const c of chunks) {\n out.set(c, offset);\n offset += c.length;\n }\n return { fileType, fileName, arrayBuffer: out.buffer, url: args.fileUrl };\n}\n","\"use client\";\r\n\r\nimport React, { useEffect, useRef } from \"react\";\r\n\r\ninterface ThumbnailsSidebarProps {\r\n isOpen: boolean;\r\n thumbnails: Array<string | undefined>; // Base64 strings\r\n currentPage: number;\r\n onSelectPage: (page: number) => void;\r\n}\r\n\r\nexport function ThumbnailsSidebar(props: ThumbnailsSidebarProps) {\r\n const { isOpen, thumbnails, currentPage, onSelectPage } = props;\r\n const activeRef = useRef<HTMLDivElement>(null);\r\n\r\n // Auto-scroll the sidebar to keep the current page thumbnail in view\r\n useEffect(() => {\r\n if (activeRef.current) {\r\n activeRef.current.scrollIntoView({\r\n behavior: \"smooth\",\r\n block: \"nearest\",\r\n });\r\n }\r\n }, [currentPage, isOpen]);\r\n\r\n return (\r\n <div className={`hv-sidebar ${!isOpen ? \"collapsed\" : \"\"}`}>\r\n <div className=\"hv-thumb-list\">\r\n {thumbnails.map((src, index) => {\r\n const pageNum = index + 1;\r\n const isActive = pageNum === currentPage;\r\n\r\n return (\r\n <div\r\n key={pageNum}\r\n ref={isActive ? activeRef : null}\r\n className={`hv-thumb-item ${isActive ? \"active\" : \"\"}`}\r\n onClick={() => onSelectPage(pageNum)}\r\n >\r\n <div className=\"hv-thumb-preview\">\r\n {src ? (\r\n <img\r\n src={src}\r\n alt={`Page ${pageNum}`}\r\n className=\"hv-thumb-img\"\r\n />\r\n ) : (\r\n // Skeleton loader state for thumbnail\r\n <div className=\"w-full h-full bg-gray-100 animate-pulse flex items-center justify-center\">\r\n <span className=\"text-xs text-gray-300\">...</span>\r\n </div>\r\n )}\r\n </div>\r\n <span className=\"hv-thumb-label\">Page {pageNum}</span>\r\n </div>\r\n );\r\n })}\r\n\r\n {thumbnails.length === 0 && (\r\n <div className=\"text-center p-4 text-xs text-gray-400\">\r\n No previews available\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport {\r\n ChevronLeft,\r\n ChevronRight,\r\n Grid2X2,\r\n LayoutTemplate,\r\n PanelLeftClose,\r\n PanelLeftOpen,\r\n PenLine, // Changed from Download\r\n PanelRightClose,\r\n PanelRightOpen,\r\n ZoomIn,\r\n ZoomOut,\r\n} from \"lucide-react\";\r\nimport React from \"react\";\r\n\r\ninterface ToolbarProps {\r\n fileName?: string;\r\n pageCount: number;\r\n currentPage: number;\r\n onPageChange: (page: number) => void;\r\n layout: \"single\" | \"side-by-side\";\r\n onLayoutChange: (layout: \"single\" | \"side-by-side\") => void;\r\n\r\n // Left Sidebar (Thumbnails)\r\n showThumbnails: boolean;\r\n onToggleThumbnails: () => void;\r\n\r\n // Right Sidebar (Signatures)\r\n showSignatures: boolean;\r\n onToggleSignatures: () => void;\r\n disableSigning?: boolean;\r\n}\r\n\r\nexport function Toolbar(props: ToolbarProps) {\r\n const {\r\n fileName,\r\n pageCount,\r\n currentPage,\r\n onPageChange,\r\n layout,\r\n onLayoutChange,\r\n } = props;\r\n\r\n const handlePrev = () => {\r\n if (currentPage > 1) onPageChange(currentPage - 1);\r\n };\r\n\r\n const handleNext = () => {\r\n if (currentPage < pageCount) onPageChange(currentPage + 1);\r\n };\r\n\r\n const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const val = parseInt(e.target.value);\r\n if (!isNaN(val) && val >= 1 && val <= pageCount) {\r\n onPageChange(val);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"hv-toolbar\">\r\n {/* Left Group: Thumbnails & Title */}\r\n <div className=\"hv-toolbar-group\">\r\n <button\r\n className={`hv-btn ${props.showThumbnails ? \"hv-btn-active\" : \"\"}`}\r\n onClick={props.onToggleThumbnails}\r\n title=\"Toggle Thumbnails\"\r\n >\r\n {props.showThumbnails ? (\r\n <PanelLeftClose size={20} />\r\n ) : (\r\n <PanelLeftOpen size={20} />\r\n )}\r\n </button>\r\n <div\r\n className=\"hv-sep\"\r\n style={{\r\n width: 1,\r\n height: 24,\r\n background: \"var(--hv-border)\",\r\n margin: \"0 8px\",\r\n }}\r\n />\r\n <span\r\n style={{\r\n fontWeight: 600,\r\n fontSize: \"14px\",\r\n maxWidth: 200,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {fileName || \"Document\"}\r\n </span>\r\n </div>\r\n\r\n {/* Center Group: Pagination */}\r\n <div className=\"hv-toolbar-group\">\r\n <button\r\n className=\"hv-btn\"\r\n disabled={currentPage <= 1}\r\n onClick={handlePrev}\r\n >\r\n <ChevronLeft size={20} />\r\n </button>\r\n\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-gray-600\">\r\n <input\r\n type=\"number\"\r\n className=\"w-12 text-center border rounded py-1 bg-gray-50 focus:bg-white focus:ring-2 focus:ring-indigo-500 outline-none transition-all\"\r\n value={currentPage}\r\n onChange={handleInput}\r\n min={1}\r\n max={pageCount}\r\n />\r\n <span className=\"text-gray-400\">/</span>\r\n <span>{pageCount}</span>\r\n </div>\r\n\r\n <button\r\n className=\"hv-btn\"\r\n disabled={currentPage >= pageCount}\r\n onClick={handleNext}\r\n >\r\n <ChevronRight size={20} />\r\n </button>\r\n </div>\r\n\r\n {/* Right Group: Layout & Signatures */}\r\n <div className=\"hv-toolbar-group\">\r\n <button\r\n className={`hv-btn ${layout === \"single\" ? \"hv-btn-active text-indigo-600 bg-indigo-50\" : \"\"}`}\r\n onClick={() => onLayoutChange(\"single\")}\r\n title=\"Single Page View\"\r\n >\r\n <LayoutTemplate size={18} />\r\n </button>\r\n <button\r\n className={`hv-btn ${layout === \"side-by-side\" ? \"hv-btn-active text-indigo-600 bg-indigo-50\" : \"\"}`}\r\n onClick={() => onLayoutChange(\"side-by-side\")}\r\n title=\"Two Page View\"\r\n >\r\n <Grid2X2 size={18} />\r\n </button>\r\n\r\n <div\r\n className=\"hv-sep\"\r\n style={{\r\n width: 1,\r\n height: 24,\r\n background: \"var(--hv-border)\",\r\n margin: \"0 8px\",\r\n }}\r\n />\r\n\r\n {/* Signature Toggle Button */}\r\n {!props.disableSigning && (\r\n <button\r\n className={`hv-btn hv-btn-primary ${props.showSignatures ? \"ring-2 ring-indigo-300\" : \"\"}`}\r\n onClick={props.onToggleSignatures}\r\n title=\"Sign Document\"\r\n >\r\n <PenLine size={18} className=\"mr-2\" />\r\n <span className=\"hidden sm:inline\">Sign</span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { Plus, Trash2, X } from \"lucide-react\";\r\nimport React, { useState, useRef } from \"react\";\r\nimport type { Signature } from \"../types\";\r\n\r\ninterface SignaturePanelProps {\r\n isOpen: boolean;\r\n onClose: () => void;\r\n onSelectSignature: (sig: Signature) => void;\r\n externalSignatures?: Signature[];\r\n onSignRequest?: () => Promise<Signature>;\r\n}\r\n\r\nexport function SignaturePanel(props: SignaturePanelProps) {\r\n const {\r\n isOpen,\r\n onClose,\r\n onSelectSignature,\r\n externalSignatures = [],\r\n onSignRequest,\r\n } = props;\r\n const [localSignatures, setLocalSignatures] = useState<Signature[]>([]);\r\n const [showModal, setShowModal] = useState(false);\r\n\r\n // Combine external + local\r\n const signatures = [...externalSignatures, ...localSignatures];\r\n\r\n // Drawing state\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const [isDrawing, setIsDrawing] = useState(false);\r\n\r\n // --- Modal Logic ---\r\n const handleCreateClick = async () => {\r\n if (onSignRequest) {\r\n try {\r\n const newSig = await onSignRequest();\r\n if (newSig) {\r\n // If the user provides a signature, we can choose to add it to local list\r\n // so it appears in the list here.\r\n // Note: If the parent manages state driven by \"externalSignatures\",\r\n // this might duplicate if we also add it locally.\r\n // However, typically onSignRequest implies external control.\r\n // Let's assume onSignRequest returns the signature and we should add it local\r\n // for immediate use, UNLESS the parent updates externalSignatures.\r\n // To be safe and simple: Add to local.\r\n setLocalSignatures((prev) => [...prev, newSig]);\r\n onSelectSignature(newSig);\r\n }\r\n } catch (err) {\r\n console.error(\"Custom sign request failed\", err);\r\n }\r\n } else {\r\n openCreateModal();\r\n }\r\n };\r\n\r\n const openCreateModal = () => {\r\n setShowModal(true);\r\n setTimeout(() => {\r\n const canvas = canvasRef.current;\r\n if (canvas) {\r\n const ctx = canvas.getContext(\"2d\");\r\n ctx?.clearRect(0, 0, canvas.width, canvas.height);\r\n }\r\n }, 100);\r\n };\r\n\r\n const saveSignature = () => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) return;\r\n\r\n const newSig: Signature = {\r\n id: Date.now().toString(),\r\n signatureImageUrl: canvas.toDataURL(\"image/png\"),\r\n signedBy: \"Me\",\r\n dateSigned: new Date().toISOString(),\r\n };\r\n\r\n setLocalSignatures([...localSignatures, newSig]);\r\n setShowModal(false);\r\n onSelectSignature(newSig);\r\n };\r\n\r\n // --- Drawing Logic ---\r\n const startDraw = (e: React.MouseEvent | React.TouchEvent) => {\r\n setIsDrawing(true);\r\n draw(e);\r\n };\r\n const stopDraw = () => setIsDrawing(false);\r\n const draw = (e: React.MouseEvent | React.TouchEvent) => {\r\n if (!isDrawing || !canvasRef.current) return;\r\n const canvas = canvasRef.current;\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return;\r\n\r\n const rect = canvas.getBoundingClientRect();\r\n const clientX =\r\n \"touches\" in e ? e.touches[0].clientX : (e as React.MouseEvent).clientX;\r\n const clientY =\r\n \"touches\" in e ? e.touches[0].clientY : (e as React.MouseEvent).clientY;\r\n\r\n const x = clientX - rect.left;\r\n const y = clientY - rect.top;\r\n\r\n ctx.lineWidth = 2;\r\n ctx.lineCap = \"round\";\r\n ctx.lineTo(x, y);\r\n ctx.stroke();\r\n ctx.beginPath();\r\n ctx.moveTo(x, y);\r\n };\r\n\r\n return (\r\n <>\r\n {/* Right Sidebar */}\r\n <div\r\n className={`hv-sidebar hv-sidebar-right ${!isOpen ? \"collapsed\" : \"\"}`}\r\n style={{ width: isOpen ? \"280px\" : \"0\" }}\r\n >\r\n <div\r\n className=\"hv-sidebar-header\"\r\n style={{ justifyContent: \"space-between\", padding: \"12px 16px\" }}\r\n >\r\n <h3 style={{ margin: 0, fontSize: \"15px\", fontWeight: 600 }}>\r\n Signatures\r\n </h3>\r\n <button\r\n onClick={onClose}\r\n className=\"hv-btn\"\r\n style={{ padding: \"4px\", border: \"none\" }}\r\n >\r\n <X size={18} />\r\n </button>\r\n </div>\r\n\r\n <div className=\"hv-thumb-list\">\r\n <button\r\n onClick={handleCreateClick}\r\n className=\"hv-btn\"\r\n style={{\r\n width: \"100%\",\r\n justifyContent: \"center\",\r\n border: \"2px dashed var(--hv-border)\",\r\n marginBottom: \"16px\",\r\n color: \"var(--hv-primary)\",\r\n }}\r\n >\r\n <Plus size={18} style={{ marginRight: \"8px\" }} />\r\n New Signature\r\n </button>\r\n\r\n {signatures.map((sig, idx) => {\r\n const isLocal = localSignatures.some((s) => s.id === sig.id);\r\n // If it's not local, we assume it's external, so we might want to disable delete\r\n // or handle it differently.\r\n // For now, only show delete for local items to avoid state mismatch.\r\n const showDelete = isLocal;\r\n\r\n return (\r\n <div\r\n key={sig.id || idx}\r\n className=\"hv-thumb-item\"\r\n style={{\r\n position: \"relative\",\r\n padding: \"12px\",\r\n background: \"var(--hv-bg)\",\r\n borderRadius: \"8px\",\r\n border: \"1px solid var(--hv-border)\",\r\n }}\r\n onClick={() => onSelectSignature(sig)}\r\n >\r\n <img\r\n src={sig.signatureImageUrl}\r\n alt=\"Signature\"\r\n style={{ height: \"40px\", objectFit: \"contain\" }}\r\n />\r\n <div\r\n style={{\r\n fontSize: \"11px\",\r\n color: \"var(--hv-muted)\",\r\n marginTop: \"4px\",\r\n textAlign: \"center\",\r\n }}\r\n >\r\n {sig.signedBy || \"User\"} •{\" \"}\r\n {new Date(sig.dateSigned).toLocaleDateString()}\r\n {sig.comment && (\r\n <div className=\"text-xs text-gray-500 mt-1 italic\">\r\n {sig.comment}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {showDelete && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setLocalSignatures(\r\n localSignatures.filter((s) => s.id !== sig.id),\r\n );\r\n }}\r\n className=\"hv-btn\"\r\n style={{\r\n position: \"absolute\",\r\n top: \"4px\",\r\n right: \"4px\",\r\n padding: \"4px\",\r\n color: \"#ef4444\",\r\n border: \"none\",\r\n background: \"white\",\r\n }}\r\n >\r\n <Trash2 size={12} />\r\n </button>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* --- MODAL FIX: Using hv-modal classes --- */}\r\n {showModal && (\r\n <div className=\"hv-modal-overlay\">\r\n <div\r\n className=\"hv-modal\"\r\n style={{ width: \"450px\", maxWidth: \"90vw\" }}\r\n >\r\n {/* Modal Header */}\r\n <div\r\n style={{\r\n padding: \"16px 24px\",\r\n borderBottom: \"1px solid var(--hv-border)\",\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <h3 style={{ margin: 0, fontSize: \"18px\", fontWeight: 600 }}>\r\n Draw Signature\r\n </h3>\r\n <button\r\n onClick={() => setShowModal(false)}\r\n className=\"hv-btn\"\r\n style={{ border: \"none\" }}\r\n >\r\n <X size={20} />\r\n </button>\r\n </div>\r\n\r\n {/* Modal Body (Canvas) */}\r\n <div\r\n style={{\r\n padding: \"24px\",\r\n background: \"#f9fafb\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <div\r\n style={{\r\n background: \"white\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: \"8px\",\r\n overflow: \"hidden\",\r\n boxShadow: \"inset 0 2px 4px 0 rgba(0,0,0,0.05)\",\r\n }}\r\n >\r\n <canvas\r\n ref={canvasRef}\r\n width={400}\r\n height={200}\r\n style={{\r\n display: \"block\",\r\n cursor: \"crosshair\",\r\n touchAction: \"none\",\r\n }}\r\n onMouseDown={startDraw}\r\n onMouseUp={stopDraw}\r\n onMouseMove={draw}\r\n onTouchStart={startDraw}\r\n onTouchEnd={stopDraw}\r\n onTouchMove={draw}\r\n />\r\n </div>\r\n <p\r\n style={{\r\n fontSize: \"12px\",\r\n color: \"var(--hv-muted)\",\r\n marginTop: \"8px\",\r\n }}\r\n >\r\n Sign above using your mouse or finger\r\n </p>\r\n </div>\r\n\r\n {/* Modal Footer */}\r\n <div\r\n style={{\r\n padding: \"16px 24px\",\r\n borderTop: \"1px solid var(--hv-border)\",\r\n display: \"flex\",\r\n justifyContent: \"flex-end\",\r\n gap: \"12px\",\r\n }}\r\n >\r\n <button\r\n onClick={() => {\r\n const ctx = canvasRef.current?.getContext(\"2d\");\r\n ctx?.clearRect(0, 0, 400, 200);\r\n }}\r\n className=\"hv-btn\"\r\n >\r\n Clear\r\n </button>\r\n <button onClick={saveSignature} className=\"hv-btn hv-btn-primary\">\r\n Create & Use\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,gBAA2C;;;ACA3C,qBAAoB;AACpB,mBAAmD;AACnD,yBAAuB;;;ACJvB,uBAAsB;AAOf,SAAS,aAAa,MAAsB;AAEjD,SAAO,iBAAAC,QAAU,SAAS,MAAM;AAAA,IAC9B,cAAc,EAAE,MAAM,KAAK;AAAA,IAC3B,UAAU,CAAC,UAAU,KAAK;AAAA,EAC5B,CAAC;AACH;;;AD+DU;AAvDH,SAAS,eAAe,OAA4B;AACzD,QAAM,gBAAY,qBAAuB,IAAI;AAC7C,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAiB,EAAE;AACzD,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAG5C,QAAM,eAAW,qBAAO,IAAI,mBAAAC,QAAW,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC,CAAC;AAErE,8BAAU,MAAM;AACd,UAAM,UAAU,YAAY;AAC1B,UAAI,CAAC,MAAM,YAAa;AACxB,iBAAW,IAAI;AAEf,UAAI;AAEF,YAAI,MAAM,SAAS,SAAS,OAAO,KAAK,MAAM,aAAa,QAAQ;AACjE,gBAAM,SAAS,MAAM,eAAAC,QAAQ,cAAc;AAAA,YACzC,aAAa,MAAM;AAAA,UACrB,CAAC;AACD,yBAAe,aAAa,OAAO,KAAK,CAAC;AAAA,QAC3C,OAEK;AAEH,gBAAM,UAAU,IAAI,YAAY,OAAO;AACvC,gBAAM,OAAO,QAAQ,OAAO,MAAM,WAAW;AAE7C,cAAI,MAAM,SAAS,SAAS,KAAK,KAAK,MAAM,aAAa,MAAM;AAE7D,kBAAM,OAAO,SAAS,QAAQ,OAAO,IAAI;AACzC,2BAAe,aAAa,IAAI,CAAC;AAAA,UACnC,OAAO;AAEL;AAAA,cACE,+DAA+D,IAAI;AAAA,YACrE;AAAA,UACF;AAAA,QACF;AAEA,cAAM,YAAY,CAAC;AAAA,MACrB,SAAS,KAAK;AACZ,gBAAQ,MAAM,yBAAyB,GAAG;AAC1C,uBAAe,kDAAkD;AAAA,MACnE,UAAE;AACA,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF;AAEA,YAAQ;AAAA,EACV,GAAG,CAAC,MAAM,aAAa,MAAM,UAAU,MAAM,QAAQ,CAAC;AAEtD,SACE,4CAAC,SAAI,WAAU,kBACb,sDAAC,SAAI,WAAU,qBACZ,oBACC,4CAAC,SAAI,WAAU,kCAAiC,gCAEhD,IAEA;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,iBAAiB,MAAM,SAAS,UAAU,MAAM,SAAS;AAAA,MACzD,yBAAyB,EAAE,QAAQ,YAAY;AAAA,MAC/C,gCAA8B;AAAA;AAAA,EAChC,GAEJ,GACF;AAEJ;;;AEzFA,IAAAC,gBAMO;AACP,WAAsB;AAsGd,IAAAC,sBAAA;AAvFD,IAAM,wBAAoB,0BAG/B,SAASC,mBAAkB,OAAO,KAAK;AACvC,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAqB,CAAC,CAAC;AAC/C,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAmB,CAAC,CAAC;AAE7C,+BAAU,MAAM;AACd,QAAI,CAAC,MAAM,YAAa;AAExB,QAAI;AACF,YAAM,KAAU,UAAK,MAAM,aAAa,EAAE,MAAM,QAAQ,CAAC;AACzD,YAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,YAAM,KAAK,GAAG,OAAO,MAAM;AAE3B,YAAM,WAAgB,WAAM,cAAc,IAAI;AAAA,QAC5C,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,UAAU;AAEhB,YAAM,OAAO,KAAK,IAAI,SAAS,SAAS,MAAM;AAC9C,YAAM,WAAW,KAAK,IAAI,SAAS,SAAS,CAAC,GAAG,UAAU,CAAC;AAE3D,YAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM;AACxD,cAAM,MAAM,SAAS,CAAC,KAAK,CAAC;AAC5B,eAAO,MAAM;AAAA,UAAK,EAAE,QAAQ,SAAS;AAAA,UAAG,CAACC,IAAG,MAC1C,IAAI,CAAC,MAAM,UAAa,IAAI,CAAC,MAAM,OAAO,OAAO,IAAI,CAAC,CAAC,IAAI;AAAA,QAC7D;AAAA,MACF,CAAC;AAED,cAAQ,UAAU;AAElB,YAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,GAAG,MAAM;AACzD,YAAI,SAAS;AACb,YAAI,OAAO;AACX,eAAO,QAAQ,GAAG;AAChB,mBAAS,OAAO,aAAc,OAAO,KAAM,EAAE,IAAI;AACjD,iBAAO,KAAK,MAAM,OAAO,EAAE,IAAI;AAAA,QACjC;AACA,eAAO;AAAA,MACT,CAAC;AACD,cAAQ,OAAO;AAAA,IACjB,SAAS,GAAG;AACV,cAAQ,MAAM,2BAA2B,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,MAAM,WAAW,CAAC;AAEtB,iBAAe,KAAK,WAAqB;AACvC,QAAI,CAAC,MAAM,OAAQ;AACnB,UAAM,KAAU,WAAM,aAAa,IAAI;AACvC,UAAM,KAAU,WAAM,SAAS;AAC/B,IAAK,WAAM,kBAAkB,IAAI,IAAI,QAAQ;AAC7C,UAAM,MAAW,WAAM,IAAI,EAAE,MAAM,SAAS,UAAU,OAAO,CAAC;AAE9D,UAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,MAAM,YAAY,KAAK;AACzC,gBAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,IACxC;AACA,UAAM,OAAO,KAAK,MAAM,GAAG;AAAA,MACzB,UAAU,MAAM;AAAA,MAChB,UAAU;AAAA,MACV,eAAe,CAAC,CAAC;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,yCAAoB,KAAK,OAAO,EAAE,KAAK,EAAE;AAEzC,SACE,6CAAC,SAAI,WAAU,kBACb;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,QACV,SAAS;AAAA,QACT,eAAe;AAAA,MACjB;AAAA,MAGA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,YAAY;AAAA,cACZ,cAAc;AAAA,cACd,SAAS;AAAA,cACT,UAAU;AAAA,cACV,OAAO;AAAA,cACP,SAAS;AAAA,cACT,KAAK;AAAA,cACL,YAAY;AAAA,YACd;AAAA,YAEA;AAAA,2DAAC,UAAK,gBAAE;AAAA,cACR;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,YAAY;AAAA,oBACZ,QAAQ;AAAA,oBACR,MAAM;AAAA,oBACN,QAAQ;AAAA,oBACR,cAAc;AAAA,kBAChB;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QACF;AAAA,QAGA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA;AAAA,cAEV,WAAW;AAAA,cACX,WAAW;AAAA,cACX,UAAU;AAAA;AAAA,cAEV,SAAS;AAAA,YACX;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,gBAAgB;AAAA,kBAChB,UAAU;AAAA,kBACV,aAAa;AAAA,gBACf;AAAA,gBAEA;AAAA,+DAAC,WACC,wDAAC,QAEC;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,OAAO;AAAA,0BACP,YAAY;AAAA,0BACZ,QAAQ;AAAA,0BACR,UAAU;AAAA,0BACV,KAAK;AAAA,0BACL,MAAM;AAAA,0BACN,QAAQ;AAAA;AAAA,wBACV;AAAA;AAAA,oBACF;AAAA,oBAGC,KAAK,IAAI,CAAC,KAAK,MACd;AAAA,sBAAC;AAAA;AAAA,wBAEC,OAAO;AAAA,0BACL,UAAU;AAAA,0BACV,YAAY;AAAA,0BACZ,QAAQ;AAAA,0BACR,OAAO;AAAA,0BACP,UAAU;AAAA,0BACV,YAAY;AAAA,0BACZ,SAAS;AAAA,0BACT,UAAU;AAAA,0BACV,KAAK;AAAA,0BACL,QAAQ;AAAA;AAAA,wBACV;AAAA,wBAEC;AAAA;AAAA,sBAdI;AAAA,oBAeP,CACD;AAAA,qBACH,GACF;AAAA,kBACA,6CAAC,WACE,eAAK,IAAI,CAAC,KAAK,MACd,8CAAC,QAEC;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,YAAY;AAAA,0BACZ,QAAQ;AAAA,0BACR,WAAW;AAAA,0BACX,UAAU;AAAA,0BACV,OAAO;AAAA,0BACP,UAAU;AAAA,0BACV,MAAM;AAAA,0BACN,QAAQ;AAAA;AAAA,wBACV;AAAA,wBAEC,cAAI;AAAA;AAAA,oBACP;AAAA,oBAGC,IAAI,IAAI,CAAC,MAAM,MACd;AAAA,sBAAC;AAAA;AAAA,wBAEC,iBAAiB,CAAC;AAAA,wBAClB,gCAA8B;AAAA,wBAC9B,QAAQ,CAAC,MAAM;AACb,gCAAM,MAAM,EAAE,cAAc;AAC5B,kCAAQ,CAAC,SAAS;AAChB,kCAAM,OAAO,CAAC,GAAG,IAAI;AACrB,iCAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;AACrB,iCAAK,CAAC,EAAE,CAAC,IAAI;AACb,mCAAO;AAAA,0BACT,CAAC;AAAA,wBACH;AAAA,wBACA,OAAO;AAAA,0BACL,QAAQ;AAAA,0BACR,SAAS;AAAA,0BACT,UAAU;AAAA,0BACV,OAAO;AAAA,0BACP,UAAU;AAAA,0BACV,YAAY;AAAA,0BACZ,UAAU;AAAA,0BACV,SAAS;AAAA,0BACT,QAAQ;AAAA,wBACV;AAAA,wBAEC;AAAA;AAAA,sBAxBI;AAAA,oBAyBP,CACD;AAAA,uBA9CM,CA+CT,CACD,GACH;AAAA;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF,GACF;AAEJ,CAAC;;;ACtPD,IAAAC,gBAAoD;AA6C5C,IAAAC,sBAAA;AAtCD,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAS,CAAC;AAClC,QAAM,UAAM,uBAAQ,MAAM;AACxB,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AACA,UAAM,OACJ,aAAa,QACT,kBACA,aAAa,QACX,cACA;AACR,WAAO,IAAI,gBAAgB,IAAI,KAAK,CAAC,WAAW,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC;AAAA,EACpE,GAAG,CAAC,aAAa,QAAQ,CAAC;AAE1B,+BAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,KAAK;AACP,YAAI,gBAAgB,GAAG;AAAA,MACzB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AAER,SACE,8CAAC,SAAI,WAAU,mCAEb;AAAA,kDAAC,SAAI,WAAU,iFACb;AAAA,mDAAC,QAAG,WAAU,uDACX,oBACH;AAAA,MAGA,8CAAC,SAAI,WAAU,sDACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,QAAQ,CAAC,MAAM,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC;AAAA,YACtD,WAAU;AAAA,YACV,cAAW;AAAA,YAEX;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,QAAO;AAAA,gBAEP;AAAA,kBAAC;AAAA;AAAA,oBACC,eAAc;AAAA,oBACd,gBAAe;AAAA,oBACf,aAAa;AAAA,oBACb,GAAE;AAAA;AAAA,gBACJ;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QAEA,8CAAC,UAAK,WAAU,uEACb;AAAA,eAAK,MAAM,OAAO,GAAG;AAAA,UAAE;AAAA,WAC1B;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,QAAQ,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC;AAAA,YACnD,WAAU;AAAA,YACV,cAAW;AAAA,YAEX;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,QAAO;AAAA,gBAEP;AAAA,kBAAC;AAAA;AAAA,oBACC,eAAc;AAAA,oBACd,gBAAe;AAAA,oBACf,aAAa;AAAA,oBACb,GAAE;AAAA;AAAA,gBACJ;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA,SACF;AAAA,OACF;AAAA,IAGA,8CAAC,SAAI,WAAU,6DACZ;AAAA,OAAC,eACA,8CAAC,SAAI,WAAU,eACb;AAAA,qDAAC,SAAI,WAAU,oFACb;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,QAAO;AAAA,YAEP;AAAA,cAAC;AAAA;AAAA,gBACC,eAAc;AAAA,gBACd,gBAAe;AAAA,gBACf,aAAa;AAAA,gBACb,GAAE;AAAA;AAAA,YACJ;AAAA;AAAA,QACF,GACF;AAAA,QACA,6CAAC,OAAE,WAAU,yBAAwB,oCAAsB;AAAA,SAC7D;AAAA,MAGD,eAAe,CAAC,OACf,8CAAC,SAAI,WAAU,eACb;AAAA,qDAAC,SAAI,WAAU,mFACb;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,QAAO;AAAA,YAEP;AAAA,cAAC;AAAA;AAAA,gBACC,eAAc;AAAA,gBACd,gBAAe;AAAA,gBACf,aAAa;AAAA,gBACb,GAAE;AAAA;AAAA,YACJ;AAAA;AAAA,QACF,GACF;AAAA,QACA,6CAAC,OAAE,WAAU,yBAAwB,kCAAoB;AAAA,SAC3D;AAAA,MAGD,OACC;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,WAAW,SAAS,IAAI,IAAI;AAAA,UACrC,WAAU;AAAA,UAEV;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAK;AAAA,cACL,OAAO,EAAE,WAAW,SAAS,IAAI,IAAI;AAAA,cACrC,WAAU;AAAA;AAAA,UACZ;AAAA;AAAA,MACF;AAAA,OAEJ;AAAA,KACF;AAEJ;;;AC/JA,wBAIO;AACP,IAAAC,gBAA4D;AAsGtD,IAAAC,sBAAA;AAlGN,IAAM,iBACJ;AAYK,SAAS,YAAY,OAAyB;AACnD,QAAM,EAAE,KAAK,aAAa,QAAQ,YAAY,IAAI;AAClD,QAAM,CAAC,KAAK,MAAM,QAAI,wBAAkC,IAAI;AAC5D,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAwB,IAAI;AAEtD,+BAAU,MAAM;AAEd,QAAI,CAAC,sCAAoB,WAAW;AAClC,4CAAoB,YAAY;AAAA,IAClC;AAEA,QAAI,SAAS;AAEb,UAAM,UAAU,YAAY;AAE1B,UAAI,CAAC,OAAO,CAAC,YAAa;AAE1B,eAAS,IAAI;AAEb,UAAI;AAIF,cAAM,aAAa,cACf,EAAE,MAAM,YAAY,MAAM,CAAC,EAAE,IAC7B,EAAE,IAAU;AAEhB,cAAM,kBAAc,+BAAY,UAAU;AAE1C,cAAM,MAAM,MAAM,YAAY;AAE9B,YAAI,QAAQ;AACV,iBAAO,GAAG;AACV,gBAAM,YAAY,IAAI,QAAQ;AAC9B,6BAAmB,GAAG;AAAA,QACxB;AAAA,MACF,SAAS,KAAU;AAEjB,gBAAQ,MAAM,mBAAmB,GAAG;AACpC,YAAI,OAAQ,UAAS,IAAI,WAAW,oBAAoB;AAAA,MAC1D;AAAA,IACF;AAEA,YAAQ;AACR,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,KAAK,WAAW,CAAC;AAErB,QAAM,qBAAqB,OAAO,QAA0B;AAC1D,QAAI;AACF,YAAM,SAAmB,CAAC;AAC1B,YAAM,MAAM,KAAK,IAAI,IAAI,UAAU,CAAC;AACpC,eAAS,IAAI,GAAG,KAAK,KAAK,KAAK;AAC7B,cAAM,OAAO,MAAM,IAAI,QAAQ,CAAC;AAChC,cAAM,WAAW,KAAK,YAAY,EAAE,OAAO,IAAI,CAAC;AAChD,cAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,eAAO,QAAQ,SAAS;AACxB,eAAO,SAAS,SAAS;AAEzB,cAAM,MAAM,OAAO,WAAW,IAAI;AAClC,YAAI,KAAK;AACP,gBAAM,KAAK,OAAO,EAAE,eAAe,KAAK,SAAS,CAAC,EAAE;AACpD,iBAAO,KAAK,OAAO,UAAU,CAAC;AAAA,QAChC;AAAA,MACF;AACA,YAAM,SAAS,MAAM;AAAA,IACvB,SAAS,GAAG;AAAA,IAEZ;AAAA,EACF;AAEA,QAAM,oBAAgB,uBAAQ,MAAM;AAClC,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,aAAa,IAAI,QAAQ,CAAC;AACzD,QAAI,WAAW,kBAAkB,IAAI,WAAW,GAAG;AACjD,UAAI,MAAM,EAAG,QAAO,CAAC,CAAC;AACtB,YAAM,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI;AACnC,aAAO,OAAO,KAAK,IAAI,WAAW,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI;AAAA,IAC5D;AACA,WAAO,CAAC,CAAC;AAAA,EACX,GAAG,CAAC,KAAK,aAAa,MAAM,CAAC;AAE7B,MAAI,OAAO;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,SAAS,QAAQ,WAAW,UAAU,OAAO,UAAU;AAAA,QAEhE;AAAA,uDAAC,YAAO,+BAAiB;AAAA,UACzB,6CAAC,OAAE,WAAU,gBAAgB,iBAAM;AAAA;AAAA;AAAA,IACrC;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iBAAiB,WAAW,iBAAiB,mBAAmB,gBAAgB;AAAA,MAE1F,wBAAc,IAAI,CAAC,SAClB,6CAAC,WAAmB,KAAU,SAAS,QAAzB,IAA+B,CAC9C;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AACF,GAGG;AACD,QAAM,gBAAY,sBAA0B,IAAI;AAEhD,+BAAU,MAAM;AACd,QAAI,CAAC,OAAO,CAAC,UAAU,QAAS;AAChC,QAAI,SAAS;AAEb,UAAM,SAAS,YAAY;AACzB,UAAI;AACF,cAAM,OAAO,MAAM,IAAI,QAAQ,OAAO;AACtC,YAAI,CAAC,OAAQ;AAEb,cAAM,QAAQ;AACd,cAAM,WAAW,KAAK,YAAY,EAAE,MAAM,CAAC;AAC3C,cAAM,SAAS,UAAU;AACzB,cAAM,MAAM,OAAO,WAAW,IAAI;AAClC,YAAI,CAAC,IAAK;AAEV,eAAO,QAAQ,SAAS;AACxB,eAAO,SAAS,SAAS;AAEzB,eAAO,MAAM,QAAQ,GAAG,SAAS,QAAQ,KAAK;AAC9C,eAAO,MAAM,SAAS,GAAG,SAAS,SAAS,KAAK;AAEhD,cAAM,KAAK,OAAO,EAAE,eAAe,KAAK,SAAS,CAAC,EAAE;AAAA,MACtD,SAAS,GAAG;AACV,gBAAQ,MAAM,sBAAsB,CAAC;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AACP,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,KAAK,OAAO,CAAC;AAEjB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,WAAW;AAAA,QACX,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,MAEA,uDAAC,YAAO,KAAK,WAAW,WAAU,iBAAgB;AAAA;AAAA,EACpD;AAEJ;;;ACtLA,IAAAC,gBAAoD;AACpD,mBAAkB;AAyKE,IAAAC,sBAAA;AArKpB,IAAM,OAAO;AACb,IAAM,OAAO;AAEb,SAAS,WAAW,WAA+C;AACjE,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,UAAU,UAAU,uBAAuB,MAAM,SAAS,EAAE,CAAC;AACnE,MAAI,SAAS;AACX,UAAM,MAAM,QAAQ,aAAa,KAAK;AACtC,WAAO,MAAM,IAAI,GAAG,KAAK;AAAA,EAC3B;AACA,QAAM,YAAY,UAAU,uBAAuB,MAAM,WAAW,EAAE,CAAC;AACvE,MAAI,WAAW;AACb,UAAM,MAAM,UAAU,aAAa,KAAK;AACxC,UAAM,WAAmC;AAAA,MACvC,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AACA,WAAO,SAAS,OAAO,EAAE,KAAK;AAAA,EAChC;AACA,SAAO;AACT;AAEA,SAAS,cAAc,KAAa;AAClC,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,MAAM,OAAO,gBAAgB,KAAK,iBAAiB;AAEzD,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,QAAM,OAKD,CAAC;AAGN,QAAM,aAAa,IAAI,uBAAuB,MAAM,IAAI;AACxD,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,OAAO,WAAW,CAAC,EAAE,uBAAuB,MAAM,MAAM,EAAE,CAAC;AACjE,QAAI,MAAM;AACR,YAAM,YAAY,KAAK,uBAAuB,MAAM,WAAW,EAAE,CAAC;AAClE,gBAAU,WAAW,SAAS;AAAA,IAChC;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,KAAK,IAAI,uBAAuB,MAAM,IAAI,CAAC;AAChE,SAAO,QAAQ,CAAC,UAAU;AACxB,UAAM,SAAS,MAAM,uBAAuB,MAAM,QAAQ,EAAE,CAAC;AAC7D,UAAM,QAAQ,QAAQ,uBAAuB,MAAM,OAAO,EAAE,CAAC;AAC7D,UAAM,OAAO,OAAO,aAAa,MAAM,GAAG,YAAY,KAAK;AAE3D,UAAM,UAAU,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,QAAQ;AAEhE,UAAM,SAAS,MAAM,uBAAuB,MAAM,QAAQ,EAAE,CAAC;AAC7D,QAAI,CAAC,OAAQ;AAEb,UAAM,aAAa,MAAM,KAAK,OAAO,uBAAuB,MAAM,GAAG,CAAC;AACtE,eAAW,QAAQ,CAAC,MAAM;AACxB,YAAM,OAAO,MAAM,KAAK,EAAE,uBAAuB,MAAM,GAAG,CAAC;AAC3D,WAAK,QAAQ,CAAC,QAAQ;AACpB,cAAM,SAAS,IAAI,uBAAuB,MAAM,GAAG,EAAE,CAAC;AACtD,cAAM,OAAO,QAAQ,aAAa,KAAK,KAAK;AAC5C,YAAI,CAAC,KAAM;AAEX,cAAM,MAAM,IAAI,uBAAuB,MAAM,KAAK,EAAE,CAAC;AACrD,YAAI;AACJ,YAAI,SAAS;AACb,YAAI,WAAW;AAEf,YAAI,KAAK;AACP,mBAAS,IAAI,aAAa,GAAG,MAAM;AACnC,qBAAW,IAAI,aAAa,GAAG,MAAM;AACrC,kBAAQ,WAAW,IAAI,uBAAuB,MAAM,WAAW,EAAE,CAAC,CAAC;AAAA,QACrE;AAEA,YAAI,WAAW,CAAC,OAAO;AACrB,kBAAQ;AACR,uBAAa;AAAA,QACf,OAAO;AACL,eAAK,KAAK,EAAE,MAAM,OAAO,QAAQ,SAAS,CAAC;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AAED,SAAO,EAAE,OAAO,YAAY,MAAM,QAAQ;AAC5C;AAaO,SAAS,aAAa,OAA0B;AACrD,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAgB,CAAC,CAAC;AAC9C,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAwB,IAAI;AAEtD,+BAAU,MAAM;AACd,QAAI,CAAC,MAAM,YAAa;AAExB,UAAM,WAAW,YAAY;AAC3B,UAAI;AACF,cAAM,MAAM,MAAM,aAAAC,QAAM,UAAU,MAAM,WAAY;AACpD,cAAM,aAAa,OAAO,KAAK,IAAI,KAAK,EACrC,OAAO,CAAC,MAAM,+BAA+B,KAAK,CAAC,CAAC,EACpD,KAAK,CAAC,GAAG,MAAM;AAEd,gBAAM,OAAO,SAAS,EAAE,MAAM,KAAK,EAAG,CAAC,CAAC;AACxC,gBAAM,OAAO,SAAS,EAAE,MAAM,KAAK,EAAG,CAAC,CAAC;AACxC,iBAAO,OAAO;AAAA,QAChB,CAAC;AAEH,cAAM,eAAe,CAAC;AACtB,mBAAW,QAAQ,YAAY;AAC7B,gBAAM,MAAM,MAAM,IAAI,MAAM,IAAI,EAAE,MAAM,QAAQ;AAChD,uBAAa,KAAK,cAAc,GAAG,CAAC;AAAA,QACtC;AAEA,kBAAU,YAAY;AACtB,cAAM,YAAY,aAAa,MAAM;AAGrC,cAAM,SAAS,aAAa;AAAA,UAC1B,CAAC,GAAG,MACF,oCAAoC;AAAA,YAClC,qMAAqM,IAAI,CAAC;AAAA,UAC5M,CAAC;AAAA,QACL;AACA,cAAM,SAAS,MAAM;AAAA,MACvB,SAAS,KAAU;AACjB,iBAAS,IAAI,WAAW,sBAAsB;AAAA,MAChD;AAAA,IACF;AAEA,aAAS;AAAA,EACX,GAAG,CAAC,MAAM,WAAW,CAAC;AAEtB,QAAM,kBAAc,uBAAQ,MAAM;AAChC,QAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,aAAa,OAAO,MAAM,CAAC;AAExE,QAAI,MAAM,WAAW,kBAAkB,OAAO,SAAS,GAAG;AACxD,UAAI,cAAc,EAAG,QAAO,CAAC,CAAC;AAC9B,YAAM,OAAO,YAAY,MAAM,IAAI,YAAY,YAAY;AAC3D,aAAO,CAAC,MAAM,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,KAAK,OAAO,MAAM;AAAA,IAC1D;AACA,WAAO,CAAC,SAAS;AAAA,EACnB,GAAG,CAAC,OAAO,QAAQ,MAAM,aAAa,MAAM,MAAM,CAAC;AAEnD,MAAI,MAAO,QAAO,6CAAC,SAAI,WAAU,gCAAgC,iBAAM;AAEvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WACE,MAAM,WAAW,iBAAiB,mBAAmB;AAAA,MAGtD,sBAAY,IAAI,CAAC,MAAM;AACtB,cAAM,QAAQ,OAAO,IAAI,CAAC;AAC1B,YAAI,CAAC,MAAO,QAAO;AAEnB,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO;AAAA;AAAA,cACP,aAAa;AAAA,cACb,SAAS;AAAA,cACT,iBAAiB,MAAM,WAAW;AAAA,cAClC,SAAS;AAAA,cACT,eAAe;AAAA,cACf,gBAAgB;AAAA,cAChB,UAAU;AAAA;AAAA,YACZ;AAAA,YAGC;AAAA,oBAAM,SACL;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,cAAc;AAAA,oBACd,YAAY;AAAA,oBACZ,OAAO,MAAM,cAAc;AAAA,oBAC3B,YAAY;AAAA,kBACd;AAAA,kBAEC,gBAAM;AAAA;AAAA,cACT;AAAA,cAIF;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,OAAO;AAAA,kBAE9D,gBAAM,KAAK,IAAI,CAAC,MAAW,MAC1B;AAAA,oBAAC;AAAA;AAAA,sBAEC,OAAO;AAAA,wBACL,SAAS;AAAA,wBACT,YAAY;AAAA,wBACZ,KAAK;AAAA,sBACP;AAAA,sBAEA;AAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,OAAO;AAAA,8BACP,QAAQ;AAAA,8BACR,YAAY,KAAK,SAAS;AAAA,8BAC1B,cAAc;AAAA,8BACd,WAAW;AAAA,8BACX,YAAY;AAAA,4BACd;AAAA;AAAA,wBACF;AAAA,wBACA;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,8BACL,UAAU;AAAA,8BACV,OAAO,KAAK,SAAS;AAAA,8BACrB,YAAY,KAAK,SAAS,SAAS;AAAA,8BACnC,WAAW,KAAK,WAAW,WAAW;AAAA,8BACtC,QAAQ;AAAA,4BACV;AAAA,4BAEC,eAAK;AAAA;AAAA,wBACR;AAAA;AAAA;AAAA,oBA3BK;AAAA,kBA4BP,CACD;AAAA;AAAA,cACH;AAAA,cAGA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,QAAQ;AAAA,oBACR,OAAO;AAAA,oBACP,OAAO;AAAA,oBACP,YAAY;AAAA,kBACd;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,UA7EK;AAAA,QA8EP;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;;;ACrQO,SAAS,cACd,MACA,UACmB;AACnB,MAAI,UAAU;AAAE,WAAO;AAAA,EAAU;AACjC,QAAM,OAAO,MAAM,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,YAAY;AACvD,QAAM,UAA+B;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAQ,QAAqB,SAAS,GAAG,IACpC,MACD;AACN;AAsBA,eAAsB,oBAAoB,KAAmC;AAC3E,QAAM,MAAM,KAAK,GAAG;AACpB,QAAM,MAAM,IAAI;AAChB,QAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAAE,UAAM,CAAC,IAAI,IAAI,WAAW,CAAC;AAAA,EAAG;AAC9D,SAAO,MAAM;AACf;AAOA,eAAsB,cAAc,MAYjC;AACD,QAAM,WAAW,cAAc,KAAK,UAAU,KAAK,QAAQ;AAC3D,QAAM,WAAW,KAAK,YAAY,YAAY,QAAQ;AAEtD,MAAI,KAAK,MAAM;AACb,UAAM,KAAK,MAAM,KAAK,KAAK,YAAY;AACvC,UAAM,MAAM,IAAI,gBAAgB,KAAK,IAAI;AACzC,WAAO,EAAE,UAAU,UAAU,aAAa,IAAI,IAAI;AAAA,EACpD;AAEA,MAAI,KAAK,QAAQ;AACf,UAAM,KAAK,MAAM,oBAAoB,KAAK,MAAM;AAChD,WAAO,EAAE,UAAU,UAAU,aAAa,GAAG;AAAA,EAC/C;AAEA,MAAI,CAAC,KAAK,SAAS;AACjB,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AAEA,QAAM,MAAM,MAAM,MAAM,KAAK,OAAO;AACpC,MAAI,CAAC,IAAI,IAAI;AAAE,UAAM,IAAI,MAAM,yBAAyB,IAAI,MAAM,GAAG;AAAA,EAAG;AAExE,QAAM,QAAQ,OAAO,IAAI,QAAQ,IAAI,gBAAgB,KAAK,EAAE,KAAK;AACjE,MAAI,CAAC,IAAI,MAAM;AACb,UAAM,KAAK,MAAM,IAAI,YAAY;AACjC,SAAK,aAAa,GAAG,YAAY,KAAK;AACtC,WAAO,EAAE,UAAU,UAAU,aAAa,IAAI,KAAK,KAAK,QAAQ;AAAA,EAClE;AAEA,QAAM,SAAS,IAAI,KAAK,UAAU;AAClC,QAAM,SAAuB,CAAC;AAC9B,MAAI,SAAS;AACb,SAAO,MAAM;AACX,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,MAAM;AAAE;AAAA,IAAO;AACnB,QAAI,OAAO;AACT,aAAO,KAAK,KAAK;AACjB,gBAAU,MAAM;AAChB,WAAK,aAAa,QAAQ,KAAK;AAAA,IACjC;AAAA,EACF;AACA,QAAM,MAAM,IAAI,WAAW,MAAM;AACjC,MAAI,SAAS;AACb,aAAW,KAAK,QAAQ;AACtB,QAAI,IAAI,GAAG,MAAM;AACjB,cAAU,EAAE;AAAA,EACd;AACA,SAAO,EAAE,UAAU,UAAU,aAAa,IAAI,QAAQ,KAAK,KAAK,QAAQ;AAC1E;;;ACzHA,IAAAC,gBAAyC;AAuCvB,IAAAC,sBAAA;AA9BX,SAAS,kBAAkB,OAA+B;AAC/D,QAAM,EAAE,QAAQ,YAAY,aAAa,aAAa,IAAI;AAC1D,QAAM,gBAAY,sBAAuB,IAAI;AAG7C,+BAAU,MAAM;AACd,QAAI,UAAU,SAAS;AACrB,gBAAU,QAAQ,eAAe;AAAA,QAC/B,UAAU;AAAA,QACV,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,aAAa,MAAM,CAAC;AAExB,SACE,6CAAC,SAAI,WAAW,cAAc,CAAC,SAAS,cAAc,EAAE,IACtD,wDAAC,SAAI,WAAU,iBACZ;AAAA,eAAW,IAAI,CAAC,KAAK,UAAU;AAC9B,YAAM,UAAU,QAAQ;AACxB,YAAM,WAAW,YAAY;AAE7B,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,WAAW,YAAY;AAAA,UAC5B,WAAW,iBAAiB,WAAW,WAAW,EAAE;AAAA,UACpD,SAAS,MAAM,aAAa,OAAO;AAAA,UAEnC;AAAA,yDAAC,SAAI,WAAU,oBACZ,gBACC;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA,KAAK,QAAQ,OAAO;AAAA,gBACpB,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,cAGA,6CAAC,SAAI,WAAU,4EACb,uDAAC,UAAK,WAAU,yBAAwB,iBAAG,GAC7C;AAAA,eAEJ;AAAA,YACA,8CAAC,UAAK,WAAU,kBAAiB;AAAA;AAAA,cAAM;AAAA,eAAQ;AAAA;AAAA;AAAA,QAnB1C;AAAA,MAoBP;AAAA,IAEJ,CAAC;AAAA,IAEA,WAAW,WAAW,KACrB,6CAAC,SAAI,WAAU,yCAAwC,mCAEvD;AAAA,KAEJ,GACF;AAEJ;;;AChEA,0BAYO;AAiDD,IAAAC,sBAAA;AA5BC,SAAS,QAAQ,OAAqB;AAC3C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,aAAa,MAAM;AACvB,QAAI,cAAc,EAAG,cAAa,cAAc,CAAC;AAAA,EACnD;AAEA,QAAM,aAAa,MAAM;AACvB,QAAI,cAAc,UAAW,cAAa,cAAc,CAAC;AAAA,EAC3D;AAEA,QAAM,cAAc,CAAC,MAA2C;AAC9D,UAAM,MAAM,SAAS,EAAE,OAAO,KAAK;AACnC,QAAI,CAAC,MAAM,GAAG,KAAK,OAAO,KAAK,OAAO,WAAW;AAC/C,mBAAa,GAAG;AAAA,IAClB;AAAA,EACF;AAEA,SACE,8CAAC,SAAI,WAAU,cAEb;AAAA,kDAAC,SAAI,WAAU,oBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,UAAU,MAAM,iBAAiB,kBAAkB,EAAE;AAAA,UAChE,SAAS,MAAM;AAAA,UACf,OAAM;AAAA,UAEL,gBAAM,iBACL,6CAAC,sCAAe,MAAM,IAAI,IAE1B,6CAAC,qCAAc,MAAM,IAAI;AAAA;AAAA,MAE7B;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,QAAQ;AAAA,UACV;AAAA;AAAA,MACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,UAAU;AAAA,YACV,UAAU;AAAA,YACV,cAAc;AAAA,YACd,YAAY;AAAA,UACd;AAAA,UAEC,sBAAY;AAAA;AAAA,MACf;AAAA,OACF;AAAA,IAGA,8CAAC,SAAI,WAAU,oBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,UAAU,eAAe;AAAA,UACzB,SAAS;AAAA,UAET,uDAAC,mCAAY,MAAM,IAAI;AAAA;AAAA,MACzB;AAAA,MAEA,8CAAC,SAAI,WAAU,6DACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAU;AAAA,YACV,KAAK;AAAA,YACL,KAAK;AAAA;AAAA,QACP;AAAA,QACA,6CAAC,UAAK,WAAU,iBAAgB,eAAC;AAAA,QACjC,6CAAC,UAAM,qBAAU;AAAA,SACnB;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,UAAU,eAAe;AAAA,UACzB,SAAS;AAAA,UAET,uDAAC,oCAAa,MAAM,IAAI;AAAA;AAAA,MAC1B;AAAA,OACF;AAAA,IAGA,8CAAC,SAAI,WAAU,oBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,UAAU,WAAW,WAAW,+CAA+C,EAAE;AAAA,UAC5F,SAAS,MAAM,eAAe,QAAQ;AAAA,UACtC,OAAM;AAAA,UAEN,uDAAC,sCAAe,MAAM,IAAI;AAAA;AAAA,MAC5B;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,UAAU,WAAW,iBAAiB,+CAA+C,EAAE;AAAA,UAClG,SAAS,MAAM,eAAe,cAAc;AAAA,UAC5C,OAAM;AAAA,UAEN,uDAAC,+BAAQ,MAAM,IAAI;AAAA;AAAA,MACrB;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,QAAQ;AAAA,UACV;AAAA;AAAA,MACF;AAAA,MAGC,CAAC,MAAM,kBACN;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,yBAAyB,MAAM,iBAAiB,2BAA2B,EAAE;AAAA,UACxF,SAAS,MAAM;AAAA,UACf,OAAM;AAAA,UAEN;AAAA,yDAAC,+BAAQ,MAAM,IAAI,WAAU,QAAO;AAAA,YACpC,6CAAC,UAAK,WAAU,oBAAmB,kBAAI;AAAA;AAAA;AAAA,MACzC;AAAA,OAEJ;AAAA,KACF;AAEJ;;;ACzKA,IAAAC,uBAAgC;AAChC,IAAAC,gBAAwC;AA+GpC,IAAAC,sBAAA;AApGG,SAAS,eAAe,OAA4B;AACzD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB,CAAC;AAAA,IACtB;AAAA,EACF,IAAI;AACJ,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAAsB,CAAC,CAAC;AACtE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAGhD,QAAM,aAAa,CAAC,GAAG,oBAAoB,GAAG,eAAe;AAG7D,QAAM,gBAAY,sBAA0B,IAAI;AAChD,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAGhD,QAAM,oBAAoB,YAAY;AACpC,QAAI,eAAe;AACjB,UAAI;AACF,cAAM,SAAS,MAAM,cAAc;AACnC,YAAI,QAAQ;AASV,6BAAmB,CAAC,SAAS,CAAC,GAAG,MAAM,MAAM,CAAC;AAC9C,4BAAkB,MAAM;AAAA,QAC1B;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,8BAA8B,GAAG;AAAA,MACjD;AAAA,IACF,OAAO;AACL,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,iBAAa,IAAI;AACjB,eAAW,MAAM;AACf,YAAM,SAAS,UAAU;AACzB,UAAI,QAAQ;AACV,cAAM,MAAM,OAAO,WAAW,IAAI;AAClC,aAAK,UAAU,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;AAAA,MAClD;AAAA,IACF,GAAG,GAAG;AAAA,EACR;AAEA,QAAM,gBAAgB,MAAM;AAC1B,UAAM,SAAS,UAAU;AACzB,QAAI,CAAC,OAAQ;AAEb,UAAM,SAAoB;AAAA,MACxB,IAAI,KAAK,IAAI,EAAE,SAAS;AAAA,MACxB,mBAAmB,OAAO,UAAU,WAAW;AAAA,MAC/C,UAAU;AAAA,MACV,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC;AAEA,uBAAmB,CAAC,GAAG,iBAAiB,MAAM,CAAC;AAC/C,iBAAa,KAAK;AAClB,sBAAkB,MAAM;AAAA,EAC1B;AAGA,QAAM,YAAY,CAAC,MAA2C;AAC5D,iBAAa,IAAI;AACjB,SAAK,CAAC;AAAA,EACR;AACA,QAAM,WAAW,MAAM,aAAa,KAAK;AACzC,QAAM,OAAO,CAAC,MAA2C;AACvD,QAAI,CAAC,aAAa,CAAC,UAAU,QAAS;AACtC,UAAM,SAAS,UAAU;AACzB,UAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAI,CAAC,IAAK;AAEV,UAAM,OAAO,OAAO,sBAAsB;AAC1C,UAAM,UACJ,aAAa,IAAI,EAAE,QAAQ,CAAC,EAAE,UAAW,EAAuB;AAClE,UAAM,UACJ,aAAa,IAAI,EAAE,QAAQ,CAAC,EAAE,UAAW,EAAuB;AAElE,UAAM,IAAI,UAAU,KAAK;AACzB,UAAM,IAAI,UAAU,KAAK;AAEzB,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,OAAO,GAAG,CAAC;AACf,QAAI,OAAO;AACX,QAAI,UAAU;AACd,QAAI,OAAO,GAAG,CAAC;AAAA,EACjB;AAEA,SACE,8EAEE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,+BAA+B,CAAC,SAAS,cAAc,EAAE;AAAA,QACpE,OAAO,EAAE,OAAO,SAAS,UAAU,IAAI;AAAA,QAEvC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,gBAAgB,iBAAiB,SAAS,YAAY;AAAA,cAE/D;AAAA,6DAAC,QAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,QAAQ,YAAY,IAAI,GAAG,wBAE7D;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS;AAAA,oBACT,WAAU;AAAA,oBACV,OAAO,EAAE,SAAS,OAAO,QAAQ,OAAO;AAAA,oBAExC,uDAAC,0BAAE,MAAM,IAAI;AAAA;AAAA,gBACf;AAAA;AAAA;AAAA,UACF;AAAA,UAEA,8CAAC,SAAI,WAAU,iBACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS;AAAA,gBACT,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,gBAAgB;AAAA,kBAChB,QAAQ;AAAA,kBACR,cAAc;AAAA,kBACd,OAAO;AAAA,gBACT;AAAA,gBAEA;AAAA,+DAAC,6BAAK,MAAM,IAAI,OAAO,EAAE,aAAa,MAAM,GAAG;AAAA,kBAAE;AAAA;AAAA;AAAA,YAEnD;AAAA,YAEC,WAAW,IAAI,CAAC,KAAK,QAAQ;AAC5B,oBAAM,UAAU,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;AAI3D,oBAAM,aAAa;AAEnB,qBACE;AAAA,gBAAC;AAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,cAAc;AAAA,oBACd,QAAQ;AAAA,kBACV;AAAA,kBACA,SAAS,MAAM,kBAAkB,GAAG;AAAA,kBAEpC;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,KAAK,IAAI;AAAA,wBACT,KAAI;AAAA,wBACJ,OAAO,EAAE,QAAQ,QAAQ,WAAW,UAAU;AAAA;AAAA,oBAChD;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,UAAU;AAAA,0BACV,OAAO;AAAA,0BACP,WAAW;AAAA,0BACX,WAAW;AAAA,wBACb;AAAA,wBAEC;AAAA,8BAAI,YAAY;AAAA,0BAAO;AAAA,0BAAG;AAAA,0BAC1B,IAAI,KAAK,IAAI,UAAU,EAAE,mBAAmB;AAAA,0BAC5C,IAAI,WACH,6CAAC,SAAI,WAAU,qCACZ,cAAI,SACP;AAAA;AAAA;AAAA,oBAEJ;AAAA,oBAEC,cACC;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,CAAC,MAAM;AACd,4BAAE,gBAAgB;AAClB;AAAA,4BACE,gBAAgB,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;AAAA,0BAC/C;AAAA,wBACF;AAAA,wBACA,WAAU;AAAA,wBACV,OAAO;AAAA,0BACL,UAAU;AAAA,0BACV,KAAK;AAAA,0BACL,OAAO;AAAA,0BACP,SAAS;AAAA,0BACT,OAAO;AAAA,0BACP,QAAQ;AAAA,0BACR,YAAY;AAAA,wBACd;AAAA,wBAEA,uDAAC,+BAAO,MAAM,IAAI;AAAA;AAAA,oBACpB;AAAA;AAAA;AAAA,gBArDG,IAAI,MAAM;AAAA,cAuDjB;AAAA,YAEJ,CAAC;AAAA,aACH;AAAA;AAAA;AAAA,IACF;AAAA,IAGC,aACC,6CAAC,SAAI,WAAU,oBACb;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,SAAS,UAAU,OAAO;AAAA,QAG1C;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,SAAS;AAAA,gBACT,gBAAgB;AAAA,gBAChB,YAAY;AAAA,cACd;AAAA,cAEA;AAAA,6DAAC,QAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,QAAQ,YAAY,IAAI,GAAG,4BAE7D;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,MAAM,aAAa,KAAK;AAAA,oBACjC,WAAU;AAAA,oBACV,OAAO,EAAE,QAAQ,OAAO;AAAA,oBAExB,uDAAC,0BAAE,MAAM,IAAI;AAAA;AAAA,gBACf;AAAA;AAAA;AAAA,UACF;AAAA,UAGA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,eAAe;AAAA,gBACf,YAAY;AAAA,cACd;AAAA,cAEA;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,YAAY;AAAA,sBACZ,QAAQ;AAAA,sBACR,cAAc;AAAA,sBACd,UAAU;AAAA,sBACV,WAAW;AAAA,oBACb;AAAA,oBAEA;AAAA,sBAAC;AAAA;AAAA,wBACC,KAAK;AAAA,wBACL,OAAO;AAAA,wBACP,QAAQ;AAAA,wBACR,OAAO;AAAA,0BACL,SAAS;AAAA,0BACT,QAAQ;AAAA,0BACR,aAAa;AAAA,wBACf;AAAA,wBACA,aAAa;AAAA,wBACb,WAAW;AAAA,wBACX,aAAa;AAAA,wBACb,cAAc;AAAA,wBACd,YAAY;AAAA,wBACZ,aAAa;AAAA;AAAA,oBACf;AAAA;AAAA,gBACF;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,OAAO;AAAA,sBACP,WAAW;AAAA,oBACb;AAAA,oBACD;AAAA;AAAA,gBAED;AAAA;AAAA;AAAA,UACF;AAAA,UAGA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,WAAW;AAAA,gBACX,SAAS;AAAA,gBACT,gBAAgB;AAAA,gBAChB,KAAK;AAAA,cACP;AAAA,cAEA;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,MAAM;AACb,4BAAM,MAAM,UAAU,SAAS,WAAW,IAAI;AAC9C,2BAAK,UAAU,GAAG,GAAG,KAAK,GAAG;AAAA,oBAC/B;AAAA,oBACA,WAAU;AAAA,oBACX;AAAA;AAAA,gBAED;AAAA,gBACA,6CAAC,YAAO,SAAS,eAAe,WAAU,yBAAwB,0BAElE;AAAA;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF,GACF;AAAA,KAEJ;AAEJ;;;AVtNQ,IAAAC,sBAAA;AA3FD,SAAS,eAAe,OAA4B;AAEzD,QAAM,OAAqB,MAAM,QAAQ;AACzC,QAAM,QAAQ,MAAM,SAAS;AAG7B,QAAM,CAAC,QAAQ,SAAS,QAAI;AAAA,IAC1B,MAAM,iBAAiB;AAAA,EACzB;AACA,QAAM,CAAC,gBAAgB,iBAAiB,QAAI;AAAA,IAC1C,MAAM,yBAAyB;AAAA,EACjC;AACA,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAG1D,QAAM,CAAC,UAAU,WAAW,QAAI,wBAKtB,IAAI;AAEd,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,IAAI;AAC3C,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAiB,EAAE;AAG7C,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,CAAC;AAC5C,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,CAAC;AAChD,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAmB,CAAC,CAAC;AAKzD,+BAAU,MAAM;AACd,QAAI,SAAS;AAEb,UAAM,WAAW,YAAY;AAC3B,iBAAW,IAAI;AACf,eAAS,EAAE;AACX,kBAAY,IAAI;AAEhB,UAAI;AACF,YAAI,SAAS,UAAU;AAErB,sBAAY;AAAA,YACV,UAAW,MAAM,YAAY;AAAA,YAC7B,UAAU,MAAM,YAAY;AAAA,UAC9B,CAAC;AAAA,QACH,OAAO;AAEL,gBAAM,MAAM,MAAM,cAAc;AAAA,YAC9B,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,MAAM,MAAM;AAAA,YACZ,UAAU,MAAM;AAAA,YAChB,UAAU,MAAM;AAAA,UAClB,CAAC;AACD,cAAI,OAAQ,aAAY,GAAG;AAAA,QAC7B;AAAA,MACF,SAAS,KAAU;AACjB,YAAI,OAAQ,UAAS,IAAI,WAAW,yBAAyB;AAAA,MAC/D,UAAE;AACA,YAAI,OAAQ,YAAW,KAAK;AAAA,MAC9B;AAAA,IACF;AAEA,aAAS;AACT,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,MAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,IAAI,CAAC;AAGlD,QAAM,wBAAwB,CAAC,QAAmB;AAEhD,QAAI,MAAM,QAAQ;AAChB,YAAM,OAAO,GAAG;AAAA,IAClB;AAGA,YAAQ,IAAI,uBAAuB,GAAG;AAAA,EAIxC;AAIA,QAAM,gBAAgB,MAAM;AAC1B,QAAI,OAAO;AACT,aACE,8CAAC,SAAI,WAAU,mBACb;AAAA,qDAAC,YAAO,oCAAsB;AAAA,QAC9B,6CAAC,OAAG,iBAAM;AAAA,SACZ;AAAA,IAEJ;AAEA,QAAI,WAAW,CAAC,UAAU;AACxB,aACE,8CAAC,SAAI,WAAU,aACb;AAAA,qDAAC,SAAI,WAAU,cAAa;AAAA,QAC5B,6CAAC,UAAK,iCAAmB;AAAA,SAC3B;AAAA,IAEJ;AAEA,UAAM,cAAc;AAAA,MAClB,aAAa,SAAS;AAAA,MACtB,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,MACnB;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,qBAAqB;AAAA,MACrB,UAAU;AAAA,IACZ;AAEA,YAAQ,SAAS,UAAU;AAAA,MACzB,KAAK;AACH,eAAO,6CAAC,eAAY,KAAK,SAAS,KAAM,GAAG,aAAa;AAAA,MAE1D,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,6CAAC,kBAAe,MAAa,GAAG,aAAa;AAAA,MAEtD,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,6CAAC,qBAAkB,MAAa,GAAG,aAAa;AAAA,MAEzD,KAAK;AAAA,MACL,KAAK;AACH,eAAO,6CAAC,gBAAc,GAAG,aAAa;AAAA,MAExC,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,6CAAC,iBAAe,GAAG,aAAa,UAAU,SAAS,UAAU;AAAA,MAEtE;AACE,eACE,8CAAC,SAAI,WAAU,mBAAkB;AAAA;AAAA,UACP,SAAS;AAAA,WACnC;AAAA,IAEN;AAAA,EACF;AAEA,SACE,8CAAC,SAAI,WAAU,WAAU,iBAAe,OAEtC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,UAAU;AAAA,QACpB;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd;AAAA,QACA,gBAAgB;AAAA,QAEhB;AAAA,QACA,oBAAoB,MAAM,kBAAkB,CAAC,cAAc;AAAA,QAE3D;AAAA,QACA,oBAAoB,MAAM,kBAAkB,CAAC,cAAc;AAAA,QAC3D,gBAAgB,MAAM;AAAA;AAAA,IACxB;AAAA,IAEA,8CAAC,SAAI,WAAU,YAEb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,cAAc;AAAA;AAAA,MAChB;AAAA,MAGA,6CAAC,UAAK,WAAU,WAAW,wBAAc,GAAE;AAAA,MAG3C;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,SAAS,MAAM,kBAAkB,KAAK;AAAA,UACtC,mBAAmB;AAAA,UACnB,oBAAoB,MAAM;AAAA,UAC1B,eAAe,MAAM;AAAA;AAAA,MACvB;AAAA,OACF;AAAA,KACF;AAEJ;","names":["import_react","DOMPurify","MarkdownIt","mammoth","import_react","import_jsx_runtime","SpreadsheetEditor","_","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","JSZip","import_react","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_react","import_jsx_runtime","import_jsx_runtime"]}