@eternalheart/react-file-preview 1.3.9 → 1.3.10
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/README.md +10 -0
- package/README.zh-CN.md +10 -0
- package/lib/FilePreviewContent.d.ts.map +1 -1
- package/lib/chunks/{index-B-H9HQiI.mjs → index-B0JUZ5rS.mjs} +10 -10
- package/lib/chunks/{index-B-H9HQiI.mjs.map → index-B0JUZ5rS.mjs.map} +1 -1
- package/lib/chunks/{index-r3q2xCCI.mjs → index-BAYc4aBz.mjs} +2 -2
- package/lib/chunks/{index-r3q2xCCI.mjs.map → index-BAYc4aBz.mjs.map} +1 -1
- package/lib/chunks/{index-BNUiNUWa.mjs → index-BOQJNL71.mjs} +2 -2
- package/lib/chunks/{index-BNUiNUWa.mjs.map → index-BOQJNL71.mjs.map} +1 -1
- package/lib/chunks/{index-BdYkTSTt.mjs → index-BkU8rK-0.mjs} +3 -3
- package/lib/chunks/{index-BdYkTSTt.mjs.map → index-BkU8rK-0.mjs.map} +1 -1
- package/lib/chunks/{index-CgV8T0G5.mjs → index-BnDoXBnH.mjs} +2 -2
- package/lib/chunks/{index-CgV8T0G5.mjs.map → index-BnDoXBnH.mjs.map} +1 -1
- package/lib/chunks/index-C5YHI0Zs.mjs +160 -0
- package/lib/chunks/index-C5YHI0Zs.mjs.map +1 -0
- package/lib/chunks/{index-Bv93wiEK.mjs → index-CGNWXFy3.mjs} +716 -666
- package/lib/chunks/index-CGNWXFy3.mjs.map +1 -0
- package/lib/chunks/{index-DdOEWhrk.mjs → index-CwmZQ-JO.mjs} +16 -16
- package/lib/chunks/{index-DdOEWhrk.mjs.map → index-CwmZQ-JO.mjs.map} +1 -1
- package/lib/chunks/{index-CKirCT35.mjs → index-CzflrElZ.mjs} +5 -5
- package/lib/chunks/{index-CKirCT35.mjs.map → index-CzflrElZ.mjs.map} +1 -1
- package/lib/chunks/{index-D8GtNeDn.mjs → index-CztCCF7q.mjs} +2 -2
- package/lib/chunks/{index-D8GtNeDn.mjs.map → index-CztCCF7q.mjs.map} +1 -1
- package/lib/chunks/{index-BGeyzo6u.mjs → index-DKEcGewg.mjs} +2 -2
- package/lib/chunks/{index-BGeyzo6u.mjs.map → index-DKEcGewg.mjs.map} +1 -1
- package/lib/chunks/{index-DV5Jd7Qe.mjs → index-DN8BQIqo.mjs} +2 -2
- package/lib/chunks/{index-DV5Jd7Qe.mjs.map → index-DN8BQIqo.mjs.map} +1 -1
- package/lib/chunks/{index-zEVVgWCH.mjs → index-DPpUj8Yy.mjs} +2 -2
- package/lib/chunks/{index-zEVVgWCH.mjs.map → index-DPpUj8Yy.mjs.map} +1 -1
- package/lib/chunks/{index-BSD3w5eG.mjs → index-DSAXdrgU.mjs} +2 -2
- package/lib/chunks/{index-BSD3w5eG.mjs.map → index-DSAXdrgU.mjs.map} +1 -1
- package/lib/chunks/{index-DGuiWJr7.mjs → index-DveR0rOk.mjs} +15 -15
- package/lib/chunks/{index-DGuiWJr7.mjs.map → index-DveR0rOk.mjs.map} +1 -1
- package/lib/chunks/{index-BqEuP_8r.mjs → index-QfO-sASN.mjs} +2 -2
- package/lib/chunks/{index-BqEuP_8r.mjs.map → index-QfO-sASN.mjs.map} +1 -1
- package/lib/chunks/{index-BcBe6KW7.mjs → index-h9bO9wmq.mjs} +4 -4
- package/lib/chunks/{index-BcBe6KW7.mjs.map → index-h9bO9wmq.mjs.map} +1 -1
- package/lib/chunks/index-mvSVNKlQ.mjs +228 -0
- package/lib/chunks/index-mvSVNKlQ.mjs.map +1 -0
- package/lib/chunks/{index-U3w45GW8.mjs → index-tecGXW2S.mjs} +43 -43
- package/lib/chunks/{index-U3w45GW8.mjs.map → index-tecGXW2S.mjs.map} +1 -1
- package/lib/chunks/{useShikiHighlight-DzEAK0S7.mjs → useShikiHighlight-DHFYu0BU.mjs} +3 -3
- package/lib/chunks/{useShikiHighlight-DzEAK0S7.mjs.map → useShikiHighlight-DHFYu0BU.mjs.map} +1 -1
- package/lib/index.cjs +22 -18
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.mjs +13 -12
- package/lib/renderers/Font/index.d.ts +6 -0
- package/lib/renderers/Font/index.d.ts.map +1 -0
- package/lib/renderers/Pdf/index.d.ts +0 -1
- package/lib/renderers/Pdf/index.d.ts.map +1 -1
- package/lib/renderers/lazy.d.ts +2 -0
- package/lib/renderers/lazy.d.ts.map +1 -1
- package/lib/utils/pdfConfig.d.ts +2 -2
- package/lib/utils/pdfConfig.d.ts.map +1 -1
- package/package.json +3 -2
- package/lib/chunks/index-Bv93wiEK.mjs.map +0 -1
- package/lib/chunks/index-DmepcY31.mjs +0 -96
- package/lib/chunks/index-DmepcY31.mjs.map +0 -1
package/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../file-preview-core/lib/index.mjs","../src/i18n/LocaleContext.tsx","../src/ThemeContext.tsx","../src/renderers/Image/toolbar.tsx","../src/renderers/Pdf/toolbar.tsx","../src/renderers/Epub/toolbar.tsx","../src/renderers/Mobi/toolbar.tsx","../src/renderers/Zip/toolbar.tsx","../src/renderers/Text/toolbar.tsx","../src/renderers/Markdown/toolbar.tsx","../src/RequestContext.tsx","../src/renderers/lazy.tsx","../src/renderers/Unsupported/index.tsx","../src/renderers/RendererLoading.tsx","../src/FilePreviewContent.tsx","../src/FilePreviewModal.tsx","../src/FilePreviewEmbed.tsx","../src/utils/pdfConfig.ts","../src/index.ts","../src/renderers/Image/index.tsx","../src/renderers/Pdf/index.tsx","../src/renderers/Docx/index.tsx","../src/renderers/Xlsx/index.tsx","../src/renderers/Pptx/index.tsx","../src/renderers/Msg/index.tsx","../src/renderers/Epub/index.tsx","../src/renderers/Mobi/index.tsx","../src/renderers/Video/index.tsx","../src/hooks/useAudioPlayer.ts","../src/renderers/Audio/index.tsx","../src/hooks/useShikiHighlight.ts","../src/renderers/Markdown/index.tsx","../src/renderers/Json/index.tsx","../src/renderers/Csv/index.tsx","../src/renderers/Xml/index.tsx","../src/renderers/Subtitle/index.tsx","../src/components/ResizableSplit.tsx","../src/renderers/Zip/index.tsx","../src/renderers/Text/index.tsx"],"sourcesContent":["import j from \"jszip\";\nfunction A(e) {\n try {\n const n = new URL(e).pathname.split(\"/\").pop() || \"file\";\n return decodeURIComponent(n);\n } catch {\n const t = e.split(\"/\").pop() || \"file\";\n return decodeURIComponent(t);\n }\n}\nfunction k(e) {\n var n;\n const t = ((n = e.split(\".\").pop()) == null ? void 0 : n.toLowerCase()) || \"\";\n return {\n // 图片\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n // 视频\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n ogg: \"video/ogg\",\n ogv: \"video/ogg\",\n mov: \"video/quicktime\",\n avi: \"video/x-msvideo\",\n mkv: \"video/x-matroska\",\n m4v: \"video/x-m4v\",\n \"3gp\": \"video/3gpp\",\n flv: \"video/x-flv\",\n // 音频\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n m4a: \"audio/mp4\",\n aac: \"audio/aac\",\n flac: \"audio/flac\",\n // 文档\n pdf: \"application/pdf\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n ppt: \"application/vnd.ms-powerpoint\",\n msg: \"application/vnd.ms-outlook\",\n mobi: \"application/x-mobipocket-ebook\",\n azw: \"application/vnd.amazon.ebook\",\n azw3: \"application/vnd.amazon.ebook\",\n kf8: \"application/vnd.amazon.ebook\",\n // 文本\n txt: \"text/plain\",\n md: \"text/markdown\",\n markdown: \"text/markdown\",\n json: \"application/json\",\n xml: \"application/xml\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"text/javascript\",\n ts: \"text/typescript\",\n jsx: \"text/javascript\",\n tsx: \"text/typescript\",\n py: \"text/x-python\",\n java: \"text/x-java\",\n cpp: \"text/x-c++src\",\n c: \"text/x-csrc\",\n cs: \"text/x-csharp\",\n php: \"text/x-php\",\n rb: \"text/x-ruby\",\n go: \"text/x-go\",\n rs: \"text/x-rust\",\n yaml: \"text/yaml\",\n yml: \"text/yaml\",\n toml: \"text/toml\",\n ini: \"text/plain\",\n env: \"text/plain\",\n diff: \"text/x-diff\",\n patch: \"text/x-diff\",\n log: \"text/plain\",\n csv: \"text/csv\",\n tsv: \"text/tab-separated-values\",\n srt: \"application/x-subrip\",\n vtt: \"text/vtt\",\n zip: \"application/zip\"\n }[t] || \"application/octet-stream\";\n}\nfunction U(e, t = 0) {\n if (e instanceof File)\n return {\n id: `file-${Date.now()}-${t}`,\n name: e.name,\n url: URL.createObjectURL(e),\n type: e.type || k(e.name),\n size: e.size\n };\n if (typeof e == \"string\") {\n const o = A(e);\n return {\n id: `url-${Date.now()}-${t}`,\n name: o,\n url: e,\n type: k(o)\n };\n }\n return {\n id: e.id || `link-${Date.now()}-${t}`,\n name: e.name,\n url: e.url,\n type: e.type || k(e.name),\n size: e.size\n };\n}\nfunction dt(e) {\n return e.map((t, o) => U(t, o));\n}\nfunction ut(e) {\n var r;\n const t = ((r = e.name.split(\".\").pop()) == null ? void 0 : r.toLowerCase()) || \"\", o = e.type.toLowerCase();\n if (o.startsWith(\"image/\") || [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"svg\"].includes(t))\n return \"image\";\n if (o.includes(\"pdf\") || t === \"pdf\")\n return \"pdf\";\n if (o.includes(\"wordprocessingml\") || t === \"docx\")\n return \"docx\";\n if (o.includes(\"spreadsheetml\") || t === \"xlsx\")\n return \"xlsx\";\n if (o.includes(\"presentationml\") || t === \"pptx\" || t === \"ppt\")\n return \"pptx\";\n if (o.includes(\"ms-outlook\") || t === \"msg\")\n return \"msg\";\n if (o.includes(\"epub\") || t === \"epub\")\n return \"epub\";\n if ([\"mobi\", \"azw\", \"azw3\", \"kf8\"].includes(t) || o === \"application/x-mobipocket-ebook\" || o === \"application/vnd.amazon.ebook\")\n return \"mobi\";\n if ([\"csv\", \"tsv\"].includes(t) || o === \"text/csv\" || o === \"text/tab-separated-values\")\n return \"csv\";\n if (t === \"xml\" || o === \"application/xml\" || o === \"text/xml\")\n return \"xml\";\n if ([\"srt\", \"vtt\", \"lrc\", \"elrc\", \"ass\", \"ssa\", \"ttml\", \"dfxp\"].includes(t) || o === \"text/vtt\" || o === \"application/x-subrip\" || o === \"application/ttml+xml\")\n return \"subtitle\";\n if (t === \"zip\" || o === \"application/zip\" || o === \"application/x-zip-compressed\")\n return \"zip\";\n if (o.startsWith(\"video/\") || [\"mp4\", \"webm\", \"ogg\", \"ogv\", \"mov\", \"avi\", \"mkv\", \"m4v\", \"3gp\", \"flv\"].includes(t))\n return \"video\";\n if (o.startsWith(\"audio/\") || [\"mp3\", \"wav\", \"ogg\", \"m4a\", \"flac\", \"aac\"].includes(t))\n return \"audio\";\n if (t === \"md\" || t === \"markdown\")\n return \"markdown\";\n if (o === \"application/json\" || t === \"json\")\n return \"json\";\n const n = [\n \"txt\",\n \"log\",\n \"lock\",\n \"js\",\n \"jsx\",\n \"ts\",\n \"tsx\",\n \"py\",\n \"java\",\n \"cpp\",\n \"c\",\n \"h\",\n \"cs\",\n \"php\",\n \"rb\",\n \"go\",\n \"mod\",\n \"rs\",\n \"swift\",\n \"kt\",\n \"lua\",\n \"vim\",\n \"html\",\n \"css\",\n \"scss\",\n \"sass\",\n \"less\",\n \"yaml\",\n \"yml\",\n \"toml\",\n \"ini\",\n \"conf\",\n \"env\",\n \"diff\",\n \"patch\",\n \"sh\",\n \"bash\",\n \"zsh\",\n \"sql\"\n ];\n return o.startsWith(\"text/\") || n.includes(t) ? \"text\" : \"unsupported\";\n}\nfunction ft(e) {\n var n;\n const t = ((n = e.split(\".\").pop()) == null ? void 0 : n.toLowerCase()) || \"\";\n return {\n js: \"javascript\",\n jsx: \"jsx\",\n ts: \"typescript\",\n tsx: \"tsx\",\n py: \"python\",\n java: \"java\",\n cpp: \"cpp\",\n c: \"c\",\n cs: \"csharp\",\n php: \"php\",\n rb: \"ruby\",\n go: \"go\",\n mod: \"go\",\n rs: \"rust\",\n swift: \"swift\",\n kt: \"kotlin\",\n lua: \"lua\",\n vim: \"vim\",\n scala: \"scala\",\n sh: \"bash\",\n bash: \"bash\",\n zsh: \"bash\",\n json: \"json\",\n xml: \"xml\",\n html: \"html\",\n css: \"css\",\n scss: \"scss\",\n sass: \"sass\",\n less: \"less\",\n sql: \"sql\",\n yaml: \"yaml\",\n yml: \"yaml\",\n toml: \"toml\",\n ini: \"ini\",\n env: \"bash\",\n conf: \"nginx\",\n diff: \"diff\",\n patch: \"diff\",\n log: \"log\",\n md: \"markdown\",\n txt: \"text\"\n }[t] || \"text\";\n}\nfunction pt(e) {\n var n;\n const t = ((n = e.split(\".\").pop()) == null ? void 0 : n.toLowerCase().split(\"?\")[0]) || \"\";\n return {\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n ogg: \"video/ogg\",\n ogv: \"video/ogg\",\n mov: \"video/quicktime\",\n avi: \"video/x-msvideo\",\n mkv: \"video/x-matroska\",\n m4v: \"video/mp4\",\n \"3gp\": \"video/3gpp\",\n flv: \"video/x-flv\"\n }[t] || \"video/mp4\";\n}\nfunction mt(e) {\n return e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} KB` : `${(e / (1024 * 1024)).toFixed(1)} MB`;\n}\nfunction ht(e) {\n if (!isFinite(e) || isNaN(e) || e < 0) return \"0:00\";\n const t = Math.floor(e / 60), o = Math.floor(e % 60);\n return `${t}:${o.toString().padStart(2, \"0\")}`;\n}\nfunction gt(e) {\n var o;\n return (((o = e.split(\".\").pop()) == null ? void 0 : o.toLowerCase()) || \"\") === \"tsv\" ? \"\t\" : \",\";\n}\nfunction xt(e, t = {}) {\n const o = t.delimiter ?? \",\", n = t.firstRowAsHeader ?? !0, r = [];\n let a = [], i = \"\", l = !1, s = 0;\n const c = e.length;\n for (; s < c; ) {\n const f = e[s];\n if (l) {\n if (f === '\"') {\n if (e[s + 1] === '\"') {\n i += '\"', s += 2;\n continue;\n }\n l = !1, s += 1;\n continue;\n }\n i += f, s += 1;\n continue;\n }\n if (f === '\"') {\n l = !0, s += 1;\n continue;\n }\n if (f === o) {\n a.push(i), i = \"\", s += 1;\n continue;\n }\n if (f === \"\\r\") {\n e[s + 1] === `\n` && (s += 1), a.push(i), r.push(a), a = [], i = \"\", s += 1;\n continue;\n }\n if (f === `\n`) {\n a.push(i), r.push(a), a = [], i = \"\", s += 1;\n continue;\n }\n i += f, s += 1;\n }\n for ((i.length > 0 || a.length > 0) && (a.push(i), r.push(a)); r.length > 0; ) {\n const f = r[r.length - 1];\n if (f.length === 1 && f[0] === \"\")\n r.pop();\n else\n break;\n }\n let d = [], p = r;\n n && r.length > 0 && (d = r[0], p = r.slice(1));\n const u = Math.max(\n d.length,\n ...p.map((f) => f.length),\n 0\n );\n for (const f of p)\n for (; f.length < u; ) f.push(\"\");\n return {\n header: d,\n rows: p,\n columnCount: u,\n delimiter: o\n };\n}\nfunction $(e) {\n const t = e instanceof Uint8Array ? e : new Uint8Array(e);\n if (t.length >= 3 && t[0] === 239 && t[1] === 187 && t[2] === 191)\n return new TextDecoder(\"utf-8\").decode(t);\n if (t.length >= 2 && t[0] === 255 && t[1] === 254)\n return new TextDecoder(\"utf-16le\").decode(t);\n if (t.length >= 2 && t[0] === 254 && t[1] === 255)\n return new TextDecoder(\"utf-16be\").decode(t);\n try {\n return new TextDecoder(\"utf-8\", { fatal: !0 }).decode(t);\n } catch {\n }\n try {\n return new TextDecoder(\"gbk\").decode(t);\n } catch {\n }\n return new TextDecoder(\"utf-8\", { fatal: !1 }).decode(t);\n}\nconst I = $;\nasync function bt(e, t) {\n const o = !!t && (\"fetcher\" in t || \"init\" in t), n = o ? t.fetcher ?? fetch : fetch, r = o ? t.init : t, a = await n(e, r);\n if (!a.ok) throw new Error(`请求失败: ${a.status}`);\n const i = await a.arrayBuffer();\n return $(i);\n}\nasync function B(e, t) {\n if (e)\n return typeof e == \"function\" ? await e(t) : e;\n}\nfunction W(e, t) {\n if (!e && !t) return;\n if (!e) return t;\n if (!t) return e;\n const o = new Headers(e.headers || {});\n return t.headers && new Headers(t.headers).forEach((n, r) => {\n o.set(r, n);\n }), {\n ...e,\n ...t,\n headers: o\n };\n}\nfunction Ft(e) {\n const t = (e == null ? void 0 : e.requestHandler) ?? ((n, r) => fetch(n, r)), o = e == null ? void 0 : e.requestInit;\n return async (n, r) => {\n const a = await B(o, n), i = W(a, r);\n return t(n, i);\n };\n}\nasync function wt(e, t = fetch, o) {\n const n = await t(e, o);\n if (!n.ok) throw new Error(`请求失败: ${n.status}`);\n const r = await n.blob();\n return URL.createObjectURL(r);\n}\nasync function vt(e, t, o = fetch, n) {\n const r = await o(e, n);\n if (!r.ok) throw new Error(`请求失败: ${r.status}`);\n const a = await r.blob(), i = URL.createObjectURL(a);\n try {\n const l = document.createElement(\"a\");\n l.href = i, l.download = t, l.style.display = \"none\", document.body.appendChild(l), l.click(), document.body.removeChild(l);\n } finally {\n setTimeout(() => URL.revokeObjectURL(i), 1e3);\n }\n}\nfunction z(e) {\n const t = e.trim().replace(\",\", \".\"), o = t.split(\":\").map((n) => n.trim());\n if (o.length === 3) {\n const [n, r, a] = o;\n return Number(n) * 3600 + Number(r) * 60 + Number(a);\n }\n if (o.length === 2) {\n const [n, r] = o;\n return Number(n) * 60 + Number(r);\n }\n return Number(t) || 0;\n}\nfunction yt(e) {\n if (!isFinite(e) || e < 0) return \"00:00:00.000\";\n const t = Math.floor(e * 1e3), o = t % 1e3, n = Math.floor(t / 1e3) % 60, r = Math.floor(t / 6e4) % 60, a = Math.floor(t / 36e5), i = (l, s = 2) => l.toString().padStart(s, \"0\");\n return `${i(a)}:${i(r)}:${i(n)}.${i(o, 3)}`;\n}\nconst E = /(\\d{1,2}:)?\\d{1,2}:\\d{1,2}[.,]\\d{1,3}\\s*-->\\s*(\\d{1,2}:)?\\d{1,2}:\\d{1,2}[.,]\\d{1,3}/, Z = /^\\s*\\[\\d{1,2}:\\d{1,2}(?:[.:]\\d{1,3})?\\]/;\nfunction V(e) {\n const t = e.replace(/^\\uFEFF/, \"\").trimStart();\n return /^WEBVTT/.test(t) ? \"vtt\" : /^<\\?xml/i.test(t) || /<tt\\b[^>]*>/i.test(t) ? \"ttml\" : /^\\[Script Info\\]/im.test(t) || /^Dialogue:/m.test(t) ? /ScriptType:\\s*v4\\.00\\s*$/im.test(t) ? \"ssa\" : \"ass\" : Z.test(t) || /^\\[(ti|ar|al|au|by|length|offset|re|ve):/im.test(t) ? /<\\d{1,2}:\\d{1,2}(?:[.:]\\d{1,3})?>/.test(t) ? \"elrc\" : \"lrc\" : \"srt\";\n}\nfunction L(e, t) {\n const n = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`), r = [];\n let a, i = 0;\n if (t === \"vtt\") {\n const l = [];\n for (; i < n.length && n[i].trim() !== \"\"; )\n l.push(n[i]), i++;\n for (a = l.join(`\n`); i < n.length && n[i].trim() === \"\"; ) i++;\n }\n for (; i < n.length; ) {\n for (; i < n.length && n[i].trim() === \"\"; ) i++;\n if (i >= n.length) break;\n let l, s = null;\n if (E.test(n[i]))\n s = n[i], i++;\n else if (l = n[i].trim() || void 0, i++, i < n.length && E.test(n[i]))\n s = n[i], i++;\n else\n continue;\n if (!s) continue;\n const c = s.match(/([\\d:.,]+)\\s*-->\\s*([\\d:.,]+)/);\n if (!c) continue;\n const d = z(c[1]), p = z(c[2]), u = [];\n for (; i < n.length && n[i].trim() !== \"\"; )\n u.push(n[i]), i++;\n r.push({ id: l, start: d, end: p, text: u.join(`\n`) });\n }\n return { format: t, cues: r, header: a };\n}\nfunction T(e, t, o) {\n const n = Number(e), r = Number(t);\n let a = 0;\n if (o) {\n const i = (o + \"000\").slice(0, 3);\n a = Number(i);\n }\n return n * 60 + r + a / 1e3;\n}\nfunction R(e, t) {\n const o = /^\\[(ti|ar|al|au|by|length|offset|re|ve):(.*)\\]$/i.exec(e.trim());\n if (!o) return !1;\n const n = o[1].toLowerCase(), r = o[2].trim();\n if (t.metadata[n] = r, n === \"offset\") {\n const a = Number(r);\n isNaN(a) || (t.offsetMs = a);\n }\n return !0;\n}\nfunction O(e) {\n const o = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`), n = { metadata: {}, offsetMs: 0 }, r = /\\[(\\d{1,2}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g, a = [];\n for (const s of o) {\n const c = s.trim();\n if (!c || R(c, n)) continue;\n const d = [];\n let p = 0;\n r.lastIndex = 0;\n let u;\n for (; (u = r.exec(c)) !== null && u.index === p; )\n d.push(T(u[1], u[2], u[3])), p = u.index + u[0].length;\n if (d.length === 0) continue;\n const f = c.slice(p).trim();\n for (const m of d)\n a.push({ start: m, text: f });\n }\n a.sort((s, c) => s.start - c.start);\n const i = n.offsetMs / 1e3;\n return { format: \"lrc\", cues: a.map((s, c) => {\n const d = Math.max(0, s.start - i), p = a[c + 1], u = p ? Math.max(d, p.start - i) : d + 5;\n return { start: d, end: u, text: s.text };\n }), metadata: n.metadata };\n}\nfunction q(e) {\n const o = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`), n = { metadata: {}, offsetMs: 0 }, r = /\\[(\\d{1,2}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g, a = /<(\\d{1,2}):(\\d{1,2})(?:[.:](\\d{1,3}))?>/g, i = [];\n for (const c of o) {\n const d = c.trim();\n if (!d || R(d, n)) continue;\n const p = [];\n let u = 0;\n r.lastIndex = 0;\n let f;\n for (; (f = r.exec(d)) !== null && f.index === u; )\n p.push(T(f[1], f[2], f[3])), u = f.index + f[0].length;\n if (p.length === 0) continue;\n const m = d.slice(u);\n for (const h of p)\n i.push({ start: h, raw: m });\n }\n i.sort((c, d) => c.start - d.start);\n const l = n.offsetMs / 1e3;\n return { format: \"elrc\", cues: i.map((c, d) => {\n const p = [];\n let u = \"\", f = 0, m = null;\n a.lastIndex = 0;\n let h;\n for (; (h = a.exec(c.raw)) !== null; ) {\n const F = c.raw.slice(f, h.index);\n m !== null && F && p.push({ start: Math.max(0, m - l), text: F }), u += F, m = T(h[1], h[2], h[3]), f = h.index + h[0].length;\n }\n const b = c.raw.slice(f);\n m !== null && b && p.push({ start: Math.max(0, m - l), text: b }), u += b;\n const g = Math.max(0, c.start - l), x = i[d + 1], v = x ? Math.max(g, x.start - l) : g + 5;\n return {\n start: g,\n end: v,\n text: u.trim(),\n words: p.length ? p : void 0\n };\n }), metadata: n.metadata };\n}\nfunction N(e) {\n const t = e.trim().split(\":\");\n return t.length !== 3 ? 0 : Number(t[0]) * 3600 + Number(t[1]) * 60 + Number(t[2].replace(\",\", \".\"));\n}\nfunction D(e, t) {\n const n = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`);\n let r = \"\", a = [];\n const i = [], l = [];\n for (const s of n) {\n const c = s.replace(/\\s+$/, \"\"), d = c.trim(), p = /^\\[([^\\]]+)\\]\\s*$/.exec(d);\n if (p) {\n r = p[1].toLowerCase(), l.push(c);\n continue;\n }\n if (r !== \"events\") {\n l.push(c);\n continue;\n }\n const u = /^Format:\\s*(.+)$/i.exec(d);\n if (u) {\n a = u[1].split(\",\").map((w) => w.trim());\n continue;\n }\n const f = /^(Dialogue|Comment):\\s*(.+)$/i.exec(d);\n if (!f || f[1].toLowerCase() === \"comment\" || a.length === 0) continue;\n const m = a.length, h = f[2].split(\",\"), b = h.slice(0, m - 1), g = h.slice(m - 1).join(\",\"), x = {};\n a.forEach((w, y) => {\n x[w] = y === m - 1 ? g : b[y] ?? \"\";\n });\n const v = N(x.Start || \"\"), F = N(x.End || \"\"), _ = (x.Text || \"\").replace(/\\\\N/g, `\n`).replace(/\\\\n/g, `\n`).replace(/\\\\h/g, \" \").replace(/\\{[^}]*\\}/g, \"\");\n i.push({ start: v, end: F, text: _, style: x.Style });\n }\n return i.sort((s, c) => s.start - c.start), {\n format: t,\n cues: i,\n header: l.join(`\n`).trim() || void 0\n };\n}\nfunction S(e) {\n const t = e.trim();\n if (!t) return 0;\n const o = /^(\\d+(?:\\.\\d+)?)(h|m|s|ms|f|t)$/i.exec(t);\n if (o) {\n const r = Number(o[1]), a = o[2].toLowerCase();\n return a === \"h\" ? r * 3600 : a === \"m\" ? r * 60 : a === \"ms\" ? r / 1e3 : r;\n }\n const n = t.split(\":\");\n return n.length === 3 ? Number(n[0]) * 3600 + Number(n[1]) * 60 + Number(n[2]) : n.length === 2 ? Number(n[0]) * 60 + Number(n[1]) : Number(t) || 0;\n}\nfunction H(e) {\n if (typeof DOMParser > \"u\")\n throw new Error(\"TTML parsing requires a DOMParser environment\");\n const t = new DOMParser().parseFromString(e, \"application/xml\");\n if (t.getElementsByTagName(\"parsererror\").length > 0)\n throw new Error(\"TTML XML parse error\");\n const n = t.getElementsByTagName(\"p\"), r = [];\n for (let a = 0; a < n.length; a++) {\n const i = n[a], l = i.getAttribute(\"begin\") || \"\", s = i.getAttribute(\"end\") || \"\", c = i.getAttribute(\"dur\") || \"\", d = S(l);\n let p;\n s ? p = S(s) : c ? p = d + S(c) : p = d + 5;\n let u = \"\";\n i.childNodes.forEach((m) => {\n if (m.nodeType === 3)\n u += m.nodeValue || \"\";\n else if (m.nodeType === 1) {\n const h = m;\n h.tagName.toLowerCase() === \"br\" ? u += `\n` : u += h.textContent || \"\";\n }\n });\n const f = u.replace(/[ \\t]+/g, \" \").replace(/\\n /g, `\n`).trim();\n (f || d || p) && r.push({ start: d, end: p, text: f });\n }\n return r.sort((a, i) => a.start - i.start), { format: \"ttml\", cues: r };\n}\nfunction _t(e, t) {\n switch (t ?? V(e)) {\n case \"lrc\":\n return O(e);\n case \"elrc\":\n return q(e);\n case \"ass\":\n return D(e, \"ass\");\n case \"ssa\":\n return D(e, \"ssa\");\n case \"ttml\":\n return H(e);\n case \"vtt\":\n return L(e, \"vtt\");\n case \"srt\":\n default:\n return L(e, \"srt\");\n }\n}\nasync function Ct(e) {\n return j.loadAsync(e);\n}\nfunction kt(e) {\n const t = [];\n return e.forEach((o, n) => {\n var p;\n const r = n.dir, a = r && !o.endsWith(\"/\") ? o + \"/\" : o, i = r ? a.replace(/\\/$/, \"\") : a, l = i.lastIndexOf(\"/\"), s = l >= 0 ? i.slice(l + 1) : i, c = l >= 0 ? i.slice(0, l) : \"\", d = r ? 0 : ((p = n._data) == null ? void 0 : p.uncompressedSize) ?? 0;\n t.push({\n path: a,\n name: s,\n dir: c,\n isDir: r,\n size: d,\n date: n.date\n });\n }), t;\n}\nfunction St(e) {\n const t = { name: \"\", path: \"\", isDir: !0, children: [], size: 0 }, o = /* @__PURE__ */ new Map();\n o.set(\"\", t);\n const n = (a) => {\n if (o.has(a)) return o.get(a);\n const i = a.split(\"/\").filter(Boolean);\n let l = t, s = \"\";\n for (const c of i) {\n s = s ? `${s}/${c}` : c;\n let d = o.get(s);\n d || (d = { name: c, path: s + \"/\", isDir: !0, children: [], size: 0 }, l.children.push(d), o.set(s, d)), l = d;\n }\n return l;\n };\n for (const a of e) {\n if (a.isDir) {\n n(a.path.replace(/\\/$/, \"\"));\n continue;\n }\n n(a.dir).children.push({\n name: a.name,\n path: a.path,\n isDir: !1,\n size: a.size\n });\n }\n const r = (a) => {\n if (a.children) {\n a.children.sort((i, l) => i.isDir !== l.isDir ? i.isDir ? -1 : 1 : i.name.localeCompare(l.name));\n for (const i of a.children) r(i);\n }\n };\n return r(t), t;\n}\nasync function Tt(e, t) {\n const o = e.file(t);\n if (!o) throw new Error(`ZIP entry not found: ${t}`);\n const n = await o.async(\"arraybuffer\");\n return I(n);\n}\nasync function Mt(e, t, o) {\n const n = e.file(t);\n if (!n) throw new Error(`ZIP entry not found: ${t}`);\n const r = await n.async(\"arraybuffer\");\n return new Blob([r], o ? { type: o } : void 0);\n}\nfunction G(e) {\n return e ? e.startsWith(\"#\") ? e : e.length === 8 ? \"#\" + e.substring(2) : e.length === 6 ? \"#\" + e : \"#000000\" : \"#000000\";\n}\nconst J = [\n \"FFFFFF\",\n \"000000\",\n \"E7E6E6\",\n \"44546A\",\n \"4472C4\",\n \"ED7D31\",\n \"A5A5A5\",\n \"FFC000\",\n \"5B9BD5\",\n \"70AD47\"\n], X = [\n \"000000\",\n \"FFFFFF\",\n \"FF0000\",\n \"00FF00\",\n \"0000FF\",\n \"FFFF00\",\n \"FF00FF\",\n \"00FFFF\",\n \"000000\",\n \"FFFFFF\",\n \"FF0000\",\n \"00FF00\",\n \"0000FF\",\n \"FFFF00\",\n \"FF00FF\",\n \"00FFFF\",\n \"800000\",\n \"008000\",\n \"000080\",\n \"808000\",\n \"800080\",\n \"008080\",\n \"C0C0C0\",\n \"808080\",\n \"9999FF\",\n \"993366\",\n \"FFFFCC\",\n \"CCFFFF\",\n \"660066\",\n \"FF8080\",\n \"0066CC\",\n \"CCCCFF\",\n \"000080\",\n \"FF00FF\",\n \"FFFF00\",\n \"00FFFF\",\n \"800080\",\n \"800000\",\n \"008080\",\n \"0000FF\",\n \"00CCFF\",\n \"CCFFFF\",\n \"CCFFCC\",\n \"FFFF99\",\n \"99CCFF\",\n \"FF99CC\",\n \"CC99FF\",\n \"FFCC99\",\n \"3366FF\",\n \"33CCCC\",\n \"99CC00\",\n \"FFCC00\",\n \"FF9900\",\n \"FF6600\",\n \"666699\",\n \"969696\",\n \"003366\",\n \"339966\",\n \"003300\",\n \"333300\",\n \"993300\",\n \"993366\",\n \"333399\",\n \"333333\"\n];\nfunction K(e, t) {\n const o = parseInt(e.substring(0, 2), 16), n = parseInt(e.substring(2, 4), 16), r = parseInt(e.substring(4, 6), 16), a = (c) => t < 0 ? Math.round(c * (1 + t)) : Math.round(c + (255 - c) * t), i = Math.min(255, Math.max(0, a(o))), l = Math.min(255, Math.max(0, a(n))), s = Math.min(255, Math.max(0, a(r)));\n return i.toString(16).padStart(2, \"0\") + l.toString(16).padStart(2, \"0\") + s.toString(16).padStart(2, \"0\");\n}\nfunction Q(e) {\n if (e && e.type === \"pattern\" && e.pattern === \"solid\") {\n const t = e.fgColor;\n if (t)\n return M(t);\n }\n}\nfunction M(e) {\n if (e) {\n if (\"argb\" in e && typeof e.argb == \"string\" && e.argb)\n return G(e.argb);\n if (\"theme\" in e && typeof e.theme == \"number\") {\n const t = J[e.theme] || \"000000\", o = \"tint\" in e && typeof e.tint == \"number\" ? e.tint : 0;\n return \"#\" + (o !== 0 ? K(t, o) : t);\n }\n if (\"indexed\" in e && typeof e.indexed == \"number\") {\n const t = X[e.indexed];\n if (t) return \"#\" + t;\n }\n }\n}\nfunction Y(e) {\n if (!e || !e.style) return;\n const t = M(e.color) || \"#000000\";\n return [e.style, t];\n}\nfunction tt(e) {\n const t = {};\n let o = !1;\n if (e.font) {\n const r = e.font;\n if ((r.name || r.size || r.bold || r.italic) && (o = !0, t.font = {}, r.name && (t.font.name = r.name), r.size && (t.font.size = r.size), r.bold && (t.font.bold = !0), r.italic && (t.font.italic = !0)), r.color) {\n const a = M(r.color);\n a && (o = !0, t.color = a);\n }\n r.underline && (o = !0, t.underline = !0), r.strike && (o = !0, t.strike = !0);\n }\n const n = Q(e.fill);\n if (n && (o = !0, t.bgcolor = n), e.alignment) {\n const r = e.alignment;\n r.horizontal && (o = !0, t.align = r.horizontal), r.vertical && (o = !0, t.valign = r.vertical), r.wrapText && (o = !0, t.textwrap = !0);\n }\n if (e.border) {\n const r = {};\n let a = !1;\n const i = [\"top\", \"bottom\", \"left\", \"right\"];\n for (const l of i) {\n const s = Y(e.border[l]);\n s && (r[l] = s, a = !0);\n }\n a && (o = !0, t.border = r);\n }\n return o ? t : null;\n}\nfunction et(e) {\n return JSON.stringify(e);\n}\nfunction ot(e, t, o) {\n const n = tt(e);\n if (!n) return -1;\n const r = et(n), a = o.get(r);\n if (a !== void 0) return a;\n const i = t.length;\n return t.push(n), o.set(r, i), i;\n}\nfunction nt(e) {\n const t = e.value;\n if (t == null) return \"\";\n if (typeof t == \"string\") return t;\n if (typeof t == \"number\") return String(t);\n if (typeof t == \"boolean\") return t ? \"TRUE\" : \"FALSE\";\n if (t instanceof Date)\n return t.toLocaleDateString();\n if (typeof t == \"object\" && \"formula\" in t) {\n const o = t.result;\n return o != null ? String(o) : \"\";\n }\n return typeof t == \"object\" && \"richText\" in t ? t.richText.map((n) => n.text).join(\"\") : typeof t == \"object\" && \"hyperlink\" in t ? t.text || \"\" : typeof t == \"object\" && \"error\" in t ? String(t.error) : String(t);\n}\nfunction rt(e) {\n const t = e.split(\":\"), o = P(t[0]), n = t[1] ? P(t[1]) : o;\n return {\n top: o.row,\n left: o.col,\n bottom: n.row,\n right: n.col\n };\n}\nfunction P(e) {\n const t = e.match(/^([A-Z]+)(\\d+)$/);\n if (!t) return { row: 1, col: 1 };\n const o = t[1], n = parseInt(t[2], 10);\n let r = 0;\n for (let a = 0; a < o.length; a++)\n r = r * 26 + (o.charCodeAt(a) - 64);\n return { row: n, col: r };\n}\nfunction zt(e) {\n const t = [];\n return e.eachSheet((o) => {\n const n = [], r = /* @__PURE__ */ new Map(), a = [], i = {}, l = {}, s = o.columnCount;\n for (let u = 1; u <= s; u++) {\n const f = o.getColumn(u);\n f.width && (l[String(u - 1)] = { width: Math.round(f.width * 7.5) });\n }\n l.len = Math.max(s, 26);\n const c = /* @__PURE__ */ new Map(), d = o.model, p = (d == null ? void 0 : d.merges) || [];\n for (const u of p) {\n a.push(u);\n const { top: f, left: m, bottom: h, right: b } = rt(u), g = h - f, x = b - m;\n c.set(`${f - 1},${m - 1}`, [g, x]);\n }\n o.eachRow({ includeEmpty: !0 }, (u, f) => {\n const m = f - 1, h = {};\n u.eachCell({ includeEmpty: !1 }, (g, x) => {\n const v = x - 1;\n if (g.isMerged && g.master !== g) return;\n const F = nt(g), _ = ot(g, n, r), w = { text: F };\n _ !== -1 && (w.style = _);\n const y = `${m},${v}`;\n c.has(y) && (w.merge = c.get(y)), h[String(v)] = w;\n });\n const b = { cells: h };\n u.height && (b.height = Math.round(u.height * 1.333)), i[String(m)] = b;\n }), t.push({\n name: o.name,\n styles: n,\n merges: a,\n rows: i,\n cols: l\n });\n }), t;\n}\nfunction Et(e, t, o = \"Sheet1\") {\n const n = e.length > 0, a = n ? [{ font: { bold: !0 } }] : [], i = {};\n if (n) {\n const s = {};\n e.forEach((c, d) => {\n s[String(d)] = { text: c, style: 0 };\n }), i[0] = { cells: s };\n }\n const l = n ? 1 : 0;\n return t.forEach((s, c) => {\n const d = {};\n s.forEach((p, u) => {\n p !== void 0 && p !== \"\" && (d[String(u)] = { text: p });\n }), i[String(c + l)] = { cells: d };\n }), [{ name: o, styles: a, rows: i }];\n}\nfunction Lt(e, t) {\n var i;\n if (typeof window > \"u\") return;\n const o = (e == null ? void 0 : e.version) || ((i = e == null ? void 0 : e.GlobalWorkerOptions) == null ? void 0 : i.version) || \"\", {\n workerSrc: n = `https://unpkg.com/pdfjs-dist@${o}/build/pdf.worker.min.mjs`,\n cMapUrl: r = `https://unpkg.com/pdfjs-dist@${o}/cmaps/`,\n cMapPacked: a = !0\n } = t || {};\n e.GlobalWorkerOptions && (e.GlobalWorkerOptions.workerSrc = n, e.GlobalWorkerOptions.cMapUrl = r, e.GlobalWorkerOptions.cMapPacked = a);\n}\nconst it = {\n // ─────── common ───────\n \"common.download\": \"下载\",\n \"common.close\": \"关闭\",\n \"common.loading\": \"加载中\",\n \"common.unknown_error\": \"未知错误\",\n \"common.unsupported_preview\": \"不支持预览此文件类型 ({type})\",\n // ─────── toolbar ───────\n \"toolbar.zoom_in\": \"放大\",\n \"toolbar.zoom_out\": \"缩小\",\n \"toolbar.rotate_left\": \"向左旋转\",\n \"toolbar.rotate_right\": \"向右旋转\",\n \"toolbar.reset\": \"复原\",\n \"toolbar.fit_to_window\": \"适应窗口\",\n \"toolbar.original_size\": \"原始尺寸\",\n \"toolbar.toc\": \"目录\",\n \"toolbar.prev_page\": \"上一页\",\n \"toolbar.next_page\": \"下一页\",\n \"toolbar.full_width\": \"全屏宽度\",\n \"toolbar.normal_width\": \"正常宽度\",\n \"toolbar.wrap_on\": \"自动换行\",\n \"toolbar.wrap_off\": \"不换行\",\n \"toolbar.source\": \"源码\",\n \"toolbar.preview\": \"预览\",\n // ─────── image ───────\n \"image.load_failed\": \"图片加载失败\",\n // ─────── pdf ───────\n \"pdf.load_failed\": \"PDF 文件加载失败\",\n // ─────── docx ───────\n \"docx.parse_failed\": \"Word 文档解析失败\",\n // ─────── xlsx ───────\n \"xlsx.loading\": \"加载 Excel 中...\",\n \"xlsx.load_failed\": \"Excel 加载失败\",\n \"xlsx.parse_failed\": \"Excel 文件解析失败\",\n \"xlsx.not_found\": \"Excel 文件不存在\",\n // ─────── pptx ───────\n \"pptx.loading\": \"加载 PPT 中...\",\n \"pptx.load_failed\": \"PPT 加载失败\",\n \"pptx.parse_failed\": \"PPT 文件解析失败\",\n \"pptx.not_found\": \"PPT 文件不存在\",\n \"pptx.invalid_format\": \"PPT 文件格式错误或已损坏\",\n \"pptx.no_pages\": \"PPT 文件无有效页面\",\n \"pptx.timeout\": \"加载超时,请检查网络或稍后重试\",\n // ─────── msg ───────\n \"msg.parse_failed\": \"Outlook 邮件解析失败\",\n \"msg.parse_failed_short\": \"邮件解析失败\",\n \"msg.empty_body\": \"(无邮件正文)\",\n // ─────── epub ───────\n \"epub.load_failed\": \"EPUB 文件加载失败\",\n // ─────── mobi ───────\n \"mobi.load_failed\": \"电子书加载失败,文件可能已损坏或带有 DRM 保护\",\n // ─────── video ───────\n \"video.loading\": \"加载视频中...\",\n \"video.load_failed\": \"视频加载失败\",\n \"video.load_failed_with_error\": \"视频加载失败: {error}\",\n // ─────── audio (aria-label) ───────\n \"audio.aria.play\": \"播放\",\n \"audio.aria.pause\": \"暂停\",\n \"audio.aria.forward_10\": \"前进 10 秒\",\n \"audio.aria.backward_10\": \"后退 10 秒\",\n \"audio.aria.mute\": \"静音\",\n \"audio.aria.unmute\": \"取消静音\",\n \"audio.aria.loop_on\": \"开启循环\",\n \"audio.aria.loop_off\": \"关闭循环\",\n \"audio.aria.progress\": \"播放进度\",\n \"audio.aria.volume\": \"音量\",\n // ─────── markdown ───────\n \"markdown.load_failed\": \"Markdown 文件加载失败\",\n \"markdown.copy_code\": \"复制代码\",\n \"markdown.copied\": \"已复制\",\n // ─────── json ───────\n \"json.load_failed\": \"JSON 文件加载失败\",\n \"json.items\": \"items\",\n \"json.keys\": \"keys\",\n // ─────── csv ───────\n \"csv.loading\": \"加载 CSV 中...\",\n \"csv.load_failed\": \"CSV 文件加载失败\",\n \"csv.parse_failed\": \"CSV 解析失败\",\n // ─────── xml ───────\n \"xml.load_failed\": \"XML 文件加载失败\",\n // ─────── subtitle / lyric ───────\n \"subtitle.load_failed\": \"字幕文件加载失败\",\n \"subtitle.parse_failed\": \"字幕解析失败\",\n \"subtitle.lines\": \"lines\",\n \"subtitle.cues\": \"cues\",\n \"subtitle.meta.title\": \"标题\",\n \"subtitle.meta.artist\": \"艺术家\",\n \"subtitle.meta.album\": \"专辑\",\n \"subtitle.meta.author\": \"作者\",\n \"subtitle.meta.by\": \"制作\",\n \"subtitle.meta.length\": \"时长\",\n \"subtitle.meta.offset\": \"偏移\",\n \"subtitle.meta.editor\": \"编辑器\",\n \"subtitle.meta.version\": \"版本\",\n // ─────── zip ───────\n \"zip.load_failed\": \"ZIP 文件加载失败\",\n \"zip.parse_failed\": \"ZIP 解析失败\",\n // ─────── text ───────\n \"text.load_failed\": \"文本文件加载失败\"\n}, at = {\n // ─────── common ───────\n \"common.download\": \"Download\",\n \"common.close\": \"Close\",\n \"common.loading\": \"Loading\",\n \"common.unknown_error\": \"Unknown error\",\n \"common.unsupported_preview\": \"Preview not supported for this file type ({type})\",\n // ─────── toolbar ───────\n \"toolbar.zoom_in\": \"Zoom in\",\n \"toolbar.zoom_out\": \"Zoom out\",\n \"toolbar.rotate_left\": \"Rotate left\",\n \"toolbar.rotate_right\": \"Rotate right\",\n \"toolbar.reset\": \"Reset\",\n \"toolbar.fit_to_window\": \"Fit to window\",\n \"toolbar.original_size\": \"Original size\",\n \"toolbar.toc\": \"Table of contents\",\n \"toolbar.prev_page\": \"Previous page\",\n \"toolbar.next_page\": \"Next page\",\n \"toolbar.full_width\": \"Full width\",\n \"toolbar.normal_width\": \"Normal width\",\n \"toolbar.wrap_on\": \"Word wrap\",\n \"toolbar.wrap_off\": \"No wrap\",\n \"toolbar.source\": \"Source\",\n \"toolbar.preview\": \"Preview\",\n // ─────── image ───────\n \"image.load_failed\": \"Failed to load image\",\n // ─────── pdf ───────\n \"pdf.load_failed\": \"Failed to load PDF\",\n // ─────── docx ───────\n \"docx.parse_failed\": \"Failed to parse Word document\",\n // ─────── xlsx ───────\n \"xlsx.loading\": \"Loading Excel...\",\n \"xlsx.load_failed\": \"Failed to load Excel\",\n \"xlsx.parse_failed\": \"Failed to parse Excel file\",\n \"xlsx.not_found\": \"Excel file not found\",\n // ─────── pptx ───────\n \"pptx.loading\": \"Loading PPT...\",\n \"pptx.load_failed\": \"Failed to load PPT\",\n \"pptx.parse_failed\": \"Failed to parse PPT file\",\n \"pptx.not_found\": \"PPT file not found\",\n \"pptx.invalid_format\": \"PPT file format is invalid or corrupted\",\n \"pptx.no_pages\": \"PPT file has no valid pages\",\n \"pptx.timeout\": \"Loading timed out, please check your network and retry\",\n // ─────── msg ───────\n \"msg.parse_failed\": \"Failed to parse Outlook message\",\n \"msg.parse_failed_short\": \"Failed to parse message\",\n \"msg.empty_body\": \"(No message body)\",\n // ─────── epub ───────\n \"epub.load_failed\": \"Failed to load EPUB\",\n // ─────── mobi ───────\n \"mobi.load_failed\": \"Failed to load ebook — file may be corrupted or DRM-protected\",\n // ─────── video ───────\n \"video.loading\": \"Loading video...\",\n \"video.load_failed\": \"Failed to load video\",\n \"video.load_failed_with_error\": \"Failed to load video: {error}\",\n // ─────── audio (aria-label) ───────\n \"audio.aria.play\": \"Play\",\n \"audio.aria.pause\": \"Pause\",\n \"audio.aria.forward_10\": \"Forward 10 seconds\",\n \"audio.aria.backward_10\": \"Back 10 seconds\",\n \"audio.aria.mute\": \"Mute\",\n \"audio.aria.unmute\": \"Unmute\",\n \"audio.aria.loop_on\": \"Enable loop\",\n \"audio.aria.loop_off\": \"Disable loop\",\n \"audio.aria.progress\": \"Playback progress\",\n \"audio.aria.volume\": \"Volume\",\n // ─────── markdown ───────\n \"markdown.load_failed\": \"Failed to load Markdown\",\n \"markdown.copy_code\": \"Copy code\",\n \"markdown.copied\": \"Copied\",\n // ─────── json ───────\n \"json.load_failed\": \"Failed to load JSON\",\n \"json.items\": \"items\",\n \"json.keys\": \"keys\",\n // ─────── csv ───────\n \"csv.loading\": \"Loading CSV...\",\n \"csv.load_failed\": \"Failed to load CSV\",\n \"csv.parse_failed\": \"Failed to parse CSV\",\n // ─────── xml ───────\n \"xml.load_failed\": \"Failed to load XML\",\n // ─────── subtitle / lyric ───────\n \"subtitle.load_failed\": \"Failed to load subtitle\",\n \"subtitle.parse_failed\": \"Failed to parse subtitle\",\n \"subtitle.lines\": \"lines\",\n \"subtitle.cues\": \"cues\",\n \"subtitle.meta.title\": \"Title\",\n \"subtitle.meta.artist\": \"Artist\",\n \"subtitle.meta.album\": \"Album\",\n \"subtitle.meta.author\": \"Author\",\n \"subtitle.meta.by\": \"By\",\n \"subtitle.meta.length\": \"Length\",\n \"subtitle.meta.offset\": \"Offset\",\n \"subtitle.meta.editor\": \"Editor\",\n \"subtitle.meta.version\": \"Version\",\n // ─────── zip ───────\n \"zip.load_failed\": \"Failed to load ZIP\",\n \"zip.parse_failed\": \"Failed to parse ZIP\",\n // ─────── text ───────\n \"text.load_failed\": \"Failed to load text file\"\n}, C = {\n \"zh-CN\": it,\n \"en-US\": at\n}, st = /\\{(\\w+)\\}/g;\nfunction lt(e, t) {\n return t ? e.replace(st, (o, n) => {\n const r = t[n];\n return r === void 0 ? `{${n}}` : String(r);\n }) : e;\n}\nfunction Nt(e) {\n var i;\n const t = e.fallbackLocale ?? \"zh-CN\", o = C[e.locale] ?? C[t] ?? C[\"zh-CN\"], n = (i = e.messages) == null ? void 0 : i[e.locale], r = n ? { ...o, ...n } : o, a = C[\"zh-CN\"];\n return (l, s) => {\n const c = r[l] ?? a[l] ?? l;\n return lt(c, s);\n };\n}\nexport {\n St as buildZipTree,\n C as builtInMessages,\n Lt as configurePdfWorker,\n Et as convertCsvToSpreadsheetData,\n zt as convertWorkbookToSpreadsheetData,\n Ft as createFetcher,\n Nt as createTranslator,\n $ as decodeText,\n I as decodeUtf8,\n vt as downloadFileWithFetcher,\n wt as fetchAsBlobUrl,\n bt as fetchTextUtf8,\n mt as formatFileSize,\n yt as formatSubtitleTime,\n ht as formatTime,\n A as getFileNameFromUrl,\n ut as getFileType,\n ft as getLanguageFromFileName,\n pt as getVideoMimeType,\n gt as guessCsvDelimiter,\n k as inferMimeType,\n kt as listZipEntries,\n Ct as loadZip,\n U as normalizeFile,\n dt as normalizeFiles,\n xt as parseCsv,\n _t as parseSubtitle,\n Mt as readZipEntryBlob,\n Tt as readZipEntryText\n};\n//# sourceMappingURL=index.mjs.map\n","import React, { createContext, useContext, useMemo } from 'react';\nimport {\n createTranslator,\n type Locale,\n type Messages,\n type Translator,\n} from '@eternalheart/file-preview-core';\n\nexport interface LocaleContextValue {\n locale: Locale;\n t: Translator;\n}\n\nconst LocaleContext = createContext<LocaleContextValue | null>(null);\n\nexport interface LocaleProviderProps {\n /** 当前语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义字典,浅合并到内置字典之上 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n children: React.ReactNode;\n}\n\nexport const LocaleProvider: React.FC<LocaleProviderProps> = ({\n locale = 'zh-CN',\n messages,\n children,\n}) => {\n const value = useMemo<LocaleContextValue>(() => {\n const t = createTranslator({ locale, messages });\n return { locale, t };\n }, [locale, messages]);\n\n return <LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>;\n};\n\n/**\n * 兜底 translator(当组件被脱离 LocaleProvider 直接使用时)\n * 保持模块级单例,避免每次调用重建\n */\nlet fallbackTranslator: Translator | null = null;\nfunction getFallbackTranslator(): Translator {\n if (!fallbackTranslator) {\n fallbackTranslator = createTranslator({ locale: 'zh-CN' });\n }\n return fallbackTranslator;\n}\n\n/**\n * 获取翻译函数。任意位置调用都安全:\n * - 在 LocaleProvider 下 → 用 provider 提供的 translator\n * - 否则 → 回落到 zh-CN 兜底 translator\n */\nexport function useTranslator(): Translator {\n const ctx = useContext(LocaleContext);\n return ctx?.t ?? getFallbackTranslator();\n}\n\n/**\n * 获取当前 locale。在 Provider 之外返回 'zh-CN'。\n */\nexport function useLocale(): Locale {\n const ctx = useContext(LocaleContext);\n return ctx?.locale ?? 'zh-CN';\n}\n","import React, { createContext, useContext } from 'react';\n\n/** 已解析的主题(auto 在 FilePreviewContent 里被解析过) */\nexport type ResolvedTheme = 'dark' | 'light';\n\nconst ThemeContext = createContext<ResolvedTheme | null>(null);\n\nexport interface ThemeProviderProps {\n theme: ResolvedTheme;\n children: React.ReactNode;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({ theme, children }) => {\n return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;\n};\n\n/**\n * 获取已解析的主题('dark' | 'light')。\n * Provider 之外默认 'dark'(保持组件历史默认行为)。\n *\n * renderer 需要切第三方库的 theme prop(如 react-syntax-highlighter 的 style、\n * shiki 的 theme 选项)时使用;不要用它做 className 分支 —— class 由 CSS 变量\n * 通过根容器 [data-theme] 自动切换。\n */\nexport function useResolvedTheme(): ResolvedTheme {\n return useContext(ThemeContext) ?? 'dark';\n}\n","import React from 'react';\nimport { ZoomIn, ZoomOut, RotateCw, RotateCcw, Scan, RefreshCw } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nconst OriginalSizeIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <text x=\"12\" y=\"17.5\" textAnchor=\"middle\" fontSize=\"20\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">\n 1:1\n </text>\n </svg>\n);\n\nexport interface ImageToolbarContext {\n zoom: number;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onFitToWidth: () => void;\n onOriginalSize: () => void;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n onReset: () => void;\n t: Translator;\n}\n\nexport function getImageToolbarGroups(ctx: ImageToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n { type: 'button', icon: <ZoomOut className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_out'), action: ctx.onZoomOut, disabled: ctx.zoom <= 0.01 },\n { type: 'text', content: `${Math.round(ctx.zoom * 100)}%`, minWidth: '3rem' },\n { type: 'button', icon: <ZoomIn className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_in'), action: ctx.onZoomIn, disabled: ctx.zoom >= 10 },\n ],\n },\n {\n items: [\n { type: 'button', icon: <Scan className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.fit_to_window'), action: ctx.onFitToWidth },\n { type: 'button', icon: <OriginalSizeIcon className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.original_size'), action: ctx.onOriginalSize },\n ],\n },\n {\n items: [\n { type: 'button', icon: <RotateCcw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.rotate_left'), action: ctx.onRotateLeft },\n { type: 'button', icon: <RotateCw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.rotate_right'), action: ctx.onRotateRight },\n ],\n },\n {\n items: [\n { type: 'button', icon: <RefreshCw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.reset'), action: ctx.onReset },\n ],\n },\n ];\n}\n","import { ZoomIn, ZoomOut, RefreshCw } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface PdfToolbarContext {\n zoom: number;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onReset: () => void;\n t: Translator;\n}\n\nexport function getPdfToolbarGroups(ctx: PdfToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n { type: 'button', icon: <ZoomOut className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_out'), action: ctx.onZoomOut, disabled: ctx.zoom <= 0.01 },\n { type: 'text', content: `${Math.round(ctx.zoom * 100)}%`, minWidth: '3rem' },\n { type: 'button', icon: <ZoomIn className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_in'), action: ctx.onZoomIn, disabled: ctx.zoom >= 10 },\n ],\n },\n {\n items: [\n { type: 'button', icon: <RefreshCw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.reset'), action: ctx.onReset },\n ],\n },\n ];\n}\n","import React from 'react';\nimport { ChevronLeft, ChevronRight, List, Maximize2, Minimize2 } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { EpubRendererHandle } from './index';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface EpubToolbarContext {\n epubRef: React.RefObject<EpubRendererHandle | null>;\n current: number;\n total: number;\n fullWidth: boolean;\n t: Translator;\n}\n\nexport function getEpubToolbarGroups(ctx: EpubToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n { type: 'button', icon: <List className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.toc'), action: () => ctx.epubRef.current?.toggleToc() },\n ],\n },\n {\n items: [\n { type: 'button', icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.prev_page'), action: () => ctx.epubRef.current?.prevPage() },\n { type: 'text', content: `${ctx.current} / ${ctx.total}`, minWidth: '4rem' },\n { type: 'button', icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.next_page'), action: () => ctx.epubRef.current?.nextPage() },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: ctx.fullWidth ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" /> : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.fullWidth ? ctx.t('toolbar.normal_width') : ctx.t('toolbar.full_width'),\n action: () => ctx.epubRef.current?.toggleFullWidth(),\n },\n ],\n },\n ];\n}\n","import React from 'react';\nimport { ChevronLeft, ChevronRight, List, Maximize2, Minimize2 } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { MobiRendererHandle } from './index';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface MobiToolbarContext {\n mobiRef: React.RefObject<MobiRendererHandle | null>;\n current: number;\n total: number;\n fullWidth: boolean;\n t: Translator;\n}\n\nexport function getMobiToolbarGroups(ctx: MobiToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n {\n type: 'button',\n icon: <List className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.t('toolbar.toc'),\n action: () => ctx.mobiRef.current?.toggleToc(),\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.t('toolbar.prev_page'),\n action: () => ctx.mobiRef.current?.prevPage(),\n },\n {\n type: 'text',\n content: `${ctx.current} / ${ctx.total}`,\n minWidth: '4rem',\n },\n {\n type: 'button',\n icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.t('toolbar.next_page'),\n action: () => ctx.mobiRef.current?.nextPage(),\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: ctx.fullWidth\n ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" />\n : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.fullWidth ? ctx.t('toolbar.normal_width') : ctx.t('toolbar.full_width'),\n action: () => ctx.mobiRef.current?.toggleFullWidth(),\n },\n ],\n },\n ];\n}\n","import type { ToolbarGroup } from '../toolbar.types';\nimport { formatFileSize } from '@eternalheart/file-preview-core';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface ZipToolbarStats {\n files: number;\n dirs: number;\n size: number;\n}\n\nexport interface ZipToolbarContext {\n stats: ZipToolbarStats | null;\n t: Translator;\n}\n\nexport function getZipToolbarGroups({ stats }: ZipToolbarContext): ToolbarGroup[] {\n if (!stats) return [];\n return [\n {\n items: [\n {\n type: 'text',\n content: `${stats.files} files · ${stats.dirs} dirs · ${formatFileSize(stats.size)}`,\n minWidth: '10rem',\n },\n ],\n },\n ];\n}\n","import { WrapText, Eye, Code } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface TextToolbarContext {\n wordWrap: boolean;\n onToggleWrap: () => void;\n isHtml: boolean;\n htmlPreview: boolean;\n onToggleHtmlPreview: () => void;\n t: Translator;\n}\n\nexport function getTextToolbarGroups(ctx: TextToolbarContext): ToolbarGroup[] {\n const groups: ToolbarGroup[] = [\n {\n items: [\n {\n type: 'button',\n icon: <WrapText className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.wordWrap ? ctx.t('toolbar.wrap_off') : ctx.t('toolbar.wrap_on'),\n action: ctx.onToggleWrap,\n },\n ],\n },\n ];\n\n if (ctx.isHtml) {\n groups.push({\n items: [\n {\n type: 'button',\n icon: ctx.htmlPreview\n ? <Code className=\"rfp-w-4 rfp-h-4\" />\n : <Eye className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.htmlPreview ? ctx.t('toolbar.source') : ctx.t('toolbar.preview'),\n action: ctx.onToggleHtmlPreview,\n },\n ],\n });\n }\n\n return groups;\n}\n","import { Eye, Code } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface MarkdownToolbarContext {\n viewMode: 'preview' | 'source';\n onToggleViewMode: () => void;\n t: Translator;\n}\n\nexport function getMarkdownToolbarGroups(ctx: MarkdownToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n {\n type: 'button',\n icon: ctx.viewMode === 'preview'\n ? <Code className=\"rfp-w-4 rfp-h-4\" />\n : <Eye className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.viewMode === 'preview' ? ctx.t('toolbar.source') : ctx.t('toolbar.preview'),\n action: ctx.onToggleViewMode,\n },\n ],\n },\n ];\n}\n","import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n Fetcher,\n PreviewFile,\n RequestHandler,\n RequestInitFactory,\n ShouldFetchAsBlob,\n} from '@eternalheart/file-preview-core';\nimport { createFetcher, fetchAsBlobUrl } from '@eternalheart/file-preview-core';\n\nexport interface RequestContextValue {\n fetcher: Fetcher;\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n}\n\nconst defaultValue: RequestContextValue = {\n fetcher: (url, init) => fetch(url, init),\n};\n\nconst RequestContext = createContext<RequestContextValue>(defaultValue);\n\nexport interface RequestProviderProps {\n requestInit?: RequestInitFactory;\n requestHandler?: RequestHandler;\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n children: React.ReactNode;\n}\n\nexport const RequestProvider: React.FC<RequestProviderProps> = ({\n requestInit,\n requestHandler,\n shouldFetchAsBlob,\n children,\n}) => {\n const value = useMemo<RequestContextValue>(\n () => ({\n fetcher: createFetcher({ requestInit, requestHandler }),\n shouldFetchAsBlob,\n }),\n [requestInit, requestHandler, shouldFetchAsBlob],\n );\n return (\n <RequestContext.Provider value={value}>{children}</RequestContext.Provider>\n );\n};\n\nexport function useRequest(): RequestContextValue {\n return useContext(RequestContext);\n}\n\nexport function useFetcher(): Fetcher {\n return useContext(RequestContext).fetcher;\n}\n\n/**\n * 解析 file 的可消费 URL:\n * - 未配置 shouldFetchAsBlob 或返回 false:直接返回 file.url\n * - 返回 true:用 fetcher 拉成 blob: URL,组件卸载或 file 变化时 revoke\n *\n * 期间返回空字符串(表示 \"还没准备好\"),调用方应避免空 URL 时挂载到 <img src> 等。\n */\nexport function useResolvedUrl(file: PreviewFile | undefined): string {\n const { fetcher, shouldFetchAsBlob } = useContext(RequestContext);\n const needBlob = !!(file && shouldFetchAsBlob?.(file));\n const [resolved, setResolved] = useState<string>(() =>\n !file ? '' : needBlob ? '' : file.url,\n );\n const createdRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!file) {\n setResolved('');\n return;\n }\n if (!needBlob) {\n setResolved(file.url);\n return;\n }\n let cancelled = false;\n setResolved('');\n fetchAsBlobUrl(file.url, fetcher)\n .then((blobUrl) => {\n if (cancelled) {\n URL.revokeObjectURL(blobUrl);\n return;\n }\n if (createdRef.current) {\n URL.revokeObjectURL(createdRef.current);\n }\n createdRef.current = blobUrl;\n setResolved(blobUrl);\n })\n .catch((err) => {\n if (!cancelled) {\n console.error('[file-preview] resolve blob url failed:', err);\n setResolved(file.url);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [file?.id, file?.url, needBlob, fetcher]);\n\n // 卸载时 revoke 最后一次创建的 blob URL\n useEffect(() => {\n return () => {\n if (createdRef.current) {\n URL.revokeObjectURL(createdRef.current);\n createdRef.current = null;\n }\n };\n }, []);\n\n return resolved;\n}\n","// 集中的 lazy 装饰:把每个 renderer 转为 React.lazy(import).then(default),\n// 让 rollup 自动按 chunk 分割。\n// 显式声明 LazyExoticComponent 以避免 TS4023(要求把内部 Props 类型导入到当前文件作用域)。\nimport { lazy, type LazyExoticComponent, type ComponentType } from 'react';\nimport type { ImageRenderer as ImageRendererImpl } from './Image';\nimport type { PdfRenderer as PdfRendererImpl } from './Pdf';\nimport type { DocxRenderer as DocxRendererImpl } from './Docx';\nimport type { XlsxRenderer as XlsxRendererImpl } from './Xlsx';\nimport type { PptxRenderer as PptxRendererImpl } from './Pptx';\nimport type { MsgRenderer as MsgRendererImpl } from './Msg';\nimport type { EpubRenderer as EpubRendererImpl } from './Epub';\nimport type { MobiRenderer as MobiRendererImpl } from './Mobi';\nimport type { VideoRenderer as VideoRendererImpl } from './Video';\nimport type { AudioRenderer as AudioRendererImpl } from './Audio';\nimport type { MarkdownRenderer as MarkdownRendererImpl } from './Markdown';\nimport type { JsonRenderer as JsonRendererImpl } from './Json';\nimport type { CsvRenderer as CsvRendererImpl } from './Csv';\nimport type { XmlRenderer as XmlRendererImpl } from './Xml';\nimport type { SubtitleRenderer as SubtitleRendererImpl } from './Subtitle';\nimport type { ZipRenderer as ZipRendererImpl } from './Zip';\nimport type { TextRenderer as TextRendererImpl } from './Text';\n\ntype Lazy<T> = LazyExoticComponent<T extends ComponentType<infer P> ? ComponentType<P> : never>;\n\nexport const ImageRenderer: Lazy<typeof ImageRendererImpl> = lazy(() =>\n import('./Image').then((m) => ({ default: m.ImageRenderer })),\n);\n\nexport const PdfRenderer: Lazy<typeof PdfRendererImpl> = lazy(() =>\n import('./Pdf').then((m) => ({ default: m.PdfRenderer })),\n);\n\nexport const DocxRenderer: Lazy<typeof DocxRendererImpl> = lazy(() =>\n import('./Docx').then((m) => ({ default: m.DocxRenderer })),\n);\n\nexport const XlsxRenderer: Lazy<typeof XlsxRendererImpl> = lazy(() =>\n import('./Xlsx').then((m) => ({ default: m.XlsxRenderer })),\n);\n\nexport const PptxRenderer: Lazy<typeof PptxRendererImpl> = lazy(() =>\n import('./Pptx').then((m) => ({ default: m.PptxRenderer })),\n);\n\nexport const MsgRenderer: Lazy<typeof MsgRendererImpl> = lazy(() =>\n import('./Msg').then((m) => ({ default: m.MsgRenderer })),\n);\n\nexport const EpubRenderer: Lazy<typeof EpubRendererImpl> = lazy(() =>\n import('./Epub').then((m) => ({ default: m.EpubRenderer })),\n);\n\nexport const MobiRenderer: Lazy<typeof MobiRendererImpl> = lazy(() =>\n import('./Mobi').then((m) => ({ default: m.MobiRenderer })),\n);\n\nexport const VideoRenderer: Lazy<typeof VideoRendererImpl> = lazy(() =>\n import('./Video').then((m) => ({ default: m.VideoRenderer })),\n);\n\nexport const AudioRenderer: Lazy<typeof AudioRendererImpl> = lazy(() =>\n import('./Audio').then((m) => ({ default: m.AudioRenderer })),\n);\n\nexport const MarkdownRenderer: Lazy<typeof MarkdownRendererImpl> = lazy(() =>\n import('./Markdown').then((m) => ({ default: m.MarkdownRenderer })),\n);\n\nexport const JsonRenderer: Lazy<typeof JsonRendererImpl> = lazy(() =>\n import('./Json').then((m) => ({ default: m.JsonRenderer })),\n);\n\nexport const CsvRenderer: Lazy<typeof CsvRendererImpl> = lazy(() =>\n import('./Csv').then((m) => ({ default: m.CsvRenderer })),\n);\n\nexport const XmlRenderer: Lazy<typeof XmlRendererImpl> = lazy(() =>\n import('./Xml').then((m) => ({ default: m.XmlRenderer })),\n);\n\nexport const SubtitleRenderer: Lazy<typeof SubtitleRendererImpl> = lazy(() =>\n import('./Subtitle').then((m) => ({ default: m.SubtitleRenderer })),\n);\n\nexport const ZipRenderer: Lazy<typeof ZipRendererImpl> = lazy(() =>\n import('./Zip').then((m) => ({ default: m.ZipRenderer })),\n);\n\nexport const TextRenderer: Lazy<typeof TextRendererImpl> = lazy(() =>\n import('./Text').then((m) => ({ default: m.TextRenderer })),\n);\n","import { FileQuestion, Download } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ninterface UnsupportedRendererProps {\n fileName: string;\n fileType: string;\n onDownload: () => void;\n}\n\nexport const UnsupportedRenderer: React.FC<UnsupportedRendererProps> = ({\n fileName,\n fileType,\n onDownload,\n}) => {\n const t = useTranslator();\n return (\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-p-8 rfp-gap-6\">\n <div className=\"rfp-w-32 rfp-h-32 rfp-rounded-full rfp-bg-surface-2 rfp-flex rfp-items-center rfp-justify-center\">\n <FileQuestion className=\"rfp-w-16 rfp-h-16 rfp-text-fg-secondary\" />\n </div>\n\n <div className=\"rfp-text-fg-primary rfp-text-center\">\n <p className=\"rfp-text-xl rfp-font-medium rfp-mb-2\">{fileName}</p>\n <p className=\"rfp-text-fg-secondary\">{t('common.unsupported_preview', { type: fileType })}</p>\n </div>\n\n <button\n onClick={onDownload}\n className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-px-6 rfp-py-3 rfp-bg-surface-2 hover:rfp-bg-surface-3 rfp-backdrop-blur-sm rfp-rounded-lg rfp-text-fg-primary rfp-font-medium rfp-transition-all\"\n >\n <Download className=\"rfp-w-5 rfp-h-5\" />\n {t('common.download')}\n </button>\n </div>\n );\n};\n","import React from 'react';\nimport { useTranslator } from '../i18n/LocaleContext';\n\nexport const RendererLoading: React.FC = () => {\n const t = useTranslator();\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-text-fg-muted\">\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-gap-3\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-rounded-full rfp-border-2 rfp-border-fg-muted rfp-border-t-transparent rfp-animate-spin\" />\n <span className=\"rfp-text-sm\">{t('common.loading') ?? 'Loading...'}</span>\n </div>\n </div>\n );\n};\n","import React, { useState, useEffect, useCallback, useMemo, useRef, Suspense } from 'react';\nimport { motion } from 'framer-motion';\nimport { X, Download, ChevronLeft, ChevronRight } from 'lucide-react';\nimport { getFileType, createTranslator, type Locale, type Messages, type Translator, type Theme } from '@eternalheart/file-preview-core';\nimport { LocaleProvider } from './i18n/LocaleContext';\nimport { ThemeProvider } from './ThemeContext';\nimport type { ToolbarGroup } from './renderers/toolbar.types';\nimport { getImageToolbarGroups } from './renderers/Image/toolbar';\nimport { getPdfToolbarGroups } from './renderers/Pdf/toolbar';\nimport { getEpubToolbarGroups } from './renderers/Epub/toolbar';\nimport { getMobiToolbarGroups } from './renderers/Mobi/toolbar';\nimport { getZipToolbarGroups, type ZipToolbarStats } from './renderers/Zip/toolbar';\nimport { getTextToolbarGroups } from './renderers/Text/toolbar';\nimport { getMarkdownToolbarGroups } from './renderers/Markdown/toolbar';\n\nimport { PreviewFileInput, CustomRenderer, CustomRendererContext } from './types';\nimport type { CustomRendererEventPayload, PreviewFile, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';\nimport { downloadFileWithFetcher } from '@eternalheart/file-preview-core';\nimport { normalizeFiles } from './utils/fileNormalizer';\nimport { RequestProvider, useResolvedUrl, useFetcher } from './RequestContext';\n// Renderer 通过 React.lazy 动态加载,运行时按需下载对应 chunk\nimport {\n ImageRenderer,\n PdfRenderer,\n DocxRenderer,\n XlsxRenderer,\n PptxRenderer,\n MsgRenderer,\n EpubRenderer,\n MobiRenderer,\n VideoRenderer,\n AudioRenderer,\n MarkdownRenderer,\n JsonRenderer,\n CsvRenderer,\n XmlRenderer,\n SubtitleRenderer,\n ZipRenderer,\n TextRenderer,\n} from './renderers/lazy';\nimport type { EpubRendererHandle } from './renderers/Epub';\nimport type { MobiRendererHandle } from './renderers/Mobi';\n// 不支持类型回退;体积极小,仍静态打包到主入口\nimport { UnsupportedRenderer } from './renderers/Unsupported';\nimport { RendererLoading } from './renderers/RendererLoading';\n\nconst MAX_ZIP_NESTING_DEPTH = 3;\n\nexport interface FilePreviewContentProps {\n files: PreviewFileInput[];\n currentIndex: number;\n onNavigate?: (index: number) => void;\n customRenderers?: CustomRenderer[];\n /** 运行模式:modal(弹窗) 或 embed(嵌入) */\n mode?: 'modal' | 'embed';\n /** 关闭回调,仅 modal 模式使用 */\n onClose?: () => void;\n /** ZIP 嵌套深度(内部使用),超过上限时不再递归渲染 ZIP */\n zipNestingDepth?: number;\n /** 国际化语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义翻译字典,浅合并到内置字典之上 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n /** 无头模式:隐藏工具栏和导航箭头,仅渲染文件内容 */\n headless?: boolean;\n /** 主题模式,默认 'dark' */\n theme?: Theme;\n /** 自定义渲染器派发的事件出口,载荷为 `{ name, payload, file }` */\n onCustomEvent?: (event: CustomRendererEventPayload) => void;\n /** 自定义 RequestInit(或工厂函数):用于注入 Authorization 等鉴权头 */\n requestInit?: RequestInitFactory;\n /** 自定义请求处理器:完全接管库内 fetch;与 requestInit 同时存在时 handler 接收已合并的 init */\n requestHandler?: RequestHandler;\n /** 返回 true 时,对应文件会先经 fetcher 拉成 blob: URL 再喂给 image/video/audio/pdf 等 renderer */\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n /**\n * 自定义下载回调。提供后完全接管下载行为;\n * 不提供时,库内默认通过 fetcher 拉成 Blob 触发下载(鉴权 URL 场景自动可用)。\n */\n onDownload?: (file: PreviewFile) => void | Promise<void>;\n}\n\nexport const FilePreviewContent: React.FC<FilePreviewContentProps> = (props) => {\n const { requestInit, requestHandler, shouldFetchAsBlob } = props;\n return (\n <RequestProvider\n requestInit={requestInit}\n requestHandler={requestHandler}\n shouldFetchAsBlob={shouldFetchAsBlob}\n >\n <FilePreviewContentInner {...props} />\n </RequestProvider>\n );\n};\n\nconst FilePreviewContentInner: React.FC<FilePreviewContentProps> = ({\n files,\n currentIndex,\n onNavigate,\n customRenderers = [],\n mode = 'modal',\n onClose,\n zipNestingDepth = 0,\n locale = 'zh-CN',\n messages: userMessages,\n headless = false,\n theme = 'dark',\n onCustomEvent,\n onDownload,\n // 以下三项已由外层 RequestProvider 消费,Inner 内不再直接使用\n requestInit: _requestInit,\n requestHandler: _requestHandler,\n shouldFetchAsBlob: _shouldFetchAsBlob,\n}) => {\n const t: Translator = useMemo(\n () => createTranslator({ locale, messages: userMessages }),\n [locale, userMessages],\n );\n\n const [systemDark, setSystemDark] = useState(() =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : true,\n );\n\n useEffect(() => {\n if (theme !== 'auto') return;\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [theme]);\n\n const resolvedTheme = theme === 'auto' ? (systemDark ? 'dark' : 'light') : theme;\n\n const [zoom, setZoom] = useState(1);\n const [rotation, setRotation] = useState(0);\n const [currentPage, setCurrentPage] = useState(1);\n const [, setTotalPages] = useState(1);\n const [contentNaturalWidth, setContentNaturalWidth] = useState(0);\n const [contentNaturalHeight, setContentNaturalHeight] = useState(0);\n const [imageResetKey, setImageResetKey] = useState(0);\n const contentRef = useRef<HTMLDivElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const epubRef = useRef<EpubRendererHandle>(null);\n const [epubCurrent, setEpubCurrent] = useState(0);\n const [epubTotal, setEpubTotal] = useState(0);\n const [epubFullWidth, setEpubFullWidth] = useState(false);\n const mobiRef = useRef<MobiRendererHandle>(null);\n const [mobiCurrent, setMobiCurrent] = useState(0);\n const [mobiTotal, setMobiTotal] = useState(0);\n const [mobiFullWidth, setMobiFullWidth] = useState(false);\n const [zipStats, setZipStats] = useState<ZipToolbarStats | null>(null);\n const [textWordWrap, setTextWordWrap] = useState(true);\n const [textHtmlPreview, setTextHtmlPreview] = useState(false);\n const [markdownViewMode, setMarkdownViewMode] = useState<'preview' | 'source'>('preview');\n\n // 导航箭头自动隐藏\n const [navVisible, setNavVisible] = useState(true);\n const navHideTimerRef = useRef<number | null>(null);\n const NAV_HIDE_DELAY = 2000;\n\n const resetNavTimer = useCallback(() => {\n setNavVisible(true);\n if (navHideTimerRef.current) {\n clearTimeout(navHideTimerRef.current);\n }\n navHideTimerRef.current = window.setTimeout(() => {\n setNavVisible(false);\n }, NAV_HIDE_DELAY);\n }, []);\n\n const handleMouseMove = useCallback(() => {\n resetNavTimer();\n }, [resetNavTimer]);\n\n // 标准化文件输入\n const normalizedFiles = useMemo(() => normalizeFiles(files), [files]);\n\n const currentFile = normalizedFiles[currentIndex];\n\n // 命中 shouldFetchAsBlob 时,把 file.url 转成 blob: URL 喂给 src 类 renderer\n const resolvedUrl = useResolvedUrl(currentFile);\n\n // 检查是否有自定义渲染器匹配当前文件\n const customRenderer = useMemo(() => {\n if (!currentFile) return null;\n return customRenderers.find(renderer => renderer.test(currentFile));\n }, [currentFile, customRenderers]);\n\n const fileType = currentFile ? getFileType(currentFile) : 'unsupported';\n\n // 自定义渲染器事件派发器:未绑定 onCustomEvent 时静默忽略\n const emitCustom = useCallback(\n (name: string, payload?: unknown) => {\n if (!currentFile) return;\n onCustomEvent?.({ name, payload, file: currentFile });\n },\n [currentFile, onCustomEvent],\n );\n\n // 自定义渲染器上下文:注入给 render / getToolbarGroups\n const customCtx = useMemo<CustomRendererContext>(\n () => ({\n emit: emitCustom,\n t,\n theme: resolvedTheme,\n locale,\n }),\n [emitCustom, t, resolvedTheme, locale],\n );\n\n // 重置状态当文件改变时\n useEffect(() => {\n setZoom(1);\n setRotation(0);\n setCurrentPage(1);\n setTotalPages(1);\n setContentNaturalWidth(0);\n setContentNaturalHeight(0);\n setNavVisible(true);\n if (navHideTimerRef.current) {\n clearTimeout(navHideTimerRef.current);\n }\n }, [currentIndex]);\n\n // 图片加载后默认适应窗口\n useEffect(() => {\n if (fileType === 'image' && contentNaturalWidth > 0 && contentNaturalHeight > 0 && contentRef.current) {\n const containerWidth = contentRef.current.clientWidth;\n const containerHeight = contentRef.current.clientHeight;\n const scaleX = containerWidth / contentNaturalWidth;\n const scaleY = containerHeight / contentNaturalHeight;\n const newZoom = Math.min(scaleX, scaleY);\n setZoom(Math.max(0.01, Math.min(10, newZoom)));\n }\n }, [fileType, contentNaturalWidth, contentNaturalHeight]);\n\n // 导航箭头自动隐藏计时器启动 & 清理\n useEffect(() => {\n if (normalizedFiles.length > 1) {\n resetNavTimer();\n }\n return () => {\n if (navHideTimerRef.current) {\n clearTimeout(navHideTimerRef.current);\n }\n };\n }, [normalizedFiles.length, resetNavTimer]);\n\n // 键盘导航\n // - modal 模式:全局监听(window)\n // - embed 模式:只在根容器 focus 时监听,避免影响外部页面交互\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && mode === 'modal') {\n onClose?.();\n } else if (e.key === 'ArrowLeft' && currentIndex > 0) {\n onNavigate?.(currentIndex - 1);\n } else if (e.key === 'ArrowRight' && currentIndex < normalizedFiles.length - 1) {\n onNavigate?.(currentIndex + 1);\n }\n };\n\n if (mode === 'modal') {\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n } else {\n const el = rootRef.current;\n if (!el) return;\n el.addEventListener('keydown', handleKeyDown as EventListener);\n return () => el.removeEventListener('keydown', handleKeyDown as EventListener);\n }\n }, [mode, currentIndex, normalizedFiles.length, onClose, onNavigate]);\n\n const handleZoomIn = useCallback(() => {\n setZoom((prev) => Math.min(prev + 0.1, 10));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setZoom((prev) => Math.max(prev - 0.1, 0.01));\n }, []);\n\n const handleRotate = useCallback(() => {\n setRotation((prev) => prev + 90);\n }, []);\n\n const handleRotateLeft = useCallback(() => {\n setRotation((prev) => prev - 90);\n }, []);\n\n const handleFitToWidth = useCallback(() => {\n if (contentRef.current && contentNaturalWidth > 0 && contentNaturalHeight > 0) {\n const containerWidth = contentRef.current.clientWidth;\n const containerHeight = contentRef.current.clientHeight;\n const scaleX = containerWidth / contentNaturalWidth;\n const scaleY = containerHeight / contentNaturalHeight;\n const newZoom = Math.min(scaleX, scaleY);\n setZoom(Math.max(0.01, Math.min(10, newZoom)));\n } else {\n setZoom(1);\n }\n setRotation(0);\n setImageResetKey(k => k + 1);\n }, [contentNaturalWidth, contentNaturalHeight]);\n\n const handleOriginalSize = useCallback(() => {\n setZoom(1);\n setRotation(0);\n setImageResetKey(k => k + 1);\n }, []);\n\n const handleZoomChange = useCallback((newZoom: number) => {\n setZoom(newZoom);\n }, []);\n\n const handleReset = useCallback(() => {\n setZoom(1);\n setRotation(0);\n setImageResetKey(k => k + 1);\n }, []);\n\n const fetcher = useFetcher();\n const handleDownload = useCallback(async () => {\n if (!currentFile) return;\n if (onDownload) {\n await onDownload(currentFile);\n return;\n }\n try {\n await downloadFileWithFetcher(currentFile.url, currentFile.name, fetcher);\n } catch (err) {\n console.error('[file-preview] download failed:', err);\n }\n }, [currentFile, onDownload, fetcher]);\n\n const handleEpubChapterChange = useCallback((current: number, total: number) => {\n setEpubCurrent(current);\n setEpubTotal(total);\n }, []);\n\n const handleMobiChapterChange = useCallback((current: number, total: number) => {\n setMobiCurrent(current);\n setMobiTotal(total);\n }, []);\n\n const handleZipStatsChange = useCallback((stats: ZipToolbarStats | null) => {\n setZipStats(stats);\n }, []);\n\n if (!currentFile) return null;\n\n const showCloseButton = mode === 'modal' && !!onClose;\n\n // 工具栏配置 — 各 Renderer 自行声明。命中自定义渲染器时优先使用其 getToolbarGroups\n const toolGroups: ToolbarGroup[] = (() => {\n if (customRenderer) {\n return customRenderer.getToolbarGroups?.(currentFile, customCtx) ?? [];\n }\n if (fileType === 'image') {\n return getImageToolbarGroups({\n zoom,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n onFitToWidth: handleFitToWidth,\n onOriginalSize: handleOriginalSize,\n onRotateLeft: handleRotateLeft,\n onRotateRight: handleRotate,\n onReset: handleReset,\n t,\n });\n }\n if (fileType === 'pdf') {\n return getPdfToolbarGroups({\n zoom,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n onReset: handleReset,\n t,\n });\n }\n if (fileType === 'epub') {\n return getEpubToolbarGroups({\n epubRef,\n current: epubCurrent,\n total: epubTotal,\n fullWidth: epubFullWidth,\n t,\n });\n }\n if (fileType === 'mobi') {\n return getMobiToolbarGroups({\n mobiRef,\n current: mobiCurrent,\n total: mobiTotal,\n fullWidth: mobiFullWidth,\n t,\n });\n }\n if (fileType === 'zip') {\n return getZipToolbarGroups({ stats: zipStats, t });\n }\n if (fileType === 'text') {\n const ext = currentFile.name.split('.').pop()?.toLowerCase() || '';\n return getTextToolbarGroups({\n wordWrap: textWordWrap,\n onToggleWrap: () => setTextWordWrap(prev => !prev),\n isHtml: ext === 'html' || ext === 'htm',\n htmlPreview: textHtmlPreview,\n onToggleHtmlPreview: () => setTextHtmlPreview(prev => !prev),\n t,\n });\n }\n if (fileType === 'markdown') {\n return getMarkdownToolbarGroups({\n viewMode: markdownViewMode,\n onToggleViewMode: () => setMarkdownViewMode(prev => prev === 'preview' ? 'source' : 'preview'),\n t,\n });\n }\n return [];\n })();\n\n // 操作组:下载、关闭(通用,不属于任何 Renderer)\n const actionGroups: ToolbarGroup[] = [\n {\n items: [\n { type: 'button', icon: <Download className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('common.download'), action: handleDownload },\n ],\n },\n ...(showCloseButton ? [{\n items: [\n { type: 'button' as const, icon: <X className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('common.close'), action: onClose! },\n ],\n }] : []),\n ];\n\n const renderToolbarItems = (groups: ToolbarGroup[], dividerClass: string) =>\n groups.map((group, gi, arr) => (\n <React.Fragment key={gi}>\n {group.items.map((item, ii) =>\n item.type === 'button' ? (\n <ToolbarButton\n key={`${gi}-${ii}`}\n icon={item.icon}\n label={item.tooltip}\n onClick={item.action}\n disabled={item.disabled}\n />\n ) : (\n <span\n key={`${gi}-${ii}`}\n className=\"rfp-text-xs rfp-text-center rfp-font-medium rfp-tabular-nums rfp-text-fg-tertiary\"\n style={{ minWidth: item.minWidth || 'auto' }}\n >\n {item.content}\n </span>\n )\n )}\n {gi < arr.length - 1 && <div className={`rfp-w-px rfp-h-4 rfp-bg-divide ${dividerClass}`} />}\n </React.Fragment>\n ));\n\n return (\n <LocaleProvider locale={locale} messages={userMessages}>\n <ThemeProvider theme={resolvedTheme}>\n <div\n ref={rootRef}\n tabIndex={mode === 'embed' ? 0 : -1}\n data-theme={resolvedTheme}\n className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-flex-col rfp-overflow-hidden rfp-outline-none\"\n >\n {/* 顶部工具栏 - 全屏融合式 */}\n {!headless && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"rfp-flex-shrink-0 rfp-z-10 rfp-backdrop-blur-md rfp-border-b rfp-bg-surface-toolbar rfp-border-line\"\n style={{ paddingTop: 'env(safe-area-inset-top, 0px)' }}\n >\n {/* 第一行:文件名 + 分页 + 关闭/下载(移动端右侧)/ 全部按钮(桌面端) */}\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-3 md:rfp-px-5 rfp-py-1.5 md:rfp-py-2.5\">\n {/* 左侧:文件名 + 分页 */}\n <div className=\"rfp-flex rfp-items-center rfp-flex-1 rfp-min-w-0 rfp-mr-2 md:rfp-mr-3\">\n <h2 className=\"rfp-font-medium rfp-text-xs md:rfp-text-sm rfp-truncate rfp-text-fg-primary\">\n {currentFile.name}\n </h2>\n <span className=\"rfp-text-xs rfp-ml-2 rfp-flex-shrink-0 rfp-text-fg-muted\">\n {currentIndex + 1}/{normalizedFiles.length}\n </span>\n </div>\n\n {/* 移动端:仅显示下载+关闭 */}\n <div className=\"rfp-flex rfp-items-center rfp-gap-1 md:rfp-hidden rfp-flex-shrink-0\">\n {renderToolbarItems(actionGroups, 'rfp-mx-0.5')}\n </div>\n\n {/* 桌面端:所有工具按钮 */}\n <div className=\"rfp-hidden md:rfp-flex rfp-items-center rfp-gap-1 rfp-flex-shrink-0\">\n {renderToolbarItems(toolGroups, 'rfp-mx-1')}\n {toolGroups.length > 0 && <div className=\"rfp-w-px rfp-h-4 rfp-mx-1 rfp-bg-divide\" />}\n {renderToolbarItems(actionGroups, 'rfp-mx-1')}\n </div>\n </div>\n\n {/* 第二行:移动端工具按钮(image/pdf/epub) */}\n {toolGroups.length > 0 && (\n <div className=\"rfp-flex rfp-items-center rfp-gap-1 rfp-px-3 rfp-pb-1.5 rfp-overflow-x-auto scrollbar-hide md:rfp-hidden\">\n {renderToolbarItems(toolGroups, 'rfp-mx-0.5')}\n </div>\n )}\n </motion.div>\n )}\n\n {/* 内容区域 */}\n <div\n ref={contentRef}\n className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center rfp-overflow-auto\"\n onMouseMove={handleMouseMove}\n >\n {customRenderer ? (\n customRenderer.render(currentFile, customCtx)\n ) : (\n <Suspense fallback={<RendererLoading />}>\n {fileType === 'image' && (\n <ImageRenderer\n url={resolvedUrl}\n zoom={zoom}\n rotation={rotation}\n resetKey={imageResetKey}\n fileSize={currentFile.size}\n onZoomChange={handleZoomChange}\n onNaturalWidthChange={setContentNaturalWidth}\n onNaturalHeightChange={setContentNaturalHeight}\n />\n )}\n {fileType === 'pdf' && (\n <PdfRenderer\n url={resolvedUrl}\n zoom={zoom}\n currentPage={currentPage}\n onPageChange={setCurrentPage}\n onTotalPagesChange={setTotalPages}\n onPageWidthChange={setContentNaturalWidth}\n />\n )}\n {fileType === 'docx' && <DocxRenderer url={resolvedUrl} />}\n {fileType === 'xlsx' && <XlsxRenderer url={resolvedUrl} />}\n {fileType === 'pptx' && <PptxRenderer url={resolvedUrl} />}\n {fileType === 'msg' && <MsgRenderer url={resolvedUrl} />}\n {fileType === 'epub' && (\n <EpubRenderer\n ref={epubRef}\n url={resolvedUrl}\n onChapterChange={handleEpubChapterChange}\n onFullWidthChange={setEpubFullWidth}\n />\n )}\n {fileType === 'mobi' && (\n <MobiRenderer\n ref={mobiRef}\n url={resolvedUrl}\n onChapterChange={handleMobiChapterChange}\n onFullWidthChange={setMobiFullWidth}\n />\n )}\n {fileType === 'video' && <VideoRenderer url={resolvedUrl} />}\n {fileType === 'audio' && (\n <AudioRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'markdown' && <MarkdownRenderer url={resolvedUrl} viewMode={markdownViewMode} />}\n {fileType === 'json' && (\n <JsonRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'csv' && (\n <CsvRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'xml' && (\n <XmlRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'subtitle' && (\n <SubtitleRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'zip' && (\n zipNestingDepth >= MAX_ZIP_NESTING_DEPTH ? (\n <UnsupportedRenderer\n fileName={currentFile.name}\n fileType={currentFile.type}\n onDownload={handleDownload}\n />\n ) : (\n <ZipRenderer url={resolvedUrl} onStatsChange={handleZipStatsChange} nestingDepth={zipNestingDepth} />\n )\n )}\n {fileType === 'text' && (\n <TextRenderer\n url={resolvedUrl}\n fileName={currentFile.name}\n wordWrap={textWordWrap}\n htmlPreview={textHtmlPreview}\n />\n )}\n {fileType === 'unsupported' && (\n <UnsupportedRenderer\n fileName={currentFile.name}\n fileType={currentFile.type}\n onDownload={handleDownload}\n />\n )}\n </Suspense>\n )}\n </div>\n\n {/* 左右导航箭头 - 自动隐藏 */}\n {!headless && normalizedFiles.length > 1 && (\n <>\n {currentIndex > 0 && (\n <motion.button\n initial={{ opacity: 0 }}\n animate={{ opacity: navVisible ? 1 : 0, x: navVisible ? 0 : -20 }}\n transition={{ duration: 0.2 }}\n onClick={() => onNavigate?.(currentIndex - 1)}\n onMouseEnter={() => setNavVisible(true)}\n style={{ pointerEvents: navVisible ? 'auto' : 'none' }}\n className=\"rfp-absolute rfp-z-20 rfp-left-2 md:rfp-left-4 rfp-top-1/2 -rfp-translate-y-1/2 rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-rounded-full rfp-backdrop-blur-xl rfp-border rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-shadow-2xl rfp-bg-surface-nav rfp-border-line hover:rfp-bg-surface-nav-hover rfp-text-fg-primary\"\n >\n <ChevronLeft className=\"rfp-w-5 rfp-h-5 md:rfp-w-6 md:rfp-h-6\" />\n </motion.button>\n )}\n\n {currentIndex < normalizedFiles.length - 1 && (\n <motion.button\n initial={{ opacity: 0 }}\n animate={{ opacity: navVisible ? 1 : 0, x: navVisible ? 0 : 20 }}\n transition={{ duration: 0.2 }}\n onClick={() => onNavigate?.(currentIndex + 1)}\n onMouseEnter={() => setNavVisible(true)}\n style={{ pointerEvents: navVisible ? 'auto' : 'none' }}\n className=\"rfp-absolute rfp-z-20 rfp-right-2 md:rfp-right-4 rfp-top-1/2 -rfp-translate-y-1/2 rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-rounded-full rfp-backdrop-blur-xl rfp-border rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-shadow-2xl rfp-bg-surface-nav rfp-border-line hover:rfp-bg-surface-nav-hover rfp-text-fg-primary\"\n >\n <ChevronRight className=\"rfp-w-5 rfp-h-5 md:rfp-w-6 md:rfp-h-6\" />\n </motion.button>\n )}\n </>\n )}\n </div>\n </ThemeProvider>\n </LocaleProvider>\n );\n};\n\n// 工具栏按钮组件\ninterface ToolbarButtonProps {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n}\n\nconst ToolbarButton: React.FC<ToolbarButtonProps> = ({ icon, label, onClick, disabled }) => {\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className={`rfp-relative rfp-group rfp-p-2 md:rfp-p-1.5 rfp-rounded-md rfp-transition-all rfp-select-none ${\n disabled\n ? 'rfp-text-fg-disabled rfp-cursor-not-allowed'\n : 'rfp-text-fg-primary hover:rfp-bg-surface-2 active:rfp-bg-surface-3'\n }`}\n >\n {icon}\n <span className=\"rfp-absolute rfp-left-1/2 -rfp-translate-x-1/2 rfp-top-full rfp-mt-1.5 rfp-px-2 rfp-py-1 rfp-text-xs rfp-rounded rfp-whitespace-nowrap rfp-pointer-events-none rfp-opacity-0 rfp-invisible group-hover:rfp-opacity-100 group-hover:rfp-visible rfp-transition-opacity rfp-duration-200 rfp-z-50 rfp-bg-fg-primary rfp-text-fg-inverse\">\n <span className=\"rfp-absolute rfp-left-1/2 -rfp-translate-x-1/2 -rfp-top-1 rfp-w-2 rfp-h-2 rfp-rotate-45 rfp-bg-fg-primary\" />\n <span className=\"rfp-relative\">{label}</span>\n </span>\n </button>\n );\n};\n","import { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { PreviewFileInput, CustomRenderer } from './types';\nimport { FilePreviewContent } from './FilePreviewContent';\nimport type { Locale, Messages, Theme, CustomRendererEventPayload, PreviewFile, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';\n\ninterface FilePreviewModalProps {\n files: PreviewFileInput[];\n currentIndex: number;\n isOpen: boolean;\n onClose: () => void;\n onNavigate?: (index: number) => void;\n customRenderers?: CustomRenderer[];\n /** 国际化语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义翻译字典 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n /** 无头模式:隐藏工具栏和导航箭头 */\n headless?: boolean;\n /** 主题模式,默认 'dark' */\n theme?: Theme;\n /** 自定义渲染器派发的事件出口 */\n onCustomEvent?: (event: CustomRendererEventPayload) => void;\n /** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */\n requestInit?: RequestInitFactory;\n /** 自定义请求处理器:完全接管库内 fetch */\n requestHandler?: RequestHandler;\n /** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */\n onDownload?: (file: PreviewFile) => void | Promise<void>;\n}\n\nexport const FilePreviewModal: React.FC<FilePreviewModalProps> = ({\n files,\n currentIndex,\n isOpen,\n onClose,\n onNavigate,\n customRenderers = [],\n locale,\n messages,\n headless,\n theme = 'dark',\n onCustomEvent,\n requestInit,\n requestHandler,\n shouldFetchAsBlob,\n onDownload,\n}) => {\n const [systemDark, setSystemDark] = useState(() =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : true,\n );\n\n useEffect(() => {\n if (theme !== 'auto') return;\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [theme]);\n\n const resolvedTheme = theme === 'auto' ? (systemDark ? 'dark' : 'light') : theme;\n\n // 锁定 body 滚动\n useEffect(() => {\n if (isOpen) {\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n\n document.body.style.overflow = 'hidden';\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n };\n }\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n const modalContent = (\n <div className=\"rfp-root\" data-theme={resolvedTheme}>\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"rfp-fixed rfp-inset-0 rfp-z-[9999] rfp-flex rfp-items-center rfp-justify-center rfp-backdrop-blur-md rfp-overflow-hidden rfp-bg-surface-overlay\"\n onClick={onClose}\n onWheel={(e) => e.stopPropagation()}\n >\n <div\n className=\"rfp-relative rfp-w-full rfp-h-full\"\n onClick={(e) => e.stopPropagation()}\n >\n <FilePreviewContent\n mode=\"modal\"\n files={files}\n currentIndex={currentIndex}\n onClose={onClose}\n onNavigate={onNavigate}\n customRenderers={customRenderers}\n locale={locale}\n messages={messages}\n headless={headless}\n theme={theme}\n onCustomEvent={onCustomEvent}\n requestInit={requestInit}\n requestHandler={requestHandler}\n shouldFetchAsBlob={shouldFetchAsBlob}\n onDownload={onDownload}\n />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n\n return createPortal(modalContent, document.body);\n};\n","import { useEffect, useState } from 'react';\nimport { PreviewFileInput, CustomRenderer } from './types';\nimport { FilePreviewContent } from './FilePreviewContent';\nimport type { Locale, Messages, Theme, CustomRendererEventPayload, PreviewFile, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';\n\ninterface FilePreviewEmbedProps {\n files: PreviewFileInput[];\n currentIndex?: number;\n onNavigate?: (index: number) => void;\n customRenderers?: CustomRenderer[];\n /** 宽度,默认 100% 填充父容器 */\n width?: number | string;\n /** 高度,默认 100% 填充父容器 */\n height?: number | string;\n className?: string;\n style?: React.CSSProperties;\n /** 国际化语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义翻译字典 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n /** 无头模式:隐藏工具栏和导航箭头 */\n headless?: boolean;\n /** 主题模式,默认 'dark' */\n theme?: Theme;\n /** 自定义渲染器派发的事件出口 */\n onCustomEvent?: (event: CustomRendererEventPayload) => void;\n /** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */\n requestInit?: RequestInitFactory;\n /** 自定义请求处理器:完全接管库内 fetch */\n requestHandler?: RequestHandler;\n /** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */\n onDownload?: (file: PreviewFile) => void | Promise<void>;\n}\n\nexport const FilePreviewEmbed: React.FC<FilePreviewEmbedProps> = ({\n files,\n currentIndex = 0,\n onNavigate,\n customRenderers = [],\n width = '100%',\n height = '100%',\n className,\n style,\n locale,\n messages,\n headless,\n theme = 'dark',\n onCustomEvent,\n requestInit,\n requestHandler,\n shouldFetchAsBlob,\n onDownload,\n}) => {\n const [systemDark, setSystemDark] = useState(() =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : true,\n );\n\n useEffect(() => {\n if (theme !== 'auto') return;\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [theme]);\n\n const resolvedTheme = theme === 'auto' ? (systemDark ? 'dark' : 'light') : theme;\n\n return (\n <div\n className={`rfp-root ${className ?? ''}`}\n style={{ width, height, ...style }}\n data-theme={resolvedTheme}\n >\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-overflow-hidden rfp-bg-surface-overlay\">\n <FilePreviewContent\n mode=\"embed\"\n files={files}\n currentIndex={currentIndex}\n onNavigate={onNavigate}\n customRenderers={customRenderers}\n locale={locale}\n messages={messages}\n headless={headless}\n theme={theme}\n onCustomEvent={onCustomEvent}\n requestInit={requestInit}\n requestHandler={requestHandler}\n shouldFetchAsBlob={shouldFetchAsBlob}\n onDownload={onDownload}\n />\n </div>\n </div>\n );\n};\n","import { pdfjs } from 'react-pdf';\n\n/**\n * PDF.js Worker 配置选项\n */\nexport interface PdfConfigOptions {\n /**\n * PDF.js worker 文件路径\n * 默认使用 CDN: `https://unpkg.com/pdfjs-dist@${version}/build/pdf.worker.min.mjs`\n */\n workerSrc?: string;\n \n /**\n * CMap 文件目录路径\n * 默认使用 CDN: `https://unpkg.com/pdfjs-dist@${version}/cmaps/`\n */\n cMapUrl?: string;\n \n /**\n * 是否使用压缩的 CMap 文件\n * 默认: true\n */\n cMapPacked?: boolean;\n}\n\n/**\n * 配置 PDF.js\n *\n * @example\n * ```ts\n * // 使用本地静态文件(推荐用于生产环境)\n * configurePdfjs({\n * workerSrc: '/pdfjs/pdf.worker.min.mjs',\n * cMapUrl: '/pdfjs/cmaps/',\n * cMapPacked: true\n * });\n * ```\n *\n * @example\n * ```ts\n * // 使用 CDN(默认配置)\n * configurePdfjs(); // 自动使用 unpkg CDN\n * ```\n */\nexport function configurePdfjs(options?: PdfConfigOptions) {\n if (typeof window === 'undefined') return;\n\n const {\n workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`,\n cMapUrl = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,\n cMapPacked = true\n } = options || {};\n\n pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;\n // @ts-ignore - cMapUrl 和 cMapPacked 在 react-pdf 的类型定义中不存在,但在运行时可用\n pdfjs.GlobalWorkerOptions.cMapUrl = cMapUrl;\n // @ts-ignore\n pdfjs.GlobalWorkerOptions.cMapPacked = cMapPacked;\n}\n\n// 默认使用 CDN 配置\nconfigurePdfjs();\n\nexport { pdfjs };\n\n","// 导入样式\nimport './index.css';\n\n// 导入版本号\nimport packageJson from '../package.json';\n\n// 导出版本号\nexport const VERSION = packageJson.version;\n\n// 导出主组件\nexport { FilePreviewModal } from './FilePreviewModal';\nexport { FilePreviewEmbed } from './FilePreviewEmbed';\nexport { FilePreviewContent } from './FilePreviewContent';\n\n// 导出类型定义\nexport type {\n PreviewFile,\n PreviewFileLink,\n PreviewFileInput,\n FileType,\n ToolbarAction,\n PreviewState,\n CustomRenderer,\n CustomRendererContext,\n CustomRendererEventPayload,\n} from './types';\n\n// 导出工具函数\nexport { normalizeFile, normalizeFiles } from './utils/fileNormalizer';\n\n// 导出 PDF.js 配置函数和类型\nexport { configurePdfjs, pdfjs } from './utils/pdfConfig';\nexport type { PdfConfigOptions } from './utils/pdfConfig';\n\n// 导出 i18n 国际化\nexport { LocaleProvider, useTranslator, useLocale } from './i18n/LocaleContext';\nexport type { LocaleProviderProps, LocaleContextValue } from './i18n/LocaleContext';\nexport type {\n Locale,\n Messages,\n MessageKey,\n Translator,\n TranslateParams,\n CreateTranslatorOptions,\n Theme,\n} from '@eternalheart/file-preview-core';\n\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { motion } from 'framer-motion';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ninterface ImageRendererProps {\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n onZoomChange?: (zoom: number) => void;\n onNaturalWidthChange?: (width: number) => void;\n onNaturalHeightChange?: (height: number) => void;\n}\n\nexport const ImageRenderer: React.FC<ImageRendererProps> = ({\n url,\n zoom,\n rotation,\n resetKey,\n fileSize,\n onZoomChange,\n onNaturalWidthChange,\n onNaturalHeightChange\n}) => {\n const t = useTranslator();\n const [loaded, setLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [internalZoom, setInternalZoom] = useState(1);\n const [naturalSize, setNaturalSize] = useState({ width: 0, height: 0 });\n const imgRef = useRef<HTMLImageElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setLoaded(false);\n setError(null);\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n }, [url]);\n\n // 当外部 zoom 改变时,同步内部 zoom\n useEffect(() => {\n setInternalZoom(zoom);\n }, [zoom]);\n\n // 适应窗口/原始尺寸等操作时重置位置居中\n useEffect(() => {\n if (resetKey !== undefined) {\n setPosition({ x: 0, y: 0 });\n }\n }, [resetKey]);\n\n const handleLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(true);\n const img = e.currentTarget;\n setNaturalSize({ width: img.naturalWidth, height: img.naturalHeight });\n onNaturalWidthChange?.(img.naturalWidth);\n onNaturalHeightChange?.(img.naturalHeight);\n };\n\n // 边界限制:确保图片至少有一部分可见\n const clampPosition = useCallback((pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.current;\n if (!container || naturalSize.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.width * currentZoom;\n const imgH = naturalSize.height * currentZoom;\n\n // 至少保留 margin px 的图片在视口内\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n }, [naturalSize]);\n\n const handleError = () => {\n setError(t('image.load_failed'));\n setLoaded(true);\n };\n\n // 双击复原:居中 + 缩放100%\n const handleDoubleClick = () => {\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n onZoomChange?.(1);\n };\n\n // 鼠标滚轮缩放 —— 以鼠标位置为缩放原点\n // 使用原生事件 + passive: false,确保 preventDefault 生效,\n // 避免滚轮事件冒泡触发外层(如嵌入模式下的页面滚动)\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n\n setInternalZoom(prev => {\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n setPosition(pos => clampPosition({\n x: mouseX - scale * (mouseX - pos.x),\n y: mouseY - scale * (mouseY - pos.y),\n }, newZoom));\n\n onZoomChange?.(newZoom);\n return newZoom;\n });\n };\n\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n return () => container.removeEventListener('wheel', handleWheelNative);\n }, [onZoomChange, clampPosition]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (e.button !== 0) return;\n setIsDragging(true);\n setDragStart({\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n });\n }, [position]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDragging) return;\n setPosition(clampPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n }, internalZoom));\n }, [isDragging, dragStart, internalZoom, clampPosition]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-relative rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-overflow-hidden\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {!loaded && !error && (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {error && (\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n <motion.img\n ref={imgRef}\n src={url}\n alt=\"Preview\"\n className={`rfp-max-w-none rfp-select-none ${!loaded ? 'rfp-hidden' : ''}`}\n style={{\n transform: `translate(${position.x}px, ${position.y}px) scale(${internalZoom}) rotate(${rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging ? 'none' : 'transform 0.3s ease-out',\n }}\n onLoad={handleLoad}\n onError={handleError}\n onDoubleClick={handleDoubleClick}\n initial={{ opacity: 0 }}\n animate={{ opacity: loaded ? 1 : 0 }}\n transition={{ duration: 0.3 }}\n draggable={false}\n />\n\n {/* 右下角分辨率 */}\n {loaded && !error && naturalSize.width > 0 && (\n <div className=\"rfp-absolute rfp-bottom-2 rfp-right-3 rfp-text-[10px] rfp-text-fg-disabled hover:rfp-text-fg-secondary rfp-transition-colors rfp-pointer-events-auto rfp-select-none rfp-cursor-default\">\n {naturalSize.width} × {naturalSize.height}{fileSize != null && ` · ${fileSize < 1024 ? `${fileSize} B` : fileSize < 1024 * 1024 ? `${(fileSize / 1024).toFixed(1)} KB` : `${(fileSize / (1024 * 1024)).toFixed(1)} MB`}`}\n </div>\n )}\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { Document, Page } from 'react-pdf';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\n// 导入 PDF.js 配置\nimport '../../utils/pdfConfig';\n\ninterface PdfRendererProps {\n url: string;\n zoom: number;\n currentPage: number;\n onPageChange: (page: number) => void;\n onTotalPagesChange: (total: number) => void;\n onPageWidthChange?: (width: number) => void;\n}\n\nexport const PdfRenderer: React.FC<PdfRendererProps> = ({\n url,\n zoom,\n currentPage,\n onPageChange,\n onTotalPagesChange,\n onPageWidthChange,\n}) => {\n const t = useTranslator();\n const [numPages, setNumPages] = useState<number>(0);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n useEffect(() => {\n setError(null);\n }, [url]);\n\n const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {\n setNumPages(numPages);\n onTotalPagesChange(numPages);\n onPageChange(1);\n };\n\n const onDocumentLoadError = (error: Error) => {\n console.error('PDF 加载错误:', error);\n setError(t('pdf.load_failed'));\n };\n\n // 滚动时更新当前页码\n const handleScroll = useCallback(() => {\n if (!containerRef.current) return;\n\n const container = containerRef.current;\n const scrollTop = container.scrollTop;\n const containerHeight = container.clientHeight;\n const scrollCenter = scrollTop + containerHeight / 2;\n\n // 找到当前可见的页面\n let currentVisiblePage = 1;\n let minDistance = Infinity;\n\n pageRefs.current.forEach((pageElement, pageNumber) => {\n const rect = pageElement.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const pageCenter = rect.top - containerRect.top + rect.height / 2 + scrollTop;\n const distance = Math.abs(pageCenter - scrollCenter);\n\n if (distance < minDistance) {\n minDistance = distance;\n currentVisiblePage = pageNumber;\n }\n });\n\n if (currentVisiblePage !== currentPage) {\n onPageChange(currentVisiblePage);\n }\n }, [currentPage, onPageChange]);\n\n // 监听滚动事件\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, [handleScroll]);\n\n // 设置页面引用\n const setPageRef = useCallback((pageNumber: number, element: HTMLDivElement | null) => {\n if (element) {\n pageRefs.current.set(pageNumber, element);\n } else {\n pageRefs.current.delete(pageNumber);\n }\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full rfp-overflow-auto rfp-py-4 md:rfp-py-8 rfp-px-2 md:rfp-px-4\"\n >\n {error && (\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n {!error && (\n <Document\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-min-h-screen\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n }\n >\n <div className=\"rfp-flex rfp-flex-col rfp-gap-4\">\n {Array.from(new Array(numPages), (_, index) => {\n const pageNumber = index + 1;\n return (\n <div\n key={`page_${pageNumber}`}\n ref={(el) => setPageRef(pageNumber, el)}\n className=\"rfp-relative\"\n >\n <Page\n pageNumber={pageNumber}\n scale={zoom}\n loading={\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-p-8 rfp-bg-surface-1 rfp-rounded-lg rfp-min-h-[600px]\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n }\n renderTextLayer={false}\n renderAnnotationLayer={false}\n className=\"rfp-shadow-2xl\"\n onRenderSuccess={(page) => {\n if (pageNumber === 1 && onPageWidthChange) {\n // 上报 scale=1 时的原始页面宽度\n onPageWidthChange(page.originalWidth || page.width / zoom);\n }\n }}\n />\n {/* 页码标签 */}\n <div className=\"rfp-absolute rfp-top-2 rfp-right-2 rfp-bg-surface-nav-hover rfp-backdrop-blur-sm rfp-text-fg-primary rfp-text-xs rfp-px-3 rfp-py-1 rfp-rounded-full\">\n {pageNumber}\n </div>\n </div>\n );\n })}\n </div>\n </Document>\n )}\n\n {/* 底部页码指示器 */}\n {numPages > 0 && (\n <div className=\"rfp-sticky rfp-bottom-2 md:rfp-bottom-4 rfp-mt-4 md:rfp-mt-8 rfp-bg-surface-nav-hover rfp-backdrop-blur-xl rfp-text-fg-primary rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-rounded-full rfp-text-xs md:rfp-text-sm rfp-font-medium rfp-shadow-2xl rfp-border rfp-border-line-weak\">\n 第 {currentPage} 页 / 共 {numPages} 页\n </div>\n )}\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport mammoth from 'mammoth';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface DocxRendererProps {\n url: string;\n}\n\n// A4 page dimensions (96dpi)\nconst PAGE_HEIGHT = 1123;\nconst PAGE_PADDING_Y = 60;\nconst PAGE_PADDING_X = 50;\nconst PAGE_CONTENT_HEIGHT = PAGE_HEIGHT - PAGE_PADDING_Y * 2;\nconst PAGE_GAP = 24;\n\nconst contentStyle: React.CSSProperties = {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n lineHeight: '1.8',\n color: '#333',\n};\n\nexport const DocxRenderer: React.FC<DocxRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [html, setHtml] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [pages, setPages] = useState<string[]>([]);\n const measureRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const loadDocx = async () => {\n setLoading(true);\n setError(null);\n setHtml('');\n\n try {\n const response = await fetcher(url);\n if (!response.ok) {\n throw new Error('文件加载失败');\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const result = await mammoth.convertToHtml({ arrayBuffer });\n setHtml(result.value);\n } catch (err) {\n console.error('Docx 解析错误:', err);\n setError(t('docx.parse_failed'));\n } finally {\n setLoading(false);\n }\n };\n\n loadDocx();\n }, [url, fetcher, t]);\n\n const paginate = useCallback(() => {\n const container = measureRef.current;\n if (!container || !html) return;\n\n const children = Array.from(container.children) as HTMLElement[];\n if (children.length === 0) {\n setPages([html]);\n return;\n }\n\n const result: string[][] = [[]];\n let currentPageUsed = 0;\n\n for (const child of children) {\n const h = child.offsetHeight;\n\n // If adding this block would exceed page content area and page isn't empty,\n // start a new page\n if (currentPageUsed > 0 && currentPageUsed + h > PAGE_CONTENT_HEIGHT) {\n result.push([]);\n currentPageUsed = 0;\n }\n\n result[result.length - 1].push(child.outerHTML);\n currentPageUsed += h;\n }\n\n // At least one page\n if (result.length === 0) result.push([]);\n\n setPages(result.map(blocks => blocks.join('')));\n }, [html]);\n\n useEffect(() => {\n if (!html || !measureRef.current) return;\n requestAnimationFrame(() => {\n paginate();\n });\n }, [html, paginate]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n className=\"rfp-w-full rfp-h-full rfp-overflow-auto\"\n style={{ background: 'rgba(0, 0, 0, 0.15)' }}\n >\n {/* Hidden measurement div — same width as page content area */}\n <div\n ref={measureRef}\n dangerouslySetInnerHTML={{ __html: html }}\n style={{\n ...contentStyle,\n position: 'absolute',\n visibility: 'hidden',\n width: `${794 - PAGE_PADDING_X * 2}px`,\n pointerEvents: 'none',\n }}\n />\n\n {/* Visible pages */}\n <div\n className=\"rfp-py-6 md:rfp-py-10 rfp-flex rfp-flex-col rfp-items-center\"\n style={{ gap: `${PAGE_GAP}px` }}\n >\n {(pages.length > 0 ? pages : ['']).map((pageHtml, i) => (\n <div\n key={i}\n style={{\n width: '100%',\n maxWidth: '794px',\n minHeight: `${PAGE_HEIGHT}px`,\n background: 'white',\n boxShadow: '0 2px 12px rgba(0, 0, 0, 0.15)',\n flexShrink: 0,\n padding: `${PAGE_PADDING_Y}px ${PAGE_PADDING_X}px`,\n }}\n >\n <div\n dangerouslySetInnerHTML={{ __html: pageHtml }}\n style={contentStyle}\n />\n </div>\n ))}\n </div>\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { FileSpreadsheet } from 'lucide-react';\nimport ExcelJS from 'exceljs';\nimport Spreadsheet from 'x-data-spreadsheet';\nimport 'x-data-spreadsheet/dist/xspreadsheet.css';\nimport { convertWorkbookToSpreadsheetData } from '../../utils/excelDataConverter';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface XlsxRendererProps {\n url: string;\n}\n\nexport const XlsxRenderer: React.FC<XlsxRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const spreadsheetRef = useRef<Spreadsheet | null>(null);\n const sheetDataRef = useRef<Record<string, unknown>[] | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 800, height: 600 };\n const rawWidth = containerRef.current.clientWidth;\n const rawHeight = containerRef.current.clientHeight;\n const width = rawWidth > 100 ? rawWidth : 800;\n const height = rawHeight > 100 ? rawHeight : 600;\n return { width, height };\n }, []);\n\n const mountSpreadsheet = useCallback(() => {\n if (!containerRef.current || !sheetDataRef.current) return;\n\n // 清空容器\n containerRef.current.innerHTML = '';\n spreadsheetRef.current = null;\n\n const { width, height } = calculateDimensions();\n const isMobile = width < 640;\n\n const s = new Spreadsheet(containerRef.current, {\n mode: 'read',\n showToolbar: false,\n showContextmenu: false,\n showGrid: true,\n row: {\n len: 100,\n height: 25,\n },\n col: {\n len: 26,\n width: isMobile ? 80 : 100,\n indexWidth: isMobile ? 40 : 60,\n minWidth: isMobile ? 40 : 60,\n },\n view: {\n height: () => height,\n width: () => width,\n },\n });\n\n s.loadData(sheetDataRef.current as unknown as Record<string, unknown>);\n spreadsheetRef.current = s;\n }, [calculateDimensions]);\n\n // 监听容器尺寸变化\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensionsRef.current = newDimensions;\n\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (sheetDataRef.current) {\n mountSpreadsheet();\n }\n }, 500);\n };\n\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, mountSpreadsheet]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadExcel = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await fetcher(url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(t('xlsx.not_found'));\n } else if (response.status === 403) {\n throw new Error('无权限访问此文件');\n } else {\n throw new Error(`文件加载失败 (${response.status})`);\n }\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error('文件为空');\n }\n\n // 使用 exceljs 解析\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(arrayBuffer);\n\n // 转换为 x-data-spreadsheet 数据格式\n const sheetData = convertWorkbookToSpreadsheetData(workbook);\n\n if (!isMounted) return;\n\n sheetDataRef.current = sheetData as unknown as Record<string, unknown>[];\n\n // 挂载 x-data-spreadsheet\n mountSpreadsheet();\n\n setLoading(false);\n } catch (err) {\n if (isMounted) {\n console.error('Excel 解析错误:', err);\n let errorMsg = t('xlsx.parse_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n }\n setError(errorMsg);\n setLoading(false);\n }\n }\n };\n\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n loadExcel();\n });\n }, 100);\n\n return () => {\n isMounted = false;\n clearTimeout(timer);\n sheetDataRef.current = null;\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n spreadsheetRef.current = null;\n };\n }, [url, mountSpreadsheet]);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {/* 加载状态 */}\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('xlsx.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 错误状态 */}\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <div className=\"rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-green-500 rfp-via-emerald-500 rfp-to-teal-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl\">\n <FileSpreadsheet className=\"rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary\" />\n </div>\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium\">{t('xlsx.load_failed')}</p>\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6\">\n {error}\n </p>\n <a\n href={url}\n download\n className=\"rfp-inline-flex rfp-items-center rfp-gap-2 rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-bg-gradient-to-r rfp-from-purple-500 rfp-to-pink-500 rfp-text-fg-primary rfp-text-sm md:rfp-text-base rfp-rounded-lg md:rfp-rounded-xl hover:rfp-scale-105 rfp-transition-all rfp-shadow-lg\"\n >\n <svg className=\"rfp-w-4 rfp-h-4 md:rfp-w-5 md:rfp-h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n {t('common.download')}\n </a>\n <p className=\"rfp-text-xs rfp-text-fg-muted rfp-mt-3 md:rfp-mt-4\">\n 提示:可以使用 Microsoft Excel 或 WPS 打开\n </p>\n </div>\n </div>\n )}\n\n {/* Spreadsheet 容器 */}\n {!error && (\n <div\n ref={containerRef}\n className=\"xlsx-spreadsheet-container rfp-w-full rfp-h-full\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { Presentation } from 'lucide-react';\nimport { init } from 'pptx-preview';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface PptxRendererProps {\n url: string;\n /** 是否平铺展示所有页面,默认 true */\n tiled?: boolean;\n}\n\nexport const PptxRenderer: React.FC<PptxRendererProps> = ({ url, tiled = true }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [slideCount, setSlideCount] = useState(0);\n const containerRef = useRef<HTMLDivElement>(null);\n const previewerRef = useRef<ReturnType<typeof init> | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const arrayBufferRef = useRef<ArrayBuffer | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n // 计算容器尺寸,带回退逻辑\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 960, height: 540 };\n const rawWidth = containerRef.current.clientWidth;\n const parentWidth = containerRef.current.parentElement?.clientWidth || 0;\n // 如果容器宽度太小,回退到父容器宽度或默认最小值\n const containerWidth = rawWidth > 100 ? rawWidth : (parentWidth > 100 ? parentWidth : 300);\n // 16:9 比例\n const height = Math.floor(containerWidth * 9 / 16);\n return { width: containerWidth, height };\n }, []);\n\n // 重新初始化预览器\n const reinitializePreviewer = useCallback(async () => {\n if (!containerRef.current || !arrayBufferRef.current || slideCount === 0) return;\n\n try {\n // 销毁旧的预览器\n if (previewerRef.current) {\n try {\n previewerRef.current.destroy();\n } catch {\n // 忽略销毁错误\n }\n }\n\n // 清空容器\n containerRef.current.innerHTML = '';\n\n // 获取当前容器尺寸\n const currentDimensions = calculateDimensions();\n\n // 初始化新的预览器,平铺模式下高度按页数计算\n const previewer = init(containerRef.current, {\n width: currentDimensions.width,\n height: tiled ? currentDimensions.height * slideCount : currentDimensions.height,\n mode: tiled ? 'list' : 'slide',\n });\n previewerRef.current = previewer;\n\n // 重新预览\n await previewer.preview(arrayBufferRef.current);\n } catch {\n // 重新初始化失败,静默处理\n }\n }, [calculateDimensions, tiled, slideCount]);\n\n // 监听容器尺寸变化\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n // 跳过初始渲染时的尺寸检查\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n\n // 检查尺寸是否真正变化(至少变化10px才触发)\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) {\n return;\n }\n\n // 更新最后的尺寸\n lastDimensionsRef.current = newDimensions;\n\n // 清除之前的定时器\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // 防抖:800ms 后重新初始化预览器\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (previewerRef.current && arrayBufferRef.current) {\n reinitializePreviewer();\n }\n }, 800);\n };\n\n // 创建 ResizeObserver\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n // 开始观察容器\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, reinitializePreviewer]);\n\n useEffect(() => {\n let isMounted = true;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const loadPptx = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n // 设置30秒超时\n timeoutId = setTimeout(() => {\n if (isMounted) {\n setError(t('pptx.timeout'));\n setLoading(false);\n }\n }, 30000);\n\n try {\n // 获取文件,处理 CORS 和重定向\n const response = await fetcher(url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(t('pptx.not_found'));\n } else if (response.status === 403) {\n throw new Error('无权限访问此文件');\n } else if (response.status >= 500) {\n throw new Error('服务器错误,请稍后重试');\n } else {\n throw new Error(`文件加载失败 (${response.status})`);\n }\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n // 验证文件大小\n if (arrayBuffer.byteLength === 0) {\n throw new Error('文件为空');\n }\n\n arrayBufferRef.current = arrayBuffer;\n\n if (!isMounted) return;\n\n // 步骤 1: 创建隐藏容器,预处理获取 slideCount\n const hiddenContainer = document.createElement('div');\n hiddenContainer.style.cssText = 'position:absolute;left:-9999px;top:-9999px;visibility:hidden';\n document.body.appendChild(hiddenContainer);\n\n try {\n // 在隐藏容器中初始化临时预览器获取页数\n const tempPreviewer = init(hiddenContainer, {\n width: 100,\n height: 100,\n mode: 'slide',\n });\n\n try {\n await tempPreviewer.preview(arrayBuffer);\n } catch {\n throw new Error(t('pptx.invalid_format'));\n }\n\n const count = tempPreviewer.slideCount;\n\n if (!count || count === 0) {\n throw new Error(t('pptx.no_pages'));\n }\n\n // 销毁临时预览器\n tempPreviewer.destroy();\n\n if (!isMounted) return;\n\n // 保存 slideCount\n setSlideCount(count);\n\n // 步骤 2: 清空真实容器并初始化\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n\n const currentDimensions = calculateDimensions();\n\n // 步骤 3: 初始化真实预览器,平铺模式下使用正确的总高度\n const previewer = init(containerRef.current, {\n width: currentDimensions.width,\n height: tiled ? currentDimensions.height * count : currentDimensions.height,\n mode: tiled ? 'list' : 'slide',\n });\n previewerRef.current = previewer;\n\n // 步骤 4: 预览 PPTX\n await previewer.preview(arrayBuffer);\n\n // 清除超时定时器\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n if (isMounted) {\n setLoading(false);\n }\n } finally {\n // 移除隐藏容器\n if (document.body.contains(hiddenContainer)) {\n document.body.removeChild(hiddenContainer);\n }\n }\n } catch (err) {\n // 清除超时定时器\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n if (isMounted) {\n let errorMsg = t('pptx.parse_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n } else if (typeof err === 'string') {\n errorMsg = err;\n }\n setError(errorMsg);\n setLoading(false);\n }\n }\n };\n\n // 延迟执行,使用 requestAnimationFrame 确保 DOM 已准备好\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n loadPptx();\n });\n });\n }, 150);\n\n // 清理函数\n return () => {\n isMounted = false;\n clearTimeout(timer);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n arrayBufferRef.current = null;\n setSlideCount(0);\n if (previewerRef.current) {\n try {\n previewerRef.current.destroy();\n } catch {\n // 忽略销毁错误\n }\n }\n previewerRef.current = null;\n };\n }, [url, calculateDimensions, tiled]);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {/* 加载状态 - 绝对定位覆盖 */}\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('pptx.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 错误状态 - 绝对定位覆盖 */}\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <div className=\"rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-orange-500 rfp-via-red-500 rfp-to-pink-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl\">\n <Presentation className=\"rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary\" />\n </div>\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium\">{t('pptx.load_failed')}</p>\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6\">\n {error}\n </p>\n <a\n href={url}\n download\n className=\"rfp-inline-flex rfp-items-center rfp-gap-2 rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-bg-gradient-to-r rfp-from-purple-500 rfp-to-pink-500 rfp-text-fg-primary rfp-text-sm md:rfp-text-base rfp-rounded-lg md:rfp-rounded-xl hover:rfp-scale-105 rfp-transition-all rfp-shadow-lg\"\n >\n <svg className=\"rfp-w-4 rfp-h-4 md:rfp-w-5 md:rfp-h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n {t('common.download')}\n </a>\n <p className=\"rfp-text-xs rfp-text-fg-muted rfp-mt-3 md:rfp-mt-4\">\n 提示:可以使用 Microsoft PowerPoint 或 WPS 打开\n </p>\n </div>\n </div>\n )}\n\n {/* PPT 容器 - 仅在非错误状态下渲染 */}\n {!error && (\n <div\n ref={containerRef}\n className=\"pptx-wrapper rfp-w-full rfp-max-w-full md:rfp-max-w-6xl\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n};\n","import { useState, useEffect } from 'react';\nimport MsgReader from '@kenjiuno/msgreader';\nimport type { FieldsData } from '@kenjiuno/msgreader';\nimport { User, Users, Paperclip, Calendar, Mail, Tag, Clock, Hash } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface MsgRendererProps {\n url: string;\n}\n\nfunction formatRecipients(recipients: FieldsData[] | undefined, type: 'to' | 'cc' | 'bcc'): string {\n if (!recipients) return '';\n return recipients\n .filter((r) => r.recipType === type)\n .map((r) => {\n const name = r.name || '';\n const email = r.smtpAddress || r.email || '';\n if (name && email && name !== email) {\n return `${name} <${email}>`;\n }\n return name || email;\n })\n .filter(Boolean)\n .join('; ');\n}\n\nfunction formatDate(dateStr: string | undefined): string {\n if (!dateStr) return '';\n try {\n const date = new Date(dateStr);\n if (isNaN(date.getTime())) return dateStr;\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\nfunction decodeHtmlBody(fields: FieldsData, emptyBodyText: string): string {\n // 优先使用 bodyHtml (string 类型)\n if (fields.bodyHtml) {\n return fields.bodyHtml;\n }\n // 其次尝试 html (Uint8Array 类型)\n if (fields.html) {\n try {\n const decoder = new TextDecoder('utf-8');\n return decoder.decode(fields.html);\n } catch {\n // fallback\n }\n }\n // 最后使用纯文本,转换为简单 HTML\n if (fields.body) {\n return `<pre style=\"white-space: pre-wrap; word-wrap: break-word; font-family: system-ui, sans-serif;\">${fields.body.replace(/&/g, '&').replace(/\\x3c/g, '<').replace(/>/g, '>')\n }</pre>`;\n }\n return `<p style=\"color: #999;\">${emptyBodyText}</p>`;\n}\n\nfunction formatMessageClass(messageClass: string | undefined): string {\n if (!messageClass) return '';\n const classMap: Record<string, string> = {\n 'IPM.Note': 'Email',\n 'IPM.Note.SMIME': 'Encrypted Email',\n 'IPM.Note.SMIME.MultipartSigned': 'Signed Email',\n 'IPM.Appointment': 'Appointment',\n 'IPM.Schedule.Meeting.Request': 'Meeting Request',\n 'IPM.Schedule.Meeting.Canceled': 'Meeting Cancellation',\n 'IPM.Contact': 'Contact',\n 'IPM.Task': 'Task',\n 'IPM.StickyNote': 'Sticky Note',\n };\n return classMap[messageClass] || messageClass;\n}\n\nconst labelStyle: React.CSSProperties = {\n flexShrink: 0,\n color: '#6b7280',\n fontWeight: 500,\n marginRight: '8px',\n whiteSpace: 'nowrap',\n};\n\nconst rowStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n padding: '6px 0',\n};\n\nconst iconWrapStyle: React.CSSProperties = {\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n height: '1.4em',\n};\n\nconst iconStyle: React.CSSProperties = {\n flexShrink: 0,\n color: '#9ca3af',\n};\n\nconst valueStyle: React.CSSProperties = {\n color: '#111827',\n wordBreak: 'break-word' as const,\n flex: 1,\n};\n\nexport const MsgRenderer: React.FC<MsgRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [fields, setFields] = useState<FieldsData | null>(null);\n\n useEffect(() => {\n const loadMsg = async () => {\n setLoading(true);\n setError(null);\n setFields(null);\n\n try {\n const response = await fetcher(url);\n if (!response.ok) {\n throw new Error('文件加载失败');\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const msgReader = new MsgReader(arrayBuffer);\n const fileData = msgReader.getFileData();\n setFields(fileData);\n } catch (err) {\n console.error('MSG 解析错误:', err);\n setError(t('msg.parse_failed'));\n } finally {\n setLoading(false);\n }\n };\n\n loadMsg();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !fields) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('msg.parse_failed_short')}</p>\n </div>\n </div>\n );\n }\n\n const toStr = formatRecipients(fields.recipients, 'to');\n const ccStr = formatRecipients(fields.recipients, 'cc');\n const bccStr = formatRecipients(fields.recipients, 'bcc');\n const senderName = fields.senderName || '';\n const senderEmail = fields.senderSmtpAddress || fields.senderEmail || '';\n const sender = senderName && senderEmail && senderName !== senderEmail\n ? `${senderName} <${senderEmail}>`\n : senderName || senderEmail;\n const sentDate = formatDate(fields.clientSubmitTime);\n const receivedDate = formatDate(fields.messageDeliveryTime);\n const createdDate = formatDate(fields.creationTime);\n const lastModified = formatDate(fields.lastModificationTime);\n const subject = fields.subject || '(无主题)';\n const attachments = (fields.attachments || []).filter((a) => !a.attachmentHidden);\n const bodyHtml = decodeHtmlBody(fields, t('msg.empty_body'));\n const messageClass = formatMessageClass(fields.messageClass);\n const messageId = fields.messageId || '';\n const fieldsAny = fields as FieldsData & Record<string, unknown>;\n const importance = typeof fieldsAny.importance === 'number' ? fieldsAny.importance : undefined;\n const importanceLabel = importance === 2 ? 'High' : importance === 0 ? 'Low' : '';\n const sensitivity = typeof fieldsAny.sensitivity === 'number' ? fieldsAny.sensitivity : undefined;\n const sensitivityLabels: Record<number, string> = {\n 0: 'Normal',\n 1: 'Personal',\n 2: 'Private',\n 3: 'Confidential',\n };\n const sensitivityLabel = sensitivity !== undefined && sensitivity !== 0 ? sensitivityLabels[sensitivity] || '' : '';\n\n return (\n <div\n className=\"rfp-w-full rfp-h-full rfp-overflow-auto\"\n style={{ background: 'white' }}\n >\n <div\n style={{\n width: '100%',\n background: 'white',\n minHeight: '100%',\n }}\n >\n {/* 邮件头部 */}\n <div style={{ borderBottom: '1px solid #e5e7eb', padding: 'clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)', background: '#f9fafb' }}>\n {/* 主题 */}\n <h2 style={{ margin: '0 0 16px 0', fontSize: 'clamp(16px, 2.5vw, 20px)', fontWeight: 600, color: '#111827', lineHeight: 1.4 }}>\n {subject}\n </h2>\n\n {/* 元信息 */}\n <div style={{ display: 'flex', flexDirection: 'column', fontSize: 'clamp(12px, 1.8vw, 14px)', color: '#4b5563' }}>\n {sender && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><User size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>From</span>\n <span style={valueStyle}>{sender}</span>\n </div>\n </div>\n )}\n\n {toStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>To</span>\n <span style={valueStyle}>{toStr}</span>\n </div>\n </div>\n )}\n\n {ccStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Cc</span>\n <span style={valueStyle}>{ccStr}</span>\n </div>\n </div>\n )}\n\n {bccStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Bcc</span>\n <span style={valueStyle}>{bccStr}</span>\n </div>\n </div>\n )}\n\n {sentDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Calendar size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Sent</span>\n <span style={valueStyle}>{sentDate}</span>\n </div>\n </div>\n )}\n\n {receivedDate && receivedDate !== sentDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Clock size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Received</span>\n <span style={valueStyle}>{receivedDate}</span>\n </div>\n </div>\n )}\n\n {!sentDate && !receivedDate && createdDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Calendar size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Date</span>\n <span style={valueStyle}>{createdDate}</span>\n </div>\n </div>\n )}\n\n {importanceLabel && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Tag size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Importance</span>\n <span style={{\n ...valueStyle,\n color: importance === 2 ? '#dc2626' : '#2563eb',\n fontWeight: 500,\n }}>\n {importanceLabel}\n </span>\n </div>\n </div>\n )}\n\n {sensitivityLabel && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Tag size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Sensitivity</span>\n <span style={valueStyle}>{sensitivityLabel}</span>\n </div>\n </div>\n )}\n\n {messageClass && messageClass !== 'Email' && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Mail size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Type</span>\n <span style={valueStyle}>{messageClass}</span>\n </div>\n </div>\n )}\n\n {attachments.length > 0 && (\n <div style={{ ...rowStyle, borderTop: '1px solid #e5e7eb', marginTop: '4px', paddingTop: '10px' }}>\n <span style={iconWrapStyle}><Paperclip size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Attachments</span>\n <div style={{ ...valueStyle, display: 'flex', flexWrap: 'wrap', gap: '6px' }}>\n {attachments.map((a, i) => {\n const name = a.fileName || a.name || '未知文件';\n const size = a.contentLength;\n const sizeStr = size\n ? size > 1048576\n ? `${(size / 1048576).toFixed(1)} MB`\n : size > 1024\n ? `${(size / 1024).toFixed(0)} KB`\n : `${size} B`\n : '';\n return (\n <span\n key={i}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n padding: '2px 8px',\n background: '#f3f4f6',\n borderRadius: '4px',\n fontSize: '13px',\n color: '#374151',\n border: '1px solid #e5e7eb',\n }}\n >\n {name}\n {sizeStr && (\n <span style={{ color: '#9ca3af', fontSize: '12px' }}>({sizeStr})</span>\n )}\n </span>\n );\n })}\n </div>\n </div>\n </div>\n )}\n\n {messageId && (\n <div style={{ ...rowStyle, borderTop: attachments.length > 0 ? 'none' : '1px solid #e5e7eb', marginTop: '4px', paddingTop: '10px' }}>\n <span style={iconWrapStyle}><Hash size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Message-ID</span>\n <span style={{ ...valueStyle, fontSize: '12px', color: '#9ca3af', fontFamily: 'monospace' }}>{messageId}</span>\n </div>\n </div>\n )}\n\n {lastModified && lastModified !== sentDate && lastModified !== receivedDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Clock size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Modified</span>\n <span style={{ ...valueStyle, fontSize: '12px', color: '#9ca3af' }}>{lastModified}</span>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* 邮件正文 */}\n <div\n style={{\n padding: 'clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n lineHeight: '1.6',\n color: '#333',\n overflowX: 'auto',\n }}\n dangerouslySetInnerHTML={{ __html: bodyHtml }}\n />\n </div>\n </div>\n );\n};\n","import { useEffect, useRef, useState, useCallback, useImperativeHandle, forwardRef } from 'react';\nimport ePub from '@likecoin/epub-ts';\nimport { X } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\n// 全局注入 epubjs 容器样式(只注入一次)\nif (typeof document !== 'undefined' && !document.getElementById('rfp-epub-styles')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'rfp-epub-styles';\n styleEl.textContent = `\n .epub-container { overflow-y: auto !important; scrollbar-width: thin; }\n .epub-container::-webkit-scrollbar { width: 8px; }\n .epub-container::-webkit-scrollbar-track { background: transparent; }\n .epub-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }\n .epub-container::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }\n .epub-view > iframe { background: white; }\n `;\n document.head.appendChild(styleEl);\n}\n\nexport interface TocItem {\n label: string;\n href: string;\n subitems?: TocItem[];\n}\n\nexport interface EpubRendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface EpubRendererProps {\n url: string;\n onChapterChange?: (current: number, total: number) => void;\n onFullWidthChange?: (isFullWidth: boolean) => void;\n}\n\ninterface RenditionLike {\n display: (target?: string) => Promise<unknown>;\n next: () => Promise<unknown>;\n prev: () => Promise<unknown>;\n on: (event: string, cb: (...args: unknown[]) => void) => void;\n resize: (width: number, height: number) => void;\n currentLocation: () => unknown;\n destroy?: () => void;\n themes: {\n register: (name: string, styles: Record<string, unknown>) => void;\n select: (name: string) => void;\n };\n}\n\ninterface BookLike {\n ready: Promise<unknown>;\n loaded: { navigation: Promise<unknown> };\n locations: {\n generate: (chars: number) => Promise<string[]>;\n length: () => number;\n locationFromCfi: (cfi: string) => number;\n };\n renderTo: (el: HTMLElement, opts: Record<string, unknown>) => RenditionLike;\n destroy: () => void;\n}\n\nconst A4_WIDTH = 794;\n\nexport const EpubRenderer = forwardRef<EpubRendererHandle, EpubRendererProps>(\n ({ url, onChapterChange, onFullWidthChange }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const viewerRef = useRef<HTMLDivElement>(null);\n const bookRef = useRef<BookLike | null>(null);\n const renditionRef = useRef<RenditionLike | null>(null);\n const onChapterChangeRef = useRef(onChapterChange);\n const onFullWidthChangeRef = useRef(onFullWidthChange);\n onChapterChangeRef.current = onChapterChange;\n onFullWidthChangeRef.current = onFullWidthChange;\n\n const totalLocationsRef = useRef(0);\n const lastCfiRef = useRef<string | null>(null);\n const isFullWidthRef = useRef(false);\n\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isFullWidth, setIsFullWidth] = useState(false);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const tocRef = useRef<TocItem[]>([]);\n tocRef.current = toc;\n\n isFullWidthRef.current = isFullWidth;\n\n const handlePrev = useCallback(() => {\n renditionRef.current?.prev();\n }, []);\n\n const handleNext = useCallback(() => {\n renditionRef.current?.next();\n }, []);\n\n // 滚动监听:接近底部时强制触发 check 加载后续 section\n const scrollContainerRef = useRef<Element | null>(null);\n const scrollRafRef = useRef(0);\n\n const onScrollRef = useRef((_e?: Event) => {\n const container = scrollContainerRef.current;\n if (!container) return;\n const el = container as HTMLElement;\n const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 200;\n if (nearBottom) {\n try {\n const mgr = (renditionRef.current as unknown as { manager?: { check?: (t?: number, e?: number) => Promise<unknown> } })?.manager;\n mgr?.check?.(500, 500);\n } catch { /* ignore */ }\n }\n });\n\n const reattachScrollListener = useCallback(() => {\n // 清理旧监听\n if (scrollContainerRef.current) {\n scrollContainerRef.current.removeEventListener('scroll', onScrollRef.current);\n scrollContainerRef.current = null;\n }\n cancelAnimationFrame(scrollRafRef.current);\n\n const tryAttach = () => {\n const container = viewerRef.current?.querySelector('.epub-container') ?? null;\n if (!container) {\n scrollRafRef.current = requestAnimationFrame(tryAttach);\n return;\n }\n scrollContainerRef.current = container;\n container.addEventListener('scroll', onScrollRef.current, { passive: true });\n };\n scrollRafRef.current = requestAnimationFrame(tryAttach);\n }, []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n onFullWidthChangeRef.current?.(newVal);\n // 等 CSS transition 完成后再 resize 并恢复位置\n setTimeout(() => {\n const viewer = viewerRef.current;\n const rendition = renditionRef.current;\n if (!viewer || !rendition) return;\n rendition.resize(viewer.offsetWidth, viewer.offsetHeight);\n // 重排后恢复阅读位置\n if (lastCfiRef.current) {\n rendition.display(lastCfiRef.current);\n }\n // resize/display 可能重建 .epub-container,需要重新绑定滚动监听\n reattachScrollListener();\n }, 350);\n }, [reattachScrollListener]);\n\n const toggleToc = useCallback(() => {\n setShowToc(prev => !prev);\n }, []);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n renditionRef.current?.display(href);\n setShowToc(false);\n }, []);\n\n useImperativeHandle(ref, () => ({\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n viewer.innerHTML = '';\n lastCfiRef.current = null;\n totalLocationsRef.current = 0;\n\n let cancelled = false;\n // StrictMode 下 effect 会立即 mount→unmount→mount\n // 用 microtask 延迟初始化,让第一次的 cleanup 先执行,避免 epubjs 内部状态被污染\n const loadTimer = window.setTimeout(() => {\n if (cancelled) return;\n load();\n }, 0);\n\n const load = async () => {\n try {\n let bookInput: string | ArrayBuffer = url;\n if (url.startsWith('blob:')) {\n const resp = await fetcher(url);\n bookInput = await resp.arrayBuffer();\n }\n\n const book = ePub(bookInput) as unknown as BookLike;\n bookRef.current = book;\n\n const rendition = book.renderTo(viewer, {\n manager: 'continuous',\n flow: 'scrolled',\n width: '100%',\n height: '100%',\n });\n renditionRef.current = rendition;\n\n rendition.themes.register('default', {\n body: {\n background: '#ffffff !important',\n color: '#1a1a1a !important',\n 'font-family': '\"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important',\n 'font-size': '16px !important',\n 'line-height': '2 !important',\n padding: '40px 60px !important',\n 'max-width': '100% !important',\n 'box-sizing': 'border-box !important',\n 'word-break': 'break-word !important',\n 'overflow-wrap': 'break-word !important',\n },\n p: { 'text-indent': '2em !important', margin: '0.8em 0 !important' },\n h1: { 'text-align': 'center !important', margin: '1.5em 0 1em !important' },\n h2: { margin: '1.2em 0 0.8em !important' },\n h3: { margin: '1em 0 0.6em !important' },\n img: { 'max-width': '100% !important', height: 'auto !important' },\n a: { color: '#2563eb !important', 'text-decoration': 'none !important' },\n });\n rendition.themes.select('default');\n\n await book.ready;\n\n // 异步生成 locations 索引(用于实时页数)\n book.locations.generate(1024).then(() => {\n if (cancelled) return;\n totalLocationsRef.current = book.locations.length();\n // 触发一次更新让父组件拿到 total\n const loc = renditionRef.current?.currentLocation() as { start?: { location?: number; cfi?: string } } | undefined;\n const cur = loc?.start?.location ?? 0;\n onChapterChangeRef.current?.(cur + 1, totalLocationsRef.current);\n }).catch(() => { /* ignore */ });\n\n // 获取目录\n const nav = await book.loaded.navigation as { toc?: TocItem[] };\n if (!cancelled && Array.isArray(nav?.toc)) {\n setToc(nav.toc);\n }\n\n await rendition.display();\n\n if (cancelled) return;\n\n setLoading(false);\n onChapterChangeRef.current?.(1, totalLocationsRef.current || 1);\n\n rendition.on('relocated', (location: unknown) => {\n const loc = location as { start?: { cfi?: string; location?: number; href?: string } };\n if (loc?.start?.cfi) {\n lastCfiRef.current = loc.start.cfi;\n }\n if (loc?.start?.href) {\n // 根据 spine href 查找匹配的 TOC 项\n const spineHref = loc.start.href;\n const matches: string[] = [];\n const collect = (items: TocItem[]) => {\n for (const item of items) {\n const base = item.href.split('#')[0];\n if (base && (spineHref === base || spineHref.endsWith('/' + base) || spineHref.endsWith(base))) {\n matches.push(item.href);\n }\n if (item.subitems) collect(item.subitems);\n }\n };\n collect(tocRef.current);\n if (matches.length === 1) {\n // 唯一匹配,直接设置\n setActiveTocHref(matches[0]);\n }\n // 多个匹配(同一文件不同 anchor)时保持当前选中(由点击设置)\n }\n const cur = loc?.start?.location;\n const total = totalLocationsRef.current;\n if (typeof cur === 'number' && total > 0) {\n onChapterChangeRef.current?.(cur + 1, total);\n }\n });\n\n } catch (err) {\n console.error('EPUB 加载错误:', err);\n if (!cancelled) {\n setError(t('epub.load_failed'));\n setLoading(false);\n }\n }\n };\n\n return () => {\n cancelled = true;\n window.clearTimeout(loadTimer);\n try { renditionRef.current?.destroy?.(); } catch { /* ignore */ }\n try { bookRef.current?.destroy(); } catch { /* ignore */ }\n renditionRef.current = null;\n bookRef.current = null;\n };\n }, [url]);\n\n useEffect(() => {\n const onResize = () => {\n const viewer = viewerRef.current;\n if (!viewer || !renditionRef.current) return;\n renditionRef.current.resize(viewer.offsetWidth, viewer.offsetHeight);\n };\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, []);\n\n useEffect(() => {\n reattachScrollListener();\n return () => {\n cancelAnimationFrame(scrollRafRef.current);\n scrollContainerRef.current?.removeEventListener('scroll', onScrollRef.current);\n };\n }, [url, reattachScrollListener]);\n\n const isActive = useCallback((href: string) => {\n return href === activeTocHref;\n }, [activeTocHref]);\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ marginLeft: depth > 0 ? 16 : 0 }}>\n {items.map((item, i) => {\n const active = isActive(item.href);\n return (\n <li key={`${item.href}-${i}`}>\n <button\n onClick={() => handleTocClick(item.href)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${active\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label.trim()}\n </button>\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n );\n })}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-[#f5f5f0] rfp-overflow-hidden\">\n {error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 - 滑入动画 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{\n opacity: showToc ? 1 : 0,\n pointerEvents: showToc ? 'auto' : 'none',\n }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={viewerRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n overflow: 'hidden',\n }}\n />\n )}\n </div>\n );\n }\n);\n","import {\n useEffect,\n useRef,\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n} from 'react';\nimport { X } from 'lucide-react';\nimport 'foliate-js/view.js';\nimport type { FoliateView, TocItem } from 'foliate-js/view.js';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\nconst READER_CSS = `\n @namespace epub \"http://www.idpf.org/2007/ops\";\n html { color-scheme: light; }\n body {\n background: #ffffff !important;\n color: #1a1a1a !important;\n font-family: \"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important;\n font-size: 16px !important;\n line-height: 2 !important;\n max-width: 100% !important;\n box-sizing: border-box !important;\n word-break: break-word !important;\n overflow-wrap: break-word !important;\n }\n p, li, blockquote, dd { line-height: 2; text-align: justify; }\n p { text-indent: 2em; margin: 0.8em 0; }\n h1 { text-align: center; margin: 1.5em 0 1em; }\n h2 { margin: 1.2em 0 0.8em; }\n h3 { margin: 1em 0 0.6em; }\n img { max-width: 100% !important; height: auto !important; }\n a { color: #2563eb; text-decoration: none; }\n pre { white-space: pre-wrap !important; }\n`;\n\nconst A4_WIDTH = 794;\n\nexport interface MobiRendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface MobiRendererProps {\n url: string;\n onChapterChange?: (current: number, total: number) => void;\n onFullWidthChange?: (isFullWidth: boolean) => void;\n}\n\nexport const MobiRenderer = forwardRef<MobiRendererHandle, MobiRendererProps>(\n ({ url, onChapterChange, onFullWidthChange }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const hostRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<FoliateView | null>(null);\n const onChapterChangeRef = useRef(onChapterChange);\n const onFullWidthChangeRef = useRef(onFullWidthChange);\n onChapterChangeRef.current = onChapterChange;\n onFullWidthChangeRef.current = onFullWidthChange;\n\n // 模拟 epub.js 的 locations 显示\n const totalLocationsRef = useRef(1);\n\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const [isFullWidth, setIsFullWidth] = useState(false);\n const isFullWidthRef = useRef(false);\n isFullWidthRef.current = isFullWidth;\n\n const reportProgress = useCallback((current: number, total: number) => {\n if (total > 0) totalLocationsRef.current = total;\n onChapterChangeRef.current?.(Math.max(1, current + 1), totalLocationsRef.current);\n }, []);\n\n const handlePrev = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.prev().catch(() => {});\n }, []);\n\n const handleNext = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.next().catch(() => {});\n }, []);\n\n const toggleToc = useCallback(() => setShowToc((prev) => !prev), []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n onFullWidthChangeRef.current?.(newVal);\n // 宽度改变后 paginator 需要重新分页\n const view = viewRef.current;\n if (!view) return;\n const renderer = (view as unknown as { renderer?: HTMLElement }).renderer;\n if (renderer) {\n renderer.setAttribute('max-inline-size', newVal ? '9999' : '720');\n }\n }, []);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n setShowToc(false);\n viewRef.current?.goTo(href).catch(() => {});\n }, []);\n\n useImperativeHandle(ref, () => ({\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n setActiveTocHref('');\n host.replaceChildren();\n\n let cancelled = false;\n let view: FoliateView | null = null;\n\n const load = async () => {\n try {\n if (cancelled) return;\n\n view = document.createElement('foliate-view') as FoliateView;\n host.appendChild(view);\n viewRef.current = view;\n\n // 先注册事件\n view.addEventListener('relocate', (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (!detail) return;\n // SectionProgress 返回的 location 对象: { current, next, total }\n const loc = detail.location as { current?: number; total?: number } | undefined;\n if (loc && typeof loc.current === 'number' && typeof loc.total === 'number') {\n reportProgress(loc.current, loc.total);\n } else {\n // fallback:用 section 级别估算\n const sections = viewRef.current?.book?.sections ?? [];\n const idx = detail.index ?? 0;\n const frac = detail.fraction ?? 0;\n const total = Math.max(sections.length, 1);\n const current = Math.round((idx + frac) / total * total);\n reportProgress(current, total);\n }\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) {\n setActiveTocHref(tocItem.href);\n }\n });\n\n const res = await fetcher(url);\n if (!res.ok) throw new Error(`请求失败: ${res.status}`);\n const blob = await res.blob();\n let name = 'book.mobi';\n try {\n const u = new URL(url, window.location.href);\n const base = u.pathname.split('/').pop();\n if (base) name = decodeURIComponent(base);\n } catch { /* blob: URL */ }\n const file = new File([blob], name);\n\n await view.open(file);\n if (cancelled) { view.book?.destroy?.(); return; }\n\n // 配置 paginator:paginated 模式(默认),带动画\n const renderer = (view as unknown as { renderer: HTMLElement & {\n setStyles?: (css: string) => void;\n next?: () => Promise<void>;\n } }).renderer;\n\n if (renderer) {\n // flow=\"paginated\" 是默认值,不需要显式设置\n renderer.setAttribute('animated', '');\n renderer.setAttribute('max-inline-size', '720');\n renderer.setAttribute('margin', '48');\n renderer.setAttribute('gap', '5%');\n renderer.setStyles?.(READER_CSS);\n // 必须调 next() 渲染首页\n await renderer.next?.();\n }\n\n setToc(view.book?.toc ?? []);\n setLoading(false);\n reportProgress(0, view.book?.sections.length ?? 1);\n } catch (err) {\n console.error('MOBI/AZW3 加载错误:', err);\n if (!cancelled) {\n setError(t('mobi.load_failed'));\n setLoading(false);\n }\n }\n };\n\n load();\n\n return () => {\n cancelled = true;\n try { viewRef.current?.book?.destroy?.(); } catch { /* ignore */ }\n viewRef.current = null;\n host.replaceChildren();\n };\n }, [url, reportProgress]);\n\n const isActive = useCallback(\n (href: string | undefined) => !!href && href === activeTocHref,\n [activeTocHref]\n );\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ listStyle: 'none', padding: 0, margin: depth > 0 ? '0 0 0 16px' : 0 }}>\n {items.map((item, i) => (\n <li key={`${item.href ?? item.label}-${i}`}>\n {item.href ? (\n <button\n onClick={() => handleTocClick(item.href!)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${\n isActive(item.href)\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label?.trim()}\n </button>\n ) : (\n <div className=\"rfp-w-full rfp-py-2 rfp-px-3 rfp-text-sm rfp-text-fg-tertiary rfp-truncate\">\n {item.label?.trim()}\n </div>\n )}\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-[#f5f5f0] rfp-overflow-hidden\">\n {error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-secondary rfp-text-center rfp-p-6\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{ opacity: showToc ? 1 : 0, pointerEvents: showToc ? 'auto' : 'none' }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={hostRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n }}\n />\n )}\n </div>\n );\n }\n);\n\nMobiRenderer.displayName = 'MobiRenderer';\n","import { useRef, useEffect, useState } from 'react';\nimport videojs from 'video.js';\nimport 'video.js/dist/video-js.css';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ntype VideoJsPlayer = ReturnType<typeof videojs>;\n\ninterface VideoRendererProps {\n url: string;\n}\n\n// 根据 URL 获取视频 MIME 类型\nconst getVideoType = (url: string): string => {\n const ext = url.split('.').pop()?.toLowerCase().split('?')[0] || '';\n const typeMap: Record<string, string> = {\n mp4: 'video/mp4',\n webm: 'video/webm',\n ogg: 'video/ogg',\n ogv: 'video/ogg',\n mov: 'video/quicktime', // MOV 使用 QuickTime MIME 类型\n avi: 'video/x-msvideo',\n mkv: 'video/x-matroska',\n m4v: 'video/mp4',\n '3gp': 'video/3gpp',\n flv: 'video/x-flv',\n };\n return typeMap[ext] || 'video/mp4';\n};\n\nexport const VideoRenderer: React.FC<VideoRendererProps> = ({ url }) => {\n const t = useTranslator();\n const [error, setError] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const videoRef = useRef<HTMLDivElement>(null);\n const playerRef = useRef<VideoJsPlayer | null>(null);\n\n useEffect(() => {\n // 确保 Video.js 播放器只初始化一次\n if (!playerRef.current && videoRef.current) {\n const videoElement = document.createElement('video-js');\n videoElement.classList.add('vjs-big-play-centered', 'vjs-theme-apple');\n videoRef.current.appendChild(videoElement);\n\n const videoType = getVideoType(url);\n\n // 为 MOV 格式提供多个 MIME 类型作为备用\n const sources = videoType === 'video/quicktime'\n ? [\n { src: url, type: 'video/quicktime' },\n { src: url, type: 'video/mp4' } // 备用方案\n ]\n : [{ src: url, type: videoType }];\n\n const player = videojs(videoElement, {\n controls: true,\n fill: true,\n preload: 'auto',\n controlBar: {\n children: [\n 'playToggle',\n 'volumePanel',\n 'currentTimeDisplay',\n 'timeDivider',\n 'durationDisplay',\n 'progressControl',\n 'remainingTimeDisplay',\n 'fullscreenToggle'\n ],\n volumePanel: {\n inline: false\n }\n },\n html5: {\n vhs: {\n overrideNative: true\n },\n nativeVideoTracks: false,\n nativeAudioTracks: false,\n nativeTextTracks: false\n },\n sources\n });\n\n // 确保视频保持比例\n const videoEl = player.el().querySelector('video');\n if (videoEl) {\n (videoEl as HTMLVideoElement).style.objectFit = 'contain';\n }\n\n // 监听加载完成\n player.on('loadeddata', () => {\n setIsLoading(false);\n });\n\n player.on('error', () => {\n const error = player.error();\n console.error('Video.js error:', error);\n setError(t('video.load_failed_with_error', { error: error?.message || t('common.unknown_error') }));\n setIsLoading(false);\n });\n\n playerRef.current = player;\n }\n }, [url]);\n\n // 清理函数\n useEffect(() => {\n const player = playerRef.current;\n\n return () => {\n if (player && !player.isDisposed()) {\n player.dispose();\n playerRef.current = null;\n }\n };\n }, []);\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-16 rfp-h-16 rfp-mx-auto rfp-mb-4 rfp-rounded-full rfp-bg-red-500/10 rfp-flex rfp-items-center rfp-justify-center\">\n <svg className=\"rfp-w-8 rfp-h-8 rfp-text-red-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\" />\n </svg>\n </div>\n <p className=\"rfp-text-lg rfp-font-medium rfp-text-fg-primary rfp-mb-2\">{t('video.load_failed')}</p>\n <p className=\"rfp-text-sm rfp-text-fg-tertiary\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-full rfp-h-full rfp-relative\">\n {/* 加载状态 */}\n {isLoading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-3 rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-3 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('video.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 视频播放器容器 */}\n <div\n ref={videoRef}\n className=\"rfp-overflow-hidden rfp-w-full rfp-h-full [&_video]:rfp-object-contain\"\n style={{\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05)'\n }}\n />\n </div>\n </div>\n );\n};\n","import { useState, useRef, useEffect, useCallback } from 'react';\n\ninterface UseAudioPlayerOptions {\n url: string;\n skipSeconds?: number;\n}\n\ninterface UseAudioPlayerReturn {\n audioRef: React.RefObject<HTMLAudioElement>;\n isPlaying: boolean;\n isLoading: boolean;\n isLoop: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n isMuted: boolean;\n error: string | null;\n togglePlay: () => void;\n seek: (time: number) => void;\n skip: (seconds: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n toggleLoop: () => void;\n formatTime: (time: number) => string;\n}\n\nexport function useAudioPlayer({\n url,\n}: UseAudioPlayerOptions): UseAudioPlayerReturn {\n const audioRef = useRef<HTMLAudioElement>(null);\n const [isPlaying, setIsPlaying] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [isMuted, setIsMuted] = useState(false);\n const [isLoop, setIsLoop] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n // 重置加载状态\n setIsLoading(true);\n setError(null);\n\n const onTimeUpdate = () => {\n if (!isNaN(audio.currentTime)) {\n setCurrentTime(audio.currentTime);\n }\n };\n\n const onDurationChange = () => {\n if (!isNaN(audio.duration) && isFinite(audio.duration)) {\n setDuration(audio.duration);\n }\n };\n\n const onCanPlay = () => {\n setIsLoading(false);\n onDurationChange();\n };\n\n const onWaiting = () => setIsLoading(true);\n const onPlaying = () => {\n setIsLoading(false);\n setIsPlaying(true);\n };\n\n // 由 audio 事件驱动播放状态,而非手动设置\n const onPlay = () => setIsPlaying(true);\n const onPause = () => setIsPlaying(false);\n const onEnded = () => setIsPlaying(false);\n\n const onError = () => {\n setError('音频加载失败');\n setIsLoading(false);\n };\n\n audio.addEventListener('timeupdate', onTimeUpdate);\n audio.addEventListener('loadedmetadata', onDurationChange);\n audio.addEventListener('durationchange', onDurationChange);\n audio.addEventListener('canplay', onCanPlay);\n audio.addEventListener('waiting', onWaiting);\n audio.addEventListener('playing', onPlaying);\n audio.addEventListener('play', onPlay);\n audio.addEventListener('pause', onPause);\n audio.addEventListener('ended', onEnded);\n audio.addEventListener('error', onError);\n\n // 如果 audio 已经就绪\n if (audio.readyState >= 3) {\n setIsLoading(false);\n onDurationChange();\n } else if (audio.readyState >= 1) {\n onDurationChange();\n }\n\n return () => {\n audio.removeEventListener('timeupdate', onTimeUpdate);\n audio.removeEventListener('loadedmetadata', onDurationChange);\n audio.removeEventListener('durationchange', onDurationChange);\n audio.removeEventListener('canplay', onCanPlay);\n audio.removeEventListener('waiting', onWaiting);\n audio.removeEventListener('playing', onPlaying);\n audio.removeEventListener('play', onPlay);\n audio.removeEventListener('pause', onPause);\n audio.removeEventListener('ended', onEnded);\n audio.removeEventListener('error', onError);\n };\n }, [url]);\n\n const togglePlay = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n if (audio.paused) {\n audio.play().catch(() => {\n // 浏览器自动播放策略拒绝\n });\n } else {\n audio.pause();\n }\n }, []);\n\n const seek = useCallback((time: number) => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.currentTime = time;\n setCurrentTime(time);\n }, []);\n\n const skip = useCallback(\n (seconds: number) => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.currentTime = Math.max(\n 0,\n Math.min(audio.currentTime + seconds, audio.duration || Infinity)\n );\n },\n []\n );\n\n const setVolume = useCallback((vol: number) => {\n const audio = audioRef.current;\n if (!audio) return;\n const clamped = Math.max(0, Math.min(1, vol));\n audio.volume = clamped;\n setVolumeState(clamped);\n if (clamped > 0) {\n audio.muted = false;\n setIsMuted(false);\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.muted = !audio.muted;\n setIsMuted(audio.muted);\n }, []);\n\n const toggleLoop = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n const next = !audio.loop;\n audio.loop = next;\n setIsLoop(next);\n }, []);\n\n const formatTime = useCallback((time: number) => {\n if (!isFinite(time) || isNaN(time) || time < 0) return '0:00';\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n }, []);\n\n return {\n audioRef,\n isPlaying,\n isLoading,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n };\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { Play, Pause, Volume2, VolumeX, Volume1, SkipBack, SkipForward, Repeat } from 'lucide-react';\nimport { useAudioPlayer } from '../../hooks/useAudioPlayer';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\n/** 文本溢出时自动横向滚动 */\nconst MarqueeText: React.FC<{\n text: string;\n className?: string;\n style?: React.CSSProperties;\n}> = ({ text, className = '', style }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const innerRef = useRef<HTMLDivElement>(null);\n const [overflow, setOverflow] = useState(false);\n const [scrollDist, setScrollDist] = useState(0);\n\n useEffect(() => {\n const check = () => {\n const container = containerRef.current;\n const inner = innerRef.current;\n if (!container || !inner) return;\n const cw = container.clientWidth;\n const tw = inner.scrollWidth;\n setOverflow(tw > cw);\n setScrollDist(tw);\n };\n check();\n const observer = new ResizeObserver(check);\n if (containerRef.current) observer.observe(containerRef.current);\n return () => observer.disconnect();\n }, [text]);\n\n const gap = 60;\n const totalScroll = scrollDist + gap;\n const dur = totalScroll / 40;\n\n return (\n <div\n ref={containerRef}\n className={`rfp-overflow-hidden rfp-whitespace-nowrap ${className}`}\n style={style}\n >\n {overflow ? (\n <motion.div\n className=\"rfp-inline-flex rfp-whitespace-nowrap\"\n animate={{ x: [0, -totalScroll] }}\n transition={{ duration: dur, repeat: Infinity, ease: 'linear', repeatDelay: 1.5 }}\n >\n <span>{text}</span>\n <span style={{ width: gap }} className=\"rfp-inline-block\" />\n <span>{text}</span>\n </motion.div>\n ) : null}\n {/* 始终渲染用于测量的隐藏层 */}\n <div\n ref={innerRef}\n className=\"rfp-whitespace-nowrap\"\n style={overflow ? { position: 'absolute', visibility: 'hidden', pointerEvents: 'none' } : undefined}\n >\n {text}\n </div>\n </div>\n );\n};\n\n/** SVG 唱臂组件 */\nconst Tonearm: React.FC<{ isPlaying: boolean }> = ({ isPlaying }) => (\n <motion.div\n className=\"rfp-absolute\"\n style={{\n top: '-6px',\n right: '2px',\n width: '100px',\n height: '120px',\n transformOrigin: '76px 16px',\n zIndex: 5,\n }}\n animate={{ rotate: isPlaying ? 16 : 0 }}\n transition={{ duration: 0.8, ease: [0.4, 0, 0.2, 1] }}\n >\n <svg\n width=\"100\"\n height=\"120\"\n viewBox=\"0 0 100 120\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* 底座阴影 */}\n <circle cx=\"76\" cy=\"16\" r=\"13\" fill=\"rgba(0,0,0,0.3)\" />\n {/* 底座外圈 */}\n <circle cx=\"76\" cy=\"16\" r=\"11\" fill=\"url(#baseGrad)\" />\n {/* 底座内圈 */}\n <circle cx=\"76\" cy=\"16\" r=\"6\" fill=\"url(#baseInnerGrad)\" />\n {/* 底座中心轴 */}\n <circle cx=\"76\" cy=\"16\" r=\"2.5\" fill=\"#222\" stroke=\"#555\" strokeWidth=\"0.5\" />\n\n {/* 臂杆 */}\n <path\n d=\"M74 22 L56 88\"\n stroke=\"url(#armGrad)\"\n strokeWidth=\"3.5\"\n strokeLinecap=\"round\"\n />\n {/* 臂杆高光 */}\n <path\n d=\"M74.8 22 L56.8 88\"\n stroke=\"rgba(255,255,255,0.06)\"\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n />\n\n {/* 唱头座 (Headshell) */}\n <rect x=\"50\" y=\"86\" width=\"12\" height=\"7\" rx=\"1.5\" fill=\"url(#headGrad)\" />\n {/* 唱头 (Cartridge) */}\n <rect x=\"52.5\" y=\"92\" width=\"7\" height=\"9\" rx=\"1\" fill=\"url(#cartridgeGrad)\" />\n {/* 唱针 (Stylus) */}\n <line x1=\"56\" y1=\"101\" x2=\"56\" y2=\"105\" stroke=\"#bbb\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n <circle cx=\"56\" cy=\"105.5\" r=\"0.8\" fill=\"#ddd\" />\n\n {/* 渐变定义 */}\n <defs>\n <radialGradient id=\"baseGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stopColor=\"#555\" />\n <stop offset=\"100%\" stopColor=\"#1a1a1a\" />\n </radialGradient>\n <radialGradient id=\"baseInnerGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stopColor=\"#666\" />\n <stop offset=\"100%\" stopColor=\"#333\" />\n </radialGradient>\n <linearGradient id=\"armGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#555\" />\n <stop offset=\"50%\" stopColor=\"#444\" />\n <stop offset=\"100%\" stopColor=\"#333\" />\n </linearGradient>\n <linearGradient id=\"headGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#555\" />\n <stop offset=\"100%\" stopColor=\"#333\" />\n </linearGradient>\n <linearGradient id=\"cartridgeGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#444\" />\n <stop offset=\"100%\" stopColor=\"#222\" />\n </linearGradient>\n </defs>\n </svg>\n </motion.div>\n);\n\ninterface AudioRendererProps {\n url: string;\n fileName: string;\n}\n\nexport const AudioRenderer: React.FC<AudioRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const {\n audioRef,\n isPlaying,\n isLoading,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n } = useAudioPlayer({ url });\n\n const [showVolume, setShowVolume] = useState(false);\n const volumeRef = useRef<HTMLDivElement>(null);\n const volumeTimerRef = useRef<ReturnType<typeof setTimeout>>();\n\n const progress = duration > 0 ? currentTime / duration : 0;\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (volumeRef.current && !volumeRef.current.contains(e.target as Node)) {\n setShowVolume(false);\n }\n };\n if (showVolume) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [showVolume]);\n\n const handleVolumeEnter = () => {\n clearTimeout(volumeTimerRef.current);\n setShowVolume(true);\n };\n\n const handleVolumeLeave = () => {\n volumeTimerRef.current = setTimeout(() => setShowVolume(false), 300);\n };\n\n const VolumeIcon = isMuted || volume === 0 ? VolumeX : volume < 0.5 ? Volume1 : Volume2;\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-p-4 md:rfp-p-8 rfp-gap-5 md:rfp-gap-8 rfp-select-none\">\n {/* 唱片机整体 */}\n <div className=\"rfp-relative\" style={{ width: '260px', height: '240px' }}>\n {/* 外圈光晕 */}\n <motion.div\n className=\"rfp-absolute rfp-rounded-full\"\n style={{\n width: '220px',\n height: '220px',\n top: '18px',\n left: '8px',\n background: 'radial-gradient(circle, rgba(129,140,248,0.12) 0%, transparent 70%)',\n }}\n animate={isPlaying ? { scale: [1, 1.08, 1], opacity: [0.5, 1, 0.5] } : { scale: 1, opacity: 0.2 }}\n transition={isPlaying ? { duration: 3, repeat: Infinity, ease: 'easeInOut' } : { duration: 0.5 }}\n />\n\n {/* 唱片主体 */}\n <div\n className=\"rfp-absolute rfp-rounded-full rfp-overflow-hidden\"\n style={{\n width: '200px',\n height: '200px',\n top: '28px',\n left: '18px',\n background: `\n radial-gradient(circle at center, transparent 95%, rgba(30,30,30,0.8) 95.5%, #111 97%),\n radial-gradient(circle at center, transparent 38%, rgba(50,50,50,0.5) 38.15%, transparent 38.4%),\n radial-gradient(circle at center, transparent 45%, rgba(50,50,50,0.3) 45.15%, transparent 45.4%),\n radial-gradient(circle at center, transparent 52%, rgba(50,50,50,0.5) 52.15%, transparent 52.4%),\n radial-gradient(circle at center, transparent 59%, rgba(50,50,50,0.3) 59.15%, transparent 59.4%),\n radial-gradient(circle at center, transparent 66%, rgba(50,50,50,0.5) 66.15%, transparent 66.4%),\n radial-gradient(circle at center, transparent 73%, rgba(50,50,50,0.3) 73.15%, transparent 73.4%),\n radial-gradient(circle at center, transparent 80%, rgba(50,50,50,0.4) 80.15%, transparent 80.4%),\n radial-gradient(circle at center, transparent 87%, rgba(50,50,50,0.3) 87.15%, transparent 87.4%),\n conic-gradient(from 0deg, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c, #212121, #1a1a1a, #252525, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c)\n `,\n boxShadow: isPlaying\n ? '0 0 36px rgba(129,140,248,0.1), 0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)'\n : '0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)',\n animation: 'rfp-vinyl-spin 8s linear infinite',\n animationPlayState: isPlaying ? 'running' : 'paused',\n }}\n >\n {/* 中心标签 */}\n <div\n className=\"rfp-absolute rfp-rounded-full\"\n style={{\n width: '34%',\n height: '34%',\n top: '33%',\n left: '33%',\n background: 'radial-gradient(circle at 40% 38%, #818cf8, #6366f1, #4f46e5, #4338ca)',\n boxShadow: 'inset 0 1px 3px rgba(255,255,255,0.25), inset 0 -1px 3px rgba(0,0,0,0.3), 0 0 8px rgba(0,0,0,0.3)',\n }}\n >\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-rounded-full rfp-opacity-20\"\n style={{\n background: `\n radial-gradient(circle at center, transparent 30%, rgba(0,0,0,0.3) 31%, transparent 32%),\n radial-gradient(circle at center, transparent 50%, rgba(0,0,0,0.2) 51%, transparent 52%),\n radial-gradient(circle at center, transparent 70%, rgba(0,0,0,0.3) 71%, transparent 72%),\n radial-gradient(circle at center, transparent 88%, rgba(0,0,0,0.2) 89%, transparent 90%)\n `,\n }}\n />\n <div\n className=\"rfp-absolute rfp-rounded-full\"\n style={{\n width: '14%',\n height: '14%',\n top: '43%',\n left: '43%',\n background: 'radial-gradient(circle at 40% 40%, #333, #0d0d0d)',\n boxShadow: 'inset 0 1px 3px rgba(0,0,0,0.9), 0 0 2px rgba(0,0,0,0.5)',\n }}\n />\n </div>\n\n {isLoading && (\n <motion.div\n className=\"rfp-absolute rfp-inset-0 rfp-rounded-full\"\n style={{ border: '2px solid rgba(129,140,248,0.3)' }}\n animate={{ scale: [1, 1.02, 1], opacity: [0.3, 0.6, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity }}\n />\n )}\n </div>\n\n {/* 唱臂 */}\n <Tonearm isPlaying={isPlaying} />\n </div>\n\n {/* 文件名 */}\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <MarqueeText\n text={fileName}\n className=\"rfp-text-lg md:rfp-text-xl rfp-font-medium rfp-mb-1 rfp-text-fg-primary\"\n />\n <p className=\"rfp-text-xs rfp-tracking-widest rfp-uppercase rfp-text-accent\">\n Audio\n </p>\n </div>\n\n {/* 控制面板 */}\n <div\n className=\"rfp-w-full rfp-max-w-sm md:rfp-max-w-md rfp-rounded-2xl rfp-p-4 md:rfp-p-6 rfp-border rfp-bg-surface-1 rfp-border-line-weak\"\n style={{ backdropFilter: 'blur(16px)' }}\n >\n {/* 进度条 */}\n <div className=\"rfp-mb-5\">\n <div className=\"rfp-relative rfp-h-4 rfp-flex rfp-items-center\">\n <div className=\"rfp-absolute rfp-w-full rfp-h-[5px] rfp-rounded-full rfp-bg-surface-2\" />\n <div\n className=\"rfp-absolute rfp-h-[5px] rfp-rounded-full rfp-pointer-events-none\"\n style={{\n width: `${progress * 100}%`,\n background: 'linear-gradient(90deg, var(--fp-accent), var(--fp-accent-hover))',\n boxShadow: isPlaying ? '0 0 8px rgba(129,140,248,0.4)' : 'none',\n transition: 'width 0.1s linear',\n }}\n />\n <input\n type=\"range\"\n min=\"0\"\n max={duration > 0 ? duration : currentTime || 100}\n step=\"any\"\n value={currentTime}\n onChange={(e) => seek(parseFloat(e.target.value))}\n disabled={duration <= 0}\n aria-label={t('audio.aria.progress')}\n className=\"audio-slider rfp-absolute rfp-w-full\"\n />\n </div>\n <div className=\"rfp-flex rfp-justify-between rfp-text-xs rfp-mt-2.5 rfp-text-fg-tertiary\">\n <span style={{ fontVariantNumeric: 'tabular-nums' }}>{formatTime(currentTime)}</span>\n <span style={{ fontVariantNumeric: 'tabular-nums' }}>{duration > 0 ? formatTime(duration) : '--:--'}</span>\n </div>\n </div>\n\n {/* 控制按钮 */}\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-gap-3\">\n {/* 循环 */}\n <motion.button\n onClick={toggleLoop}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={isLoop ? t('audio.aria.loop_off') : t('audio.aria.loop_on')}\n className={`rfp-w-9 rfp-h-9 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors ${\n isLoop\n ? 'rfp-bg-accent-soft rfp-text-accent'\n : 'rfp-bg-surface-2 rfp-text-fg-tertiary'\n }`}\n >\n <Repeat className=\"rfp-w-4 rfp-h-4\" />\n </motion.button>\n\n {/* 后退 */}\n <motion.button\n onClick={() => skip(-10)}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={t('audio.aria.backward_10')}\n className=\"rfp-w-10 rfp-h-10 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-bg-surface-2 rfp-text-fg-secondary\"\n >\n <SkipBack className=\"rfp-w-[18px] rfp-h-[18px]\" />\n </motion.button>\n\n {/* 播放/暂停 */}\n <motion.button\n onClick={togglePlay}\n whileHover={{ scale: 1.06 }}\n whileTap={{ scale: 0.94 }}\n aria-label={isPlaying ? t('audio.aria.pause') : t('audio.aria.play')}\n className=\"rfp-w-14 rfp-h-14 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center\"\n style={{\n background: 'linear-gradient(135deg, var(--fp-accent-hover), var(--fp-accent))',\n color: '#fff',\n boxShadow: '0 4px 20px rgba(99,102,241,0.35)',\n }}\n >\n {isPlaying ? (\n <Pause className=\"rfp-w-6 rfp-h-6\" />\n ) : (\n <Play className=\"rfp-w-6 rfp-h-6 rfp-ml-0.5\" />\n )}\n </motion.button>\n\n {/* 前进 */}\n <motion.button\n onClick={() => skip(10)}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={t('audio.aria.forward_10')}\n className=\"rfp-w-10 rfp-h-10 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-bg-surface-2 rfp-text-fg-secondary\"\n >\n <SkipForward className=\"rfp-w-[18px] rfp-h-[18px]\" />\n </motion.button>\n\n {/* 音量 */}\n <div\n ref={volumeRef}\n className=\"rfp-relative\"\n onMouseEnter={handleVolumeEnter}\n onMouseLeave={handleVolumeLeave}\n >\n <motion.button\n onClick={toggleMute}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={isMuted ? t('audio.aria.unmute') : t('audio.aria.mute')}\n className={`rfp-w-9 rfp-h-9 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors ${\n showVolume\n ? 'rfp-bg-accent-soft rfp-text-accent'\n : 'rfp-bg-surface-2 rfp-text-fg-secondary'\n }`}\n >\n <VolumeIcon className=\"rfp-w-4 rfp-h-4\" />\n </motion.button>\n\n <AnimatePresence>\n {showVolume && (\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ duration: 0.12 }}\n className=\"rfp-absolute rfp-bottom-full rfp-mb-2 rfp-rounded-xl rfp-p-3 rfp-border rfp-bg-surface-3 rfp-border-line\"\n style={{\n left: '50%',\n marginLeft: '-27px',\n backdropFilter: 'blur(16px)',\n }}\n onMouseEnter={handleVolumeEnter}\n onMouseLeave={handleVolumeLeave}\n >\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-gap-2\" style={{ height: '100px' }}>\n <div className=\"rfp-relative rfp-flex rfp-items-center rfp-justify-center\" style={{ width: '24px', height: '80px' }}>\n <div\n className=\"rfp-absolute rfp-rounded-full rfp-bg-surface-2\"\n style={{ width: '3px', height: '100%' }}\n />\n <div\n className=\"rfp-absolute rfp-bottom-0 rfp-rounded-full rfp-pointer-events-none\"\n style={{\n width: '3px',\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: 'var(--fp-accent-hover)',\n transition: 'height 0.1s linear',\n }}\n />\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n value={isMuted ? 0 : volume}\n onChange={(e) => setVolume(parseFloat(e.target.value))}\n aria-label={t('audio.aria.volume')}\n className=\"volume-slider-vertical rfp-absolute\"\n style={{\n width: '80px',\n height: '24px',\n transform: 'rotate(-90deg)',\n transformOrigin: 'center center',\n }}\n />\n </div>\n <span className=\"rfp-text-[10px] rfp-tabular-nums rfp-text-fg-tertiary\">\n {Math.round((isMuted ? 0 : volume) * 100)}\n </span>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n </div>\n </div>\n\n <audio ref={audioRef} src={url} className=\"rfp-hidden\" />\n </div>\n );\n};\n","import { useState, useEffect } from 'react';\nimport { codeToHtml } from 'shiki';\nimport { useResolvedTheme } from '../ThemeContext';\n\n/**\n * 用 shiki 把代码高亮成 HTML(与 vue-file-preview 同引擎、同主题,保证两端视觉一致)。\n *\n * - dark 主题用 `dark-plus`(VSCode Dark Plus)\n * - light 主题用 `github-light`(GitHub Light)\n *\n * shiki 输出的 <pre> 自带 inline 背景/前景色,主题切换时必须重新高亮,\n * 因此 resolvedTheme 进入依赖数组。\n *\n * @returns\n * - `html`: 高亮后的 HTML 字符串(失败或加载中为 '')\n * - `loading`: 是否正在高亮\n */\nexport function useShikiHighlight(code: string, lang: string): { html: string; loading: boolean } {\n const resolvedTheme = useResolvedTheme();\n const [html, setHtml] = useState('');\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n codeToHtml(code, {\n lang,\n theme: resolvedTheme === 'light' ? 'github-light' : 'dark-plus',\n })\n .then((out) => {\n if (!cancelled) {\n setHtml(out);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setHtml('');\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [code, lang, resolvedTheme]);\n\n return { html, loading };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport rehypeRaw from 'rehype-raw';\nimport { Copy, Check } from 'lucide-react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\nimport 'katex/dist/katex.min.css';\n\ninterface MarkdownRendererProps {\n url: string;\n viewMode?: 'preview' | 'source';\n}\n\nconst useCopy = (text: string) => {\n const [copied, setCopied] = useState(false);\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n }\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [text]);\n return { copied, handleCopy };\n};\n\n/** 内联版复制按钮:放在代码块 header 行内,始终可见 */\nconst InlineCopyButton = ({ text }: { text: string }) => {\n const t = useTranslator();\n const { copied, handleCopy } = useCopy(text);\n return (\n <button\n onClick={handleCopy}\n className=\"rfp-p-1 rfp-rounded rfp-text-fg-muted hover:rfp-text-fg-secondary rfp-transition-colors rfp-flex rfp-items-center rfp-gap-1\"\n title={copied ? t('markdown.copied') : t('markdown.copy_code')}\n >\n {copied ? <Check size={13} /> : <Copy size={13} />}\n </button>\n );\n};\n\n/** 浮动版复制按钮:无 header 时绝对定位于代码块右上角(hover 显示) */\nconst FloatingCopyButton = ({ text }: { text: string }) => {\n const t = useTranslator();\n const { copied, handleCopy } = useCopy(text);\n return (\n <button\n onClick={handleCopy}\n className=\"rfp-absolute rfp-top-2 rfp-right-2 rfp-p-1.5 rfp-rounded-md rfp-bg-surface-2 hover:rfp-bg-surface-3 rfp-text-fg-tertiary hover:rfp-text-fg-secondary rfp-transition-colors rfp-opacity-0 group-hover:rfp-opacity-100 rfp-border rfp-border-line\"\n title={copied ? t('markdown.copied') : t('markdown.copy_code')}\n >\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n );\n};\n\n/** 带语言标注的代码块:shiki 高亮 + header + 复制按钮 */\nconst ShikiCodeBlock = ({ code, lang }: { code: string; lang: string }) => {\n const { html } = useShikiHighlight(code, lang);\n return (\n <div className=\"rfp-relative rfp-group rfp-my-4\">\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-1.5 rfp-bg-surface-1 rfp-border rfp-border-line-weak rfp-rounded-t-md rfp-border-b-0\">\n <span className=\"rfp-text-xs rfp-text-fg-secondary rfp-font-mono rfp-select-none\">{lang}</span>\n <InlineCopyButton text={code} />\n </div>\n {html ? (\n <div\n className=\"rfp-shiki-wrapper rfp-rounded-b-md rfp-border rfp-border-line-weak rfp-border-t-0 rfp-overflow-x-auto\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre\n className=\"rfp-m-0 rfp-rounded-b-md rfp-border rfp-border-line-weak rfp-border-t-0 rfp-overflow-x-auto rfp-p-4 rfp-bg-code-bg\"\n style={{ fontSize: '13px', lineHeight: '1.5' }}\n >\n <code className=\"rfp-font-mono rfp-text-code-fg rfp-text-sm\">{code}</code>\n </pre>\n )}\n </div>\n );\n};\n\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ url, viewMode = 'preview' }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const { html: sourceHtml } = useShikiHighlight(\n viewMode === 'source' ? content : '',\n 'markdown',\n );\n\n useEffect(() => {\n const loadMarkdown = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher });\n setContent(text);\n } catch (err) {\n setError(t('markdown.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n\n loadMarkdown();\n }, [url, fetcher, t]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n // 源码视图\n if (viewMode === 'source') {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {sourceHtml ? (\n <div\n className=\"rfp-shiki-wrapper with-line-numbers\"\n dangerouslySetInnerHTML={{ __html: sourceHtml }}\n />\n ) : (\n <pre className=\"rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm rfp-whitespace-pre-wrap rfp-break-words\">\n {content}\n </pre>\n )}\n </div>\n );\n }\n\n // 预览视图\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-p-6 md:rfp-p-10\">\n <div className=\"rfp-max-w-full md:rfp-max-w-4xl rfp-mx-auto\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkMath]}\n rehypePlugins={[rehypeRaw, rehypeKatex]}\n components={{\n code({ node, inline, className, children, ...props }: any) {\n const match = /language-(\\w+)/.exec(className || '');\n const codeString = String(children).replace(/\\n$/, '');\n if (!inline && match) {\n // 有语言标注的代码块 - shiki 高亮\n return <ShikiCodeBlock code={codeString} lang={match[1]} />;\n }\n if (!inline) {\n // 无语言标注的代码块 - 纯文本暗色显示\n return (\n <div className=\"rfp-relative rfp-group rfp-my-4\">\n <FloatingCopyButton text={codeString} />\n <pre\n className=\"rfp-m-0 rfp-rounded-md rfp-border rfp-border-line-weak rfp-overflow-x-auto rfp-p-4 rfp-bg-code-bg\"\n style={{ fontSize: '13px', lineHeight: '1.5' }}\n >\n <code className=\"rfp-font-mono rfp-text-code-fg rfp-text-sm\">{children}</code>\n </pre>\n </div>\n );\n }\n // 行内代码\n return (\n <code\n className=\"rfp-bg-surface-2 rfp-px-1.5 rfp-py-0.5 rfp-rounded rfp-text-sm rfp-font-mono rfp-text-fg-primary rfp-border rfp-border-line-weak\"\n {...props}\n >\n {children}\n </code>\n );\n },\n h1: ({ children }) => (\n <h1 className=\"rfp-text-3xl rfp-font-semibold rfp-mb-4 rfp-mt-6 rfp-text-fg-primary first:rfp-mt-0\">\n {children}\n </h1>\n ),\n h2: ({ children }) => (\n <h2 className=\"rfp-text-2xl rfp-font-semibold rfp-mb-3 rfp-mt-8 rfp-text-fg-primary\">\n {children}\n </h2>\n ),\n h3: ({ children }) => (\n <h3 className=\"rfp-text-xl rfp-font-semibold rfp-mb-2 rfp-mt-6 rfp-text-fg-primary\">{children}</h3>\n ),\n h4: ({ children }) => (\n <h4 className=\"rfp-text-lg rfp-font-semibold rfp-mb-2 rfp-mt-4 rfp-text-fg-primary\">{children}</h4>\n ),\n p: ({ children }) => (\n <p className=\"rfp-text-fg-secondary rfp-mb-4 rfp-leading-7 rfp-text-base\">{children}</p>\n ),\n a: ({ href, children }) => (\n <a\n href={href}\n className=\"rfp-text-indigo-400 hover:rfp-text-indigo-300 rfp-underline rfp-decoration-indigo-600 hover:rfp-decoration-indigo-400\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </a>\n ),\n ul: ({ children }) => (\n <ul className=\"rfp-list-disc rfp-pl-6 rfp-mb-4 rfp-text-fg-secondary rfp-space-y-1\">{children}</ul>\n ),\n ol: ({ children }) => (\n <ol className=\"rfp-list-decimal rfp-pl-6 rfp-mb-4 rfp-text-fg-secondary rfp-space-y-1\">{children}</ol>\n ),\n li: ({ children }) => <li className=\"rfp-leading-7\">{children}</li>,\n blockquote: ({ children }) => (\n <blockquote className=\"rfp-border-l-4 rfp-border-line-strong rfp-pl-4 rfp-text-fg-tertiary rfp-my-4 rfp-italic\">\n {children}\n </blockquote>\n ),\n table: ({ children }) => (\n <div className=\"rfp-overflow-x-auto rfp-my-4 rfp-rounded-md rfp-border rfp-border-line\">\n <table className=\"rfp-min-w-full rfp-divide-y rfp-divide-divide\">{children}</table>\n </div>\n ),\n thead: ({ children }) => <thead className=\"rfp-bg-surface-1\">{children}</thead>,\n tbody: ({ children }) => (\n <tbody className=\"rfp-divide-y rfp-divide-divide rfp-bg-transparent\">{children}</tbody>\n ),\n tr: ({ children }) => (\n <tr className=\"hover:rfp-bg-surface-1 rfp-transition-colors\">{children}</tr>\n ),\n th: ({ children }) => (\n <th className=\"rfp-px-4 rfp-py-3 rfp-text-left rfp-text-xs rfp-font-semibold rfp-text-fg-tertiary rfp-uppercase rfp-tracking-wider\">\n {children}\n </th>\n ),\n td: ({ children }) => (\n <td className=\"rfp-px-4 rfp-py-3 rfp-text-sm rfp-text-fg-secondary\">{children}</td>\n ),\n hr: () => <hr className=\"rfp-border-line rfp-my-6\" />,\n img: ({ src, alt }) => (\n <img\n src={src}\n alt={alt}\n className=\"rfp-rounded-md rfp-max-w-full rfp-h-auto rfp-my-4 rfp-mx-auto rfp-block rfp-shadow-sm\"\n />\n ),\n input: ({ type, checked, ...props }) => {\n if (type === 'checkbox') {\n return (\n <input\n type=\"checkbox\"\n checked={checked}\n readOnly\n className=\"rfp-mr-2 rfp-rounded rfp-border-line\"\n {...props}\n />\n );\n }\n return <input type={type} {...props} />;\n },\n strong: ({ children }) => (\n <strong className=\"rfp-font-semibold rfp-text-fg-primary\">{children}</strong>\n ),\n em: ({ children }) => <em className=\"rfp-italic\">{children}</em>,\n del: ({ children }) => (\n <del className=\"rfp-text-fg-muted rfp-line-through\">{children}</del>\n ),\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n </div>\n );\n};\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { ChevronRight, ChevronDown } from 'lucide-react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useResolvedTheme, type ResolvedTheme } from '../../ThemeContext';\n\ninterface JsonRendererProps {\n url: string;\n fileName: string;\n}\n\ninterface JsonColors {\n key: string;\n string: string;\n number: string;\n keyword: string;\n bracket: string; // { } [ ]\n colon: string; // :\n collapsed: string; // \"N items / N keys\" 折叠提示\n arrow: string; // 折叠箭头\n}\n\n// VSCode Dark Plus / GitHub Light 两套配色,与 react-syntax-highlighter 的 vscDarkPlus / vs 主题保持一致\nconst DARK_COLORS: JsonColors = {\n key: '#9cdcfe',\n string: '#ce9178',\n number: '#b5cea8',\n keyword: '#569cd6',\n bracket: '#d4d4d4',\n colon: 'rgb(255 255 255 / 0.6)',\n collapsed: 'rgb(255 255 255 / 0.4)',\n arrow: 'rgb(255 255 255 / 0.5)',\n};\n\nconst LIGHT_COLORS: JsonColors = {\n key: '#005cc5',\n string: '#032f62',\n number: '#005cc5',\n keyword: '#d73a49',\n bracket: '#24292e',\n colon: 'rgb(23 23 23 / 0.6)',\n collapsed: 'rgb(23 23 23 / 0.45)',\n arrow: 'rgb(23 23 23 / 0.55)',\n};\n\n// ---------- JSON 树节点 ----------\n\ninterface JsonNodeProps {\n keyName?: string;\n value: unknown;\n depth: number;\n defaultExpanded: boolean;\n colors: JsonColors;\n}\n\nconst JsonNode: React.FC<JsonNodeProps> = ({ keyName, value, depth, defaultExpanded, colors }) => {\n const t = useTranslator();\n const [expanded, setExpanded] = useState(defaultExpanded);\n const indent = depth * 20;\n\n const toggle = useCallback(() => setExpanded(prev => !prev), []);\n\n // 基本类型\n if (value === null || value === undefined || typeof value !== 'object') {\n return (\n <div className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm\" style={{ paddingLeft: `${indent}px` }}>\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0\" />\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n {renderPrimitive(value, colors)}\n </div>\n );\n }\n\n const isArray = Array.isArray(value);\n const entries = isArray ? (value as unknown[]) : Object.entries(value as Record<string, unknown>);\n const count = entries.length;\n const openBracket = isArray ? '[' : '{';\n const closeBracket = isArray ? ']' : '}';\n\n // 空对象/数组\n if (count === 0) {\n return (\n <div className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm\" style={{ paddingLeft: `${indent}px` }}>\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0\" />\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n <span style={{ color: colors.bracket }}>{openBracket}{closeBracket}</span>\n </div>\n );\n }\n\n return (\n <div>\n {/* 折叠行 */}\n <div\n className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm rfp-cursor-pointer hover:rfp-bg-surface-1 rfp-select-none\"\n style={{ paddingLeft: `${indent}px` }}\n onClick={toggle}\n >\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0 rfp-flex rfp-items-center rfp-justify-center\" style={{ color: colors.arrow }}>\n {expanded\n ? <ChevronDown className=\"rfp-w-3.5 rfp-h-3.5\" />\n : <ChevronRight className=\"rfp-w-3.5 rfp-h-3.5\" />\n }\n </span>\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n <span style={{ color: colors.bracket }}>{openBracket}</span>\n {!expanded && (\n <span className=\"rfp-ml-1\" style={{ color: colors.collapsed }}>\n {isArray ? `${count} ${t('json.items')}` : `${count} ${t('json.keys')}`}\n <span style={{ color: colors.bracket }}> {closeBracket}</span>\n </span>\n )}\n </div>\n\n {/* 子节点 */}\n {expanded && (\n <>\n {isArray\n ? (value as unknown[]).map((item, i) => (\n <JsonNode key={i} value={item} depth={depth + 1} defaultExpanded={depth < 1} colors={colors} />\n ))\n : Object.entries(value as Record<string, unknown>).map(([k, v]) => (\n <JsonNode key={k} keyName={k} value={v} depth={depth + 1} defaultExpanded={depth < 1} colors={colors} />\n ))\n }\n <div className=\"rfp-font-mono rfp-text-sm rfp-py-px\" style={{ paddingLeft: `${indent + 20}px`, color: colors.bracket }}>\n {closeBracket}\n </div>\n </>\n )}\n </div>\n );\n};\n\nfunction renderPrimitive(value: unknown, colors: JsonColors) {\n if (value === null) return <span style={{ color: colors.keyword, fontStyle: 'italic' }}>null</span>;\n if (value === undefined) return <span style={{ color: colors.keyword, fontStyle: 'italic' }}>undefined</span>;\n if (typeof value === 'boolean') return <span style={{ color: colors.keyword }}>{String(value)}</span>;\n if (typeof value === 'number') return <span style={{ color: colors.number }}>{String(value)}</span>;\n if (typeof value === 'string') return <span style={{ color: colors.string }}>\"{value}\"</span>;\n return <span style={{ color: colors.bracket }}>{String(value)}</span>;\n}\n\nfunction pickColors(theme: ResolvedTheme): JsonColors {\n return theme === 'light' ? LIGHT_COLORS : DARK_COLORS;\n}\n\n// ---------- Main ----------\n\nexport const JsonRenderer: React.FC<JsonRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const resolvedTheme = useResolvedTheme();\n const colors = useMemo(() => pickColors(resolvedTheme), [resolvedTheme]);\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const loadJson = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher });\n setData(JSON.parse(text));\n } catch (err) {\n setError(t('json.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n loadJson();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg rfp-py-3 rfp-pr-4\">\n <JsonNode value={data} depth={0} defaultExpanded colors={colors} />\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { FileSpreadsheet } from 'lucide-react';\nimport Spreadsheet from 'x-data-spreadsheet';\nimport 'x-data-spreadsheet/dist/xspreadsheet.css';\nimport {\n parseCsv,\n guessCsvDelimiter,\n fetchTextUtf8,\n convertCsvToSpreadsheetData,\n} from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface CsvRendererProps {\n url: string;\n fileName: string;\n}\n\nexport const CsvRenderer: React.FC<CsvRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const spreadsheetRef = useRef<Spreadsheet | null>(null);\n const sheetDataRef = useRef<Record<string, unknown>[] | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 800, height: 600 };\n const rawWidth = containerRef.current.clientWidth;\n const rawHeight = containerRef.current.clientHeight;\n const width = rawWidth > 100 ? rawWidth : 800;\n const height = rawHeight > 100 ? rawHeight : 600;\n return { width, height };\n }, []);\n\n const mountSpreadsheet = useCallback(() => {\n if (!containerRef.current || !sheetDataRef.current) return;\n\n containerRef.current.innerHTML = '';\n spreadsheetRef.current = null;\n\n const { width, height } = calculateDimensions();\n const isMobile = width < 640;\n\n const s = new Spreadsheet(containerRef.current, {\n mode: 'read',\n showToolbar: false,\n showContextmenu: false,\n showGrid: true,\n row: {\n len: 100,\n height: 25,\n },\n col: {\n len: 26,\n width: isMobile ? 80 : 100,\n indexWidth: isMobile ? 40 : 60,\n minWidth: isMobile ? 40 : 60,\n },\n view: {\n height: () => height,\n width: () => width,\n },\n });\n\n s.loadData(sheetDataRef.current as unknown as Record<string, unknown>);\n spreadsheetRef.current = s;\n }, [calculateDimensions]);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensionsRef.current = newDimensions;\n\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (sheetDataRef.current) {\n mountSpreadsheet();\n }\n }, 500);\n };\n\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, mountSpreadsheet]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadCsv = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const text = await fetchTextUtf8(url, { fetcher });\n const parsed = parseCsv(text, { delimiter: guessCsvDelimiter(fileName) });\n const sheetData = convertCsvToSpreadsheetData(parsed.header, parsed.rows, fileName);\n\n if (!isMounted) return;\n\n sheetDataRef.current = sheetData as unknown as Record<string, unknown>[];\n mountSpreadsheet();\n setLoading(false);\n } catch (err) {\n if (isMounted) {\n console.error('CSV 解析错误:', err);\n setError(t('csv.load_failed'));\n setLoading(false);\n }\n }\n };\n\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n loadCsv();\n });\n }, 100);\n\n return () => {\n isMounted = false;\n clearTimeout(timer);\n sheetDataRef.current = null;\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n spreadsheetRef.current = null;\n };\n }, [url, fileName, mountSpreadsheet]);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('csv.loading')}</p>\n </div>\n </div>\n )}\n\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <div className=\"rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-green-500 rfp-via-emerald-500 rfp-to-teal-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl\">\n <FileSpreadsheet className=\"rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary\" />\n </div>\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium\">{t('csv.load_failed')}</p>\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6\">{error}</p>\n </div>\n </div>\n )}\n\n {!error && (\n <div\n ref={containerRef}\n className=\"xlsx-spreadsheet-container rfp-w-full rfp-h-full\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n};\n","import { useState, useEffect } from 'react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\n\ninterface XmlRendererProps {\n url: string;\n fileName: string;\n}\n\n/**\n * 用 DOMParser 美化 XML:失败则原样返回\n */\nconst prettyPrintXml = (xml: string): string => {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'application/xml');\n // 检测解析错误\n const errNode = doc.querySelector('parsererror');\n if (errNode) return xml;\n // 使用 XSLT 或手动缩进:这里手动缩进更稳\n const serializer = new XMLSerializer();\n const serialized = serializer.serializeToString(doc);\n return indentXml(serialized);\n } catch {\n return xml;\n }\n};\n\nconst indentXml = (xml: string): string => {\n const PADDING = ' ';\n const reg = /(>)(<)(\\/*)/g;\n let formatted = xml.replace(reg, '$1\\n$2$3');\n // 自闭合和 CDATA 等不处理\n let pad = 0;\n return formatted\n .split('\\n')\n .map((line) => {\n let indent = 0;\n if (/^<\\/\\w/.test(line)) {\n pad = Math.max(pad - 1, 0);\n } else if (/^<\\w[^>]*[^/]>.*$/.test(line) && !/<.+<\\/.+>$/.test(line)) {\n indent = 1;\n }\n const padded = PADDING.repeat(pad) + line;\n pad += indent;\n return padded;\n })\n .join('\\n');\n};\n\nexport const XmlRenderer: React.FC<XmlRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const { html: highlighted } = useShikiHighlight(content, 'xml');\n\n useEffect(() => {\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n const raw = await fetchTextUtf8(url, { fetcher });\n setContent(prettyPrintXml(raw));\n } catch (err) {\n console.error(err);\n setError(t('xml.load_failed'));\n } finally {\n setLoading(false);\n }\n };\n load();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {highlighted ? (\n <div\n className=\"rfp-shiki-wrapper with-line-numbers\"\n dangerouslySetInnerHTML={{ __html: highlighted }}\n />\n ) : (\n <pre className=\"rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm rfp-whitespace-pre-wrap rfp-break-words\">\n {content}\n </pre>\n )}\n </div>\n );\n};\n","import { useState, useEffect, useMemo } from 'react';\nimport {\n parseSubtitle,\n formatSubtitleTime,\n fetchTextUtf8,\n type SubtitleParseResult,\n type SubtitleFormat,\n} from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface SubtitleRendererProps {\n url: string;\n fileName: string;\n}\n\nconst FORMAT_BY_EXT: Record<string, SubtitleFormat> = {\n srt: 'srt',\n vtt: 'vtt',\n lrc: 'lrc',\n elrc: 'elrc',\n ass: 'ass',\n ssa: 'ssa',\n ttml: 'ttml',\n dfxp: 'ttml',\n};\n\nconst getFormat = (fileName: string): SubtitleFormat | undefined => {\n const ext = fileName.split('.').pop()?.toLowerCase() || '';\n return FORMAT_BY_EXT[ext];\n};\n\nexport const SubtitleRenderer: React.FC<SubtitleRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [text, setText] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n setText(await fetchTextUtf8(url, { fetcher }));\n } catch (err) {\n console.error(err);\n setError(t('subtitle.load_failed'));\n } finally {\n setLoading(false);\n }\n };\n load();\n }, [url]);\n\n const parsed: SubtitleParseResult | null = useMemo(() => {\n if (!text) return null;\n try {\n return parseSubtitle(text, getFormat(fileName));\n } catch (err) {\n console.error(err);\n return null;\n }\n }, [text, fileName]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !parsed) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('subtitle.parse_failed')}</p>\n </div>\n </div>\n );\n }\n\n const isLyric = parsed.format === 'lrc' || parsed.format === 'elrc';\n const meta = parsed.metadata ?? {};\n const dotHover = isLyric ? 'group-hover:rfp-bg-violet-400' : 'group-hover:rfp-bg-sky-400';\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n {/* 内容滚动区 */}\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-px-6 md:rfp-px-10 rfp-pt-6 rfp-pb-16 md:rfp-pb-20\">\n <div className=\"rfp-relative rfp-max-w-5xl rfp-mx-auto\">\n {/* vertical line */}\n <div className=\"rfp-absolute rfp-left-[5px] md:rfp-left-[7px] rfp-top-2 rfp-bottom-2 rfp-w-px rfp-bg-surface-1\" />\n\n <ol className=\"rfp-space-y-5 md:rfp-space-y-6\">\n {parsed.cues.map((cue, i) => (\n <li key={`cue-${i}`} className=\"rfp-relative rfp-pl-6 md:rfp-pl-8 rfp-group\">\n {/* dot */}\n <div\n className={`rfp-absolute rfp-left-0 rfp-top-2 rfp-w-3 rfp-h-3 rfp-rounded-full rfp-bg-surface-3 rfp-border-2 rfp-border-[#0f0f12] rfp-transition-colors ${dotHover}`}\n />\n\n <div className=\"rfp-flex rfp-flex-wrap rfp-items-baseline rfp-gap-x-3 rfp-gap-y-1 rfp-mb-1.5\">\n <span className=\"rfp-text-[11px] rfp-font-mono rfp-text-fg-muted rfp-tabular-nums\">\n {formatSubtitleTime(cue.start)}\n </span>\n <span className=\"rfp-text-[11px] rfp-text-fg-disabled\">→</span>\n <span className=\"rfp-text-[11px] rfp-font-mono rfp-text-fg-muted rfp-tabular-nums\">\n {formatSubtitleTime(cue.end)}\n </span>\n <span className=\"rfp-text-[10px] rfp-font-mono rfp-text-fg-disabled rfp-tabular-nums\">\n #{cue.id ?? i + 1}\n </span>\n {cue.style && (\n <span className=\"rfp-text-[9px] rfp-uppercase rfp-tracking-widest rfp-text-fg-tertiary rfp-px-1.5 rfp-py-0.5 rfp-rounded rfp-bg-surface-1 rfp-border rfp-border-line-weak\">\n {cue.style}\n </span>\n )}\n </div>\n\n {cue.words && cue.words.length > 0 ? (\n <div className=\"rfp-flex rfp-flex-wrap rfp-gap-x-1.5 rfp-gap-y-1 rfp-text-base md:rfp-text-lg rfp-text-fg-primary rfp-leading-relaxed group-hover:rfp-text-fg-primary rfp-transition-colors\">\n {cue.words.map((word, wi) => (\n <span\n key={`w-${wi}`}\n className=\"rfp-inline-flex rfp-flex-col rfp-items-start\"\n title={formatSubtitleTime(word.start)}\n >\n <span className=\"rfp-text-[9px] rfp-text-fg-disabled rfp-font-mono rfp-leading-none rfp-tabular-nums\">\n {formatSubtitleTime(word.start).slice(3, 8)}\n </span>\n <span className=\"rfp-leading-snug\">{word.text}</span>\n </span>\n ))}\n </div>\n ) : (\n <p\n className={`rfp-whitespace-pre-wrap rfp-break-words rfp-leading-relaxed group-hover:rfp-text-fg-primary rfp-transition-colors rfp-text-fg-primary ${\n isLyric ? 'rfp-text-base md:rfp-text-xl rfp-font-medium' : 'rfp-text-sm md:rfp-text-base'\n }`}\n >\n {cue.text}\n </p>\n )}\n </li>\n ))}\n </ol>\n </div>\n </div>\n\n {/* 底部状态栏 */}\n <div className=\"rfp-pointer-events-none rfp-absolute rfp-bottom-3 rfp-right-3 md:rfp-bottom-4 md:rfp-right-4 rfp-flex rfp-items-center rfp-gap-2 rfp-px-2.5 rfp-py-1 rfp-rounded-full rfp-bg-surface-nav rfp-backdrop-blur rfp-border rfp-border-line-weak rfp-text-[10px] rfp-text-fg-tertiary rfp-font-mono rfp-tabular-nums\">\n <span>{parsed.cues.length} {isLyric ? t('subtitle.lines') : t('subtitle.cues')}</span>\n {meta.length && (\n <>\n <span className=\"rfp-text-fg-disabled\">·</span>\n <span>{meta.length}</span>\n </>\n )}\n </div>\n </div>\n );\n};\n","import React, { useEffect, useRef, useState, useCallback } from 'react';\n\nexport interface ResizableSplitProps {\n /** 左侧内容 */\n left: React.ReactNode;\n /** 右侧内容 */\n right: React.ReactNode;\n /** 左侧初始宽度(px);传入 storageKey 时会从 localStorage 读取 */\n initialLeftWidth?: number;\n /** 左侧最小宽度(px) */\n minLeftWidth?: number;\n /** 左侧最大宽度(px),同时不超过 `容器宽 - minRightWidth - 分隔线宽` */\n maxLeftWidth?: number;\n /** 右侧至少保留的宽度(px) */\n minRightWidth?: number;\n /** localStorage 持久化 key;不传则不持久化 */\n storageKey?: string;\n /** 启用横向拖动的媒体查询,默认 `(min-width: 768px)` */\n desktopMedia?: string;\n /** 容器额外类名 */\n className?: string;\n}\n\n/**\n * 通用可拖动分隔布局:\n * - 桌面端(由 `desktopMedia` 判定)横向分两栏,中间分隔线可左右拖动调整左栏宽度\n * - 移动端退化为上下堆叠,不显示分隔线\n * - 可选 `storageKey` 将宽度持久化到 localStorage\n */\nexport const ResizableSplit: React.FC<ResizableSplitProps> = ({\n left,\n right,\n initialLeftWidth = 280,\n minLeftWidth = 160,\n maxLeftWidth = 640,\n minRightWidth = 200,\n storageKey,\n desktopMedia = '(min-width: 768px)',\n className = '',\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [leftWidth, setLeftWidth] = useState<number>(() => {\n if (storageKey && typeof window !== 'undefined') {\n const saved = Number(window.localStorage.getItem(storageKey));\n if (!isNaN(saved) && saved > 0) return saved;\n }\n return initialLeftWidth;\n });\n const [dragging, setDragging] = useState(false);\n const [isDesktop, setIsDesktop] = useState(false);\n\n // 响应式:监听媒体查询\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia(desktopMedia);\n const handler = () => setIsDesktop(mq.matches);\n handler();\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, [desktopMedia]);\n\n // 拖动\n useEffect(() => {\n if (!dragging) return;\n const handleMove = (e: MouseEvent) => {\n if (!containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const cap = rect.width - minRightWidth - 6;\n const effectiveMax = Math.min(maxLeftWidth, cap);\n const newW = Math.max(minLeftWidth, Math.min(effectiveMax, x));\n setLeftWidth(newW);\n };\n const handleUp = () => setDragging(false);\n window.addEventListener('mousemove', handleMove);\n window.addEventListener('mouseup', handleUp);\n const prevCursor = document.body.style.cursor;\n const prevSelect = document.body.style.userSelect;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n return () => {\n window.removeEventListener('mousemove', handleMove);\n window.removeEventListener('mouseup', handleUp);\n document.body.style.cursor = prevCursor;\n document.body.style.userSelect = prevSelect;\n };\n }, [dragging, minLeftWidth, maxLeftWidth, minRightWidth]);\n\n // 持久化\n useEffect(() => {\n if (!storageKey || dragging) return;\n try {\n window.localStorage.setItem(storageKey, String(leftWidth));\n } catch {\n // ignore\n }\n }, [leftWidth, storageKey, dragging]);\n\n const handleDividerDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n setDragging(true);\n }, []);\n\n return (\n <div\n ref={containerRef}\n className={`rfp-w-full rfp-h-full rfp-flex rfp-flex-col md:rfp-flex-row rfp-min-h-0 rfp-min-w-0 ${className}`}\n >\n <div\n className=\"rfp-min-h-0 rfp-min-w-0 rfp-flex-shrink-0 rfp-w-full rfp-max-h-60 md:rfp-h-full md:rfp-max-h-none\"\n style={isDesktop ? { width: `${leftWidth}px` } : undefined}\n >\n {left}\n </div>\n {/* 分隔线:仅桌面显示 */}\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n onMouseDown={handleDividerDown}\n className={`rfp-hidden md:rfp-block rfp-relative rfp-w-1.5 rfp-flex-shrink-0 rfp-cursor-col-resize rfp-transition-colors ${\n dragging ? 'rfp-bg-surface-toolbar' : 'rfp-bg-surface-2 hover:rfp-bg-surface-3'\n }`}\n >\n {/* 加宽命中区,改善拖动体验 */}\n <span className=\"rfp-absolute rfp-inset-y-0 -rfp-left-1 -rfp-right-1\" />\n </div>\n <div className=\"rfp-flex-1 rfp-min-w-0 rfp-min-h-0 rfp-overflow-hidden\">{right}</div>\n </div>\n );\n};\n","import { useState, useEffect, useMemo, useCallback, useRef, lazy, Suspense } from 'react';\nimport React from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n Folder,\n FolderOpen,\n FileText,\n FileImage,\n FileCode,\n File as FileIcon,\n ChevronRight,\n} from 'lucide-react';\nimport type JSZip from 'jszip';\nimport {\n loadZip,\n listZipEntries,\n buildZipTree,\n readZipEntryBlob,\n formatFileSize,\n getFileType,\n inferMimeType,\n type ZipTreeNode,\n} from '@eternalheart/file-preview-core';\nimport { ResizableSplit } from '../../components/ResizableSplit';\nimport type { ZipToolbarStats } from './toolbar';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\n// 懒加载 FilePreviewContent 以打破循环依赖\nconst LazyFilePreviewContent = lazy(() =>\n import('../../FilePreviewContent').then(m => ({ default: m.FilePreviewContent }))\n);\n\ninterface ZipRendererProps {\n url: string;\n /** ZIP 嵌套深度(由 FilePreviewContent 传入) */\n nestingDepth?: number;\n /** 解析完成后向外回报统计信息(files / dirs / size),供工具栏展示 */\n onStatsChange?: (stats: ZipToolbarStats | null) => void;\n}\n\ninterface SelectedPreview {\n path: string;\n name: string;\n size: number;\n blobUrl: string;\n}\n\n/** 根据文件类型返回树节点图标 */\nconst resolveIcon = (name: string) => {\n const ft = getFileType({ id: '', name, url: '', type: '' });\n if (ft === 'image') return FileImage;\n if (ft === 'text' || ft === 'markdown' || ft === 'json' || ft === 'csv' || ft === 'xml' || ft === 'subtitle') {\n return name.endsWith('.md') || name.endsWith('.markdown') ? FileText : FileCode;\n }\n return FileIcon;\n};\n\n// ---------- Tooltip via portal ----------\n\ninterface HoverTipState {\n text: string;\n x: number;\n y: number;\n}\n\n// ---------- Tree item ----------\n\ninterface TreeItemProps {\n node: ZipTreeNode;\n depth: number;\n selectedPath: string | null;\n expanded: Set<string>;\n onToggle: (path: string) => void;\n onSelect: (node: ZipTreeNode) => void;\n onHover: (text: string, rect: DOMRect) => void;\n onLeave: () => void;\n}\n\nconst TreeItem: React.FC<TreeItemProps> = ({\n node,\n depth,\n selectedPath,\n expanded,\n onToggle,\n onSelect,\n onHover,\n onLeave,\n}) => {\n const isOpen = expanded.has(node.path);\n const isSelected = selectedPath === node.path;\n const pad = { paddingLeft: `${depth * 14 + 10}px` };\n const handleEnter = (e: React.MouseEvent<HTMLElement>) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n onHover(node.name || '/', rect);\n };\n\n if (node.isDir) {\n return (\n <>\n <button\n type=\"button\"\n onClick={() => onToggle(node.path)}\n onMouseEnter={handleEnter}\n onMouseLeave={onLeave}\n className=\"rfp-w-full rfp-flex rfp-items-center rfp-gap-1.5 rfp-py-1.5 rfp-pr-2 rfp-text-left rfp-text-fg-secondary hover:rfp-bg-surface-1 rfp-text-sm\"\n style={pad}\n >\n <ChevronRight\n className={`rfp-w-3.5 rfp-h-3.5 rfp-flex-shrink-0 rfp-transition-transform ${\n isOpen ? 'rfp-rotate-90' : ''\n }`}\n />\n {isOpen ? (\n <FolderOpen className=\"rfp-w-4 rfp-h-4 rfp-flex-shrink-0 rfp-text-amber-300/80\" />\n ) : (\n <Folder className=\"rfp-w-4 rfp-h-4 rfp-flex-shrink-0 rfp-text-amber-300/80\" />\n )}\n <span className=\"rfp-truncate rfp-flex-1 rfp-min-w-0\">{node.name || '/'}</span>\n </button>\n {isOpen &&\n node.children?.map((child) => (\n <TreeItem\n key={child.path}\n node={child}\n depth={depth + 1}\n selectedPath={selectedPath}\n expanded={expanded}\n onToggle={onToggle}\n onSelect={onSelect}\n onHover={onHover}\n onLeave={onLeave}\n />\n ))}\n </>\n );\n }\n\n const Icon = resolveIcon(node.name);\n\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(node)}\n onMouseEnter={handleEnter}\n onMouseLeave={onLeave}\n className={`rfp-w-full rfp-flex rfp-items-center rfp-gap-1.5 rfp-py-1.5 rfp-pr-2 rfp-text-left rfp-text-sm ${\n isSelected ? 'rfp-bg-surface-2 rfp-text-fg-primary' : 'rfp-text-fg-secondary hover:rfp-bg-surface-1'\n }`}\n style={pad}\n >\n <span className=\"rfp-w-3.5 rfp-h-3.5 rfp-flex-shrink-0\" />\n <Icon className=\"rfp-w-4 rfp-h-4 rfp-flex-shrink-0 rfp-text-fg-tertiary\" />\n <span className=\"rfp-flex-1 rfp-truncate rfp-min-w-0\">{node.name}</span>\n <span className=\"rfp-text-xs rfp-text-fg-disabled rfp-flex-shrink-0 rfp-ml-2\">\n {formatFileSize(node.size)}\n </span>\n </button>\n );\n};\n\n// ---------- Main Zip Renderer ----------\n\nexport const ZipRenderer: React.FC<ZipRendererProps> = ({ url, nestingDepth = 0, onStatsChange }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [zip, setZip] = useState<JSZip | null>(null);\n const [tree, setTree] = useState<ZipTreeNode | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [expanded, setExpanded] = useState<Set<string>>(new Set(['']));\n const [selected, setSelected] = useState<SelectedPreview | null>(null);\n const [previewLoading, setPreviewLoading] = useState(false);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [hoverTip, setHoverTip] = useState<HoverTipState | null>(null);\n const onStatsChangeRef = useRef(onStatsChange);\n\n useEffect(() => {\n onStatsChangeRef.current = onStatsChange;\n }, [onStatsChange]);\n\n useEffect(() => {\n let cancelled = false;\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n const res = await fetcher(url);\n if (!res.ok) throw new Error('加载失败');\n const buf = await res.arrayBuffer();\n const z = await loadZip(buf);\n if (cancelled) return;\n const entries = listZipEntries(z);\n const root = buildZipTree(entries);\n setZip(z);\n setTree(root);\n const init = new Set<string>(['']);\n if (root.children) {\n for (const c of root.children) if (c.isDir) init.add(c.path);\n }\n setExpanded(init);\n } catch (err) {\n console.error(err);\n if (!cancelled) setError(t('zip.load_failed'));\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n load();\n return () => {\n cancelled = true;\n };\n }, [url]);\n\n // 切换文件时回收 blob URL\n useEffect(() => {\n return () => {\n if (selected?.blobUrl) URL.revokeObjectURL(selected.blobUrl);\n };\n }, [selected]);\n\n const totalStats = useMemo<ZipToolbarStats | null>(() => {\n if (!tree) return null;\n let files = 0;\n let dirs = 0;\n let size = 0;\n const walk = (n: ZipTreeNode) => {\n if (n.isDir) {\n if (n.path) dirs++;\n n.children?.forEach(walk);\n } else {\n files++;\n size += n.size;\n }\n };\n walk(tree);\n return { files, dirs, size };\n }, [tree]);\n\n // 向外回报 stats\n useEffect(() => {\n onStatsChangeRef.current?.(totalStats);\n return () => {\n onStatsChangeRef.current?.(null);\n };\n }, [totalStats]);\n\n const handleToggle = useCallback((path: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n return next;\n });\n }, []);\n\n const handleHover = useCallback((text: string, rect: DOMRect) => {\n setHoverTip({\n text,\n x: rect.right + 8,\n y: rect.top + rect.height / 2,\n });\n }, []);\n\n const handleLeave = useCallback(() => {\n setHoverTip(null);\n }, []);\n\n const handleSelect = useCallback(\n async (node: ZipTreeNode) => {\n if (!zip || node.isDir) return;\n if (selected?.blobUrl) URL.revokeObjectURL(selected.blobUrl);\n setPreviewLoading(true);\n setPreviewError(null);\n\n try {\n const mime = inferMimeType(node.name);\n const blob = await readZipEntryBlob(zip, node.path, mime !== 'application/octet-stream' ? mime : undefined);\n const blobUrl = URL.createObjectURL(blob);\n setSelected({ path: node.path, name: node.name, size: node.size, blobUrl });\n } catch (err) {\n console.error(err);\n setPreviewError('条目读取失败');\n } finally {\n setPreviewLoading(false);\n }\n },\n [zip, selected]\n );\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !tree) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('zip.parse_failed')}</p>\n </div>\n </div>\n );\n }\n\n // 左侧:文件树\n const leftPane = (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto\">\n {tree.children?.map((child) => (\n <TreeItem\n key={child.path}\n node={child}\n depth={0}\n selectedPath={selected?.path ?? null}\n expanded={expanded}\n onToggle={handleToggle}\n onSelect={handleSelect}\n onHover={handleHover}\n onLeave={handleLeave}\n />\n ))}\n </div>\n );\n\n // 右侧:预览区\n const rightPane = (\n <div className=\"rfp-w-full rfp-h-full rfp-flex rfp-flex-col\">\n {!selected && (\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-muted rfp-text-sm rfp-p-6\">\n 从左侧选择一个文件以预览\n </div>\n )}\n {selected && previewLoading && (\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n {selected && !previewLoading && previewError && (\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-secondary\">\n {previewError}\n </div>\n )}\n {selected && !previewLoading && !previewError && (\n <>\n <div className=\"rfp-flex-1 rfp-min-h-0 rfp-overflow-hidden rfp-flex rfp-relative rfp-z-0\">\n <Suspense\n fallback={\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n }\n >\n <LazyFilePreviewContent\n mode=\"embed\"\n files={[{ name: selected.name, url: selected.blobUrl, type: inferMimeType(selected.name) }]}\n currentIndex={0}\n zipNestingDepth={nestingDepth + 1}\n />\n </Suspense>\n </div>\n </>\n )}\n </div>\n );\n\n return (\n <>\n <ResizableSplit\n left={leftPane}\n right={rightPane}\n initialLeftWidth={280}\n minLeftWidth={180}\n maxLeftWidth={560}\n storageKey=\"rfp-zip-split-left\"\n />\n {/* 文件名 hover tooltip(portal 到 body,避免被滚动区裁剪) */}\n {hoverTip &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n className=\"rfp-fixed rfp-z-[9999] rfp-pointer-events-none rfp-px-2 rfp-py-1 rfp-bg-[rgba(0,0,0,0.85)] rfp-text-fg-primary rfp-text-xs rfp-rounded rfp-whitespace-nowrap rfp-shadow-lg\"\n style={{\n left: `${hoverTip.x}px`,\n top: `${hoverTip.y}px`,\n transform: 'translateY(-50%)',\n }}\n >\n {hoverTip.text}\n </div>,\n document.body\n )}\n </>\n );\n};\n","import { useState, useEffect } from 'react';\nimport { fetchTextUtf8, getLanguageFromFileName } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\n\ninterface TextRendererProps {\n url: string;\n fileName: string;\n wordWrap?: boolean;\n htmlPreview?: boolean;\n}\n\nexport const TextRenderer: React.FC<TextRendererProps> = ({\n url,\n fileName,\n wordWrap = true,\n htmlPreview = false,\n}) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const language = getLanguageFromFileName(fileName);\n const { html: highlighted } = useShikiHighlight(\n language !== 'text' ? content : '',\n language,\n );\n\n useEffect(() => {\n const loadText = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher });\n setContent(text);\n } catch (err) {\n setError(t('text.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n\n loadText();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n // HTML 预览模式\n if (htmlPreview && (language === 'html')) {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-bg-surface-toolbar\">\n <iframe\n srcDoc={content}\n sandbox=\"allow-same-origin\"\n className=\"rfp-w-full rfp-h-full rfp-border-0\"\n title={fileName}\n />\n </div>\n );\n }\n\n // 源码模式\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {language === 'text' || !highlighted ? (\n <pre\n className={`rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm ${\n wordWrap ? 'rfp-whitespace-pre-wrap rfp-break-words' : 'rfp-whitespace-pre'\n }`}\n >\n {content}\n </pre>\n ) : (\n <div\n className={`rfp-shiki-wrapper with-line-numbers ${wordWrap ? '' : 'no-wrap'}`}\n dangerouslySetInnerHTML={{ __html: highlighted }}\n />\n )}\n </div>\n );\n};\n"],"names":["A","e","n","k","t","U","o","dt","ut","r","ft","mt","gt","xt","a","i","s","c","f","p","u","$","bt","B","W","Ft","wt","vt","z","yt","E","Z","V","L","l","d","T","R","O","q","F","b","g","x","v","N","D","w","m","h","y","_","S","H","_t","Ct","j","kt","St","Mt","G","J","X","K","Q","M","Y","tt","et","ot","nt","rt","P","zt","Et","it","at","C","st","lt","Nt","LocaleContext","createContext","LocaleProvider","locale","messages","children","value","useMemo","createTranslator","jsx","fallbackTranslator","getFallbackTranslator","useTranslator","ctx","useContext","useLocale","ThemeContext","ThemeProvider","theme","useResolvedTheme","OriginalSizeIcon","className","getImageToolbarGroups","ZoomOut","ZoomIn","Scan","RotateCcw","RotateCw","RefreshCw","getPdfToolbarGroups","getEpubToolbarGroups","List","_a","ChevronLeft","ChevronRight","Minimize2","Maximize2","getMobiToolbarGroups","getZipToolbarGroups","stats","formatFileSize","getTextToolbarGroups","groups","WrapText","Code","Eye","getMarkdownToolbarGroups","defaultValue","url","init","RequestContext","RequestProvider","requestInit","requestHandler","shouldFetchAsBlob","createFetcher","useFetcher","useResolvedUrl","file","fetcher","needBlob","resolved","setResolved","useState","createdRef","useRef","useEffect","cancelled","fetchAsBlobUrl","blobUrl","err","ImageRenderer","lazy","index$g","PdfRenderer","index$f","DocxRenderer","index$e","XlsxRenderer","index$d","PptxRenderer","index$c","MsgRenderer","index$b","EpubRenderer","index$a","MobiRenderer","index$9","VideoRenderer","index$8","AudioRenderer","index$7","MarkdownRenderer","index$6","JsonRenderer","index$5","CsvRenderer","index$4","XmlRenderer","index$3","SubtitleRenderer","index$2","ZipRenderer","index$1","TextRenderer","index","UnsupportedRenderer","fileName","fileType","onDownload","jsxs","FileQuestion","Download","RendererLoading","MAX_ZIP_NESTING_DEPTH","FilePreviewContent","props","FilePreviewContentInner","files","currentIndex","onNavigate","customRenderers","mode","onClose","zipNestingDepth","userMessages","headless","onCustomEvent","_requestInit","_requestHandler","_shouldFetchAsBlob","systemDark","setSystemDark","mql","handler","resolvedTheme","zoom","setZoom","rotation","setRotation","currentPage","setCurrentPage","setTotalPages","contentNaturalWidth","setContentNaturalWidth","contentNaturalHeight","setContentNaturalHeight","imageResetKey","setImageResetKey","contentRef","rootRef","epubRef","epubCurrent","setEpubCurrent","epubTotal","setEpubTotal","epubFullWidth","setEpubFullWidth","mobiRef","mobiCurrent","setMobiCurrent","mobiTotal","setMobiTotal","mobiFullWidth","setMobiFullWidth","zipStats","setZipStats","textWordWrap","setTextWordWrap","textHtmlPreview","setTextHtmlPreview","markdownViewMode","setMarkdownViewMode","navVisible","setNavVisible","navHideTimerRef","NAV_HIDE_DELAY","resetNavTimer","useCallback","handleMouseMove","normalizedFiles","normalizeFiles","currentFile","resolvedUrl","customRenderer","renderer","getFileType","emitCustom","name","payload","customCtx","containerWidth","containerHeight","scaleX","scaleY","newZoom","handleKeyDown","el","handleZoomIn","prev","handleZoomOut","handleRotate","handleRotateLeft","handleFitToWidth","handleOriginalSize","handleZoomChange","handleReset","handleDownload","downloadFileWithFetcher","handleEpubChapterChange","current","total","handleMobiChapterChange","handleZipStatsChange","showCloseButton","toolGroups","ext","_b","actionGroups","renderToolbarItems","dividerClass","group","gi","arr","React","item","ii","ToolbarButton","motion","Suspense","Fragment","icon","label","onClick","disabled","FilePreviewModal","isOpen","originalOverflow","originalPaddingRight","scrollbarWidth","modalContent","AnimatePresence","createPortal","FilePreviewEmbed","width","height","style","configurePdfjs","options","workerSrc","pdfjs","cMapUrl","cMapPacked","VERSION","packageJson","resetKey","fileSize","onZoomChange","onNaturalWidthChange","onNaturalHeightChange","loaded","setLoaded","error","setError","position","setPosition","isDragging","setIsDragging","dragStart","setDragStart","internalZoom","setInternalZoom","naturalSize","setNaturalSize","imgRef","containerRef","handleLoad","img","clampPosition","pos","currentZoom","container","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleError","handleDoubleClick","handleWheelNative","rect","mouseX","mouseY","delta","scale","handleMouseDown","handleMouseUp","onPageChange","onTotalPagesChange","onPageWidthChange","numPages","setNumPages","pageRefs","onDocumentLoadSuccess","onDocumentLoadError","handleScroll","scrollTop","scrollCenter","currentVisiblePage","minDistance","pageElement","pageNumber","containerRect","pageCenter","distance","setPageRef","element","Document","Page","page","PAGE_HEIGHT","PAGE_PADDING_Y","PAGE_PADDING_X","PAGE_CONTENT_HEIGHT","PAGE_GAP","contentStyle","html","setHtml","loading","setLoading","pages","setPages","measureRef","response","arrayBuffer","result","mammoth","paginate","currentPageUsed","child","blocks","pageHtml","spreadsheetRef","sheetDataRef","resizeObserverRef","resizeTimeoutRef","lastDimensionsRef","calculateDimensions","rawWidth","rawHeight","mountSpreadsheet","isMobile","Spreadsheet","isInitialRender","updateDimensions","newDimensions","lastDimensions","widthDiff","heightDiff","isMounted","loadExcel","workbook","ExcelJS","sheetData","convertWorkbookToSpreadsheetData","errorMsg","timer","FileSpreadsheet","tiled","slideCount","setSlideCount","previewerRef","arrayBufferRef","parentWidth","reinitializePreviewer","currentDimensions","previewer","timeoutId","loadPptx","hiddenContainer","tempPreviewer","count","Presentation","formatRecipients","recipients","type","email","formatDate","dateStr","date","decodeHtmlBody","fields","emptyBodyText","formatMessageClass","messageClass","labelStyle","rowStyle","iconWrapStyle","iconStyle","valueStyle","setFields","fileData","MsgReader","toStr","ccStr","bccStr","senderName","senderEmail","sender","sentDate","receivedDate","createdDate","lastModified","subject","attachments","bodyHtml","messageId","fieldsAny","importance","importanceLabel","sensitivity","sensitivityLabel","User","Users","Calendar","Clock","Tag","Mail","Paperclip","size","sizeStr","Hash","styleEl","A4_WIDTH","forwardRef","onChapterChange","onFullWidthChange","ref","viewerRef","bookRef","renditionRef","onChapterChangeRef","onFullWidthChangeRef","totalLocationsRef","lastCfiRef","isFullWidthRef","isFullWidth","setIsFullWidth","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","tocRef","handlePrev","handleNext","scrollContainerRef","scrollRafRef","onScrollRef","_e","mgr","reattachScrollListener","tryAttach","toggleFullWidth","newVal","viewer","rendition","toggleToc","handleTocClick","href","useImperativeHandle","loadTimer","load","bookInput","book","ePub","loc","cur","_c","nav","location","spineHref","matches","collect","items","base","_d","onResize","isActive","renderTocItems","depth","active","READER_CSS","hostRef","viewRef","reportProgress","view","host","detail","sections","idx","frac","tocItem","res","blob","_f","getVideoType","isLoading","setIsLoading","videoRef","playerRef","videoElement","videoType","player","videojs","videoEl","useAudioPlayer","audioRef","isPlaying","setIsPlaying","currentTime","setCurrentTime","duration","setDuration","volume","setVolumeState","isMuted","setIsMuted","isLoop","setIsLoop","audio","onTimeUpdate","onDurationChange","onCanPlay","onWaiting","onPlaying","onPlay","onPause","onEnded","onError","togglePlay","seek","time","skip","seconds","setVolume","vol","clamped","toggleMute","toggleLoop","next","formatTime","minutes","MarqueeText","text","innerRef","overflow","setOverflow","scrollDist","setScrollDist","check","inner","cw","tw","observer","gap","totalScroll","dur","Tonearm","showVolume","setShowVolume","volumeRef","volumeTimerRef","progress","handleClickOutside","handleVolumeEnter","handleVolumeLeave","VolumeIcon","VolumeX","Volume1","Volume2","Repeat","SkipBack","Pause","Play","SkipForward","useShikiHighlight","code","lang","codeToHtml","out","useCopy","copied","setCopied","handleCopy","textarea","InlineCopyButton","Check","Copy","FloatingCopyButton","ShikiCodeBlock","viewMode","content","setContent","sourceHtml","fetchTextUtf8","ReactMarkdown","remarkGfm","remarkMath","rehypeRaw","rehypeKatex","node","inline","match","codeString","src","alt","checked","DARK_COLORS","LIGHT_COLORS","JsonNode","keyName","defaultExpanded","colors","expanded","setExpanded","indent","toggle","renderPrimitive","isArray","openBracket","closeBracket","ChevronDown","pickColors","data","setData","loadCsv","parsed","parseCsv","guessCsvDelimiter","convertCsvToSpreadsheetData","prettyPrintXml","xml","doc","serialized","indentXml","PADDING","reg","formatted","pad","line","padded","highlighted","raw","FORMAT_BY_EXT","getFormat","setText","parseSubtitle","isLyric","meta","dotHover","cue","formatSubtitleTime","word","wi","ResizableSplit","left","right","initialLeftWidth","minLeftWidth","maxLeftWidth","minRightWidth","storageKey","desktopMedia","leftWidth","setLeftWidth","saved","dragging","setDragging","isDesktop","setIsDesktop","mq","handleMove","cap","effectiveMax","newW","handleUp","prevCursor","prevSelect","handleDividerDown","LazyFilePreviewContent","FilePreviewContent$1","resolveIcon","FileImage","FileText","FileCode","FileIcon","TreeItem","selectedPath","onToggle","onSelect","onHover","onLeave","isSelected","handleEnter","FolderOpen","Folder","Icon","nestingDepth","onStatsChange","zip","setZip","tree","setTree","selected","setSelected","previewLoading","setPreviewLoading","previewError","setPreviewError","hoverTip","setHoverTip","onStatsChangeRef","buf","loadZip","entries","listZipEntries","root","buildZipTree","totalStats","dirs","walk","handleToggle","path","handleHover","handleLeave","handleSelect","mime","inferMimeType","readZipEntryBlob","leftPane","rightPane","wordWrap","htmlPreview","language","getLanguageFromFileName"],"mappings":"osBACA,SAASA,GAAEC,EAAG,CACZ,GAAI,CACF,MAAMC,EAAI,IAAI,IAAID,CAAC,EAAE,SAAS,MAAM,GAAG,EAAE,IAAG,GAAM,OAClD,OAAO,mBAAmBC,CAAC,CAC7B,MAAQ,CACN,MAAM,EAAID,EAAE,MAAM,GAAG,EAAE,IAAG,GAAM,OAChC,OAAO,mBAAmB,CAAC,CAC7B,CACF,CACA,SAASE,GAAEF,EAAG,CACZ,IAAIC,EACJ,MAAME,IAAMF,EAAID,EAAE,MAAM,GAAG,EAAE,IAAG,IAAO,KAAO,OAASC,EAAE,YAAW,IAAO,GAC3E,MAAO,CAEL,IAAK,aACL,KAAM,aACN,IAAK,YACL,IAAK,YACL,KAAM,aACN,IAAK,gBACL,IAAK,YACL,IAAK,eAEL,IAAK,YACL,KAAM,aACN,IAAK,YACL,IAAK,YACL,IAAK,kBACL,IAAK,kBACL,IAAK,mBACL,IAAK,cACL,MAAO,aACP,IAAK,cAEL,IAAK,aACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,KAAM,aAEN,IAAK,kBACL,KAAM,0EACN,KAAM,oEACN,KAAM,4EACN,IAAK,gCACL,IAAK,6BACL,KAAM,iCACN,IAAK,+BACL,KAAM,+BACN,IAAK,+BAEL,IAAK,aACL,GAAI,gBACJ,SAAU,gBACV,KAAM,mBACN,IAAK,kBACL,KAAM,YACN,IAAK,WACL,GAAI,kBACJ,GAAI,kBACJ,IAAK,kBACL,IAAK,kBACL,GAAI,gBACJ,KAAM,cACN,IAAK,gBACL,EAAG,cACH,GAAI,gBACJ,IAAK,aACL,GAAI,cACJ,GAAI,YACJ,GAAI,cACJ,KAAM,YACN,IAAK,YACL,KAAM,YACN,IAAK,aACL,IAAK,aACL,KAAM,cACN,MAAO,cACP,IAAK,aACL,IAAK,WACL,IAAK,4BACL,IAAK,uBACL,IAAK,WACL,IAAK,iBACT,EAAIE,CAAC,GAAK,0BACV,CACA,SAASC,GAAEJ,EAAG,EAAI,EAAG,CACnB,GAAIA,aAAa,KACf,MAAO,CACL,GAAI,QAAQ,KAAK,IAAG,CAAE,IAAI,CAAC,GAC3B,KAAMA,EAAE,KACR,IAAK,IAAI,gBAAgBA,CAAC,EAC1B,KAAMA,EAAE,MAAQE,GAAEF,EAAE,IAAI,EACxB,KAAMA,EAAE,IACd,EACE,GAAI,OAAOA,GAAK,SAAU,CACxB,MAAMK,EAAIN,GAAEC,CAAC,EACb,MAAO,CACL,GAAI,OAAO,KAAK,IAAG,CAAE,IAAI,CAAC,GAC1B,KAAMK,EACN,IAAKL,EACL,KAAME,GAAEG,CAAC,CACf,CACE,CACA,MAAO,CACL,GAAIL,EAAE,IAAM,QAAQ,KAAK,IAAG,CAAE,IAAI,CAAC,GACnC,KAAMA,EAAE,KACR,IAAKA,EAAE,IACP,KAAMA,EAAE,MAAQE,GAAEF,EAAE,IAAI,EACxB,KAAMA,EAAE,IACZ,CACA,CACA,SAASM,GAAGN,EAAG,CACb,OAAOA,EAAE,IAAI,CAAC,EAAGK,IAAMD,GAAE,EAAGC,CAAC,CAAC,CAChC,CACA,SAASE,GAAGP,EAAG,CACb,IAAIQ,EACJ,MAAML,IAAMK,EAAIR,EAAE,KAAK,MAAM,GAAG,EAAE,IAAG,IAAO,KAAO,OAASQ,EAAE,YAAW,IAAO,GAAIH,EAAIL,EAAE,KAAK,YAAW,EAC1G,GAAIK,EAAE,WAAW,QAAQ,GAAK,CAAC,MAAO,OAAQ,MAAO,MAAO,OAAQ,KAAK,EAAE,SAASF,CAAC,EACnF,MAAO,QACT,GAAIE,EAAE,SAAS,KAAK,GAAKF,IAAM,MAC7B,MAAO,MACT,GAAIE,EAAE,SAAS,kBAAkB,GAAKF,IAAM,OAC1C,MAAO,OACT,GAAIE,EAAE,SAAS,eAAe,GAAKF,IAAM,OACvC,MAAO,OACT,GAAIE,EAAE,SAAS,gBAAgB,GAAKF,IAAM,QAAUA,IAAM,MACxD,MAAO,OACT,GAAIE,EAAE,SAAS,YAAY,GAAKF,IAAM,MACpC,MAAO,MACT,GAAIE,EAAE,SAAS,MAAM,GAAKF,IAAM,OAC9B,MAAO,OACT,GAAI,CAAC,OAAQ,MAAO,OAAQ,KAAK,EAAE,SAASA,CAAC,GAAKE,IAAM,kCAAoCA,IAAM,+BAChG,MAAO,OACT,GAAI,CAAC,MAAO,KAAK,EAAE,SAASF,CAAC,GAAKE,IAAM,YAAcA,IAAM,4BAC1D,MAAO,MACT,GAAIF,IAAM,OAASE,IAAM,mBAAqBA,IAAM,WAClD,MAAO,MACT,GAAI,CAAC,MAAO,MAAO,MAAO,OAAQ,MAAO,MAAO,OAAQ,MAAM,EAAE,SAASF,CAAC,GAAKE,IAAM,YAAcA,IAAM,wBAA0BA,IAAM,uBACvI,MAAO,WACT,GAAIF,IAAM,OAASE,IAAM,mBAAqBA,IAAM,+BAClD,MAAO,MACT,GAAIA,EAAE,WAAW,QAAQ,GAAK,CAAC,MAAO,OAAQ,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAK,EAAE,SAASF,CAAC,EAC9G,MAAO,QACT,GAAIE,EAAE,WAAW,QAAQ,GAAK,CAAC,MAAO,MAAO,MAAO,MAAO,OAAQ,KAAK,EAAE,SAASF,CAAC,EAClF,MAAO,QACT,GAAIA,IAAM,MAAQA,IAAM,WACtB,MAAO,WACT,GAAIE,IAAM,oBAAsBF,IAAM,OACpC,MAAO,OACT,MAAMF,EAAI,CACR,MACA,MACA,OACA,KACA,MACA,KACA,MACA,KACA,OACA,MACA,IACA,IACA,KACA,MACA,KACA,KACA,MACA,KACA,QACA,KACA,MACA,MACA,OACA,MACA,OACA,OACA,OACA,OACA,MACA,OACA,MACA,OACA,MACA,OACA,QACA,KACA,OACA,MACA,KACJ,EACE,OAAOI,EAAE,WAAW,OAAO,GAAKJ,EAAE,SAASE,CAAC,EAAI,OAAS,aAC3D,CACA,SAASM,GAAGT,EAAG,CACb,IAAIC,EACJ,MAAME,IAAMF,EAAID,EAAE,MAAM,GAAG,EAAE,IAAG,IAAO,KAAO,OAASC,EAAE,YAAW,IAAO,GAC3E,MAAO,CACL,GAAI,aACJ,IAAK,MACL,GAAI,aACJ,IAAK,MACL,GAAI,SACJ,KAAM,OACN,IAAK,MACL,EAAG,IACH,GAAI,SACJ,IAAK,MACL,GAAI,OACJ,GAAI,KACJ,IAAK,KACL,GAAI,OACJ,MAAO,QACP,GAAI,SACJ,IAAK,MACL,IAAK,MACL,MAAO,QACP,GAAI,OACJ,KAAM,OACN,IAAK,OACL,KAAM,OACN,IAAK,MACL,KAAM,OACN,IAAK,MACL,KAAM,OACN,KAAM,OACN,KAAM,OACN,IAAK,MACL,KAAM,OACN,IAAK,OACL,KAAM,OACN,IAAK,MACL,IAAK,OACL,KAAM,QACN,KAAM,OACN,MAAO,OACP,IAAK,MACL,GAAI,WACJ,IAAK,MACT,EAAIE,CAAC,GAAK,MACV,CAiBA,SAASO,GAAGV,EAAG,CACb,OAAOA,EAAI,KAAO,GAAGA,CAAC,KAAOA,EAAI,KAAO,KAAO,IAAIA,EAAI,MAAM,QAAQ,CAAC,CAAC,MAAQ,IAAIA,GAAK,KAAO,OAAO,QAAQ,CAAC,CAAC,KAClH,CAMA,SAASW,GAAGX,EAAG,CACb,IAAIK,EACJ,SAAUA,EAAIL,EAAE,MAAM,GAAG,EAAE,IAAG,IAAO,KAAO,OAASK,EAAE,YAAW,IAAO,MAAQ,MAAQ,IAAM,GACjG,CACA,SAASO,GAAGZ,EAAG,EAAI,GAAI,CACrB,MAAMK,EAAI,EAAE,WAAa,IAAKJ,EAAI,EAAE,kBAAoB,GAAIO,EAAI,CAAA,EAChE,IAAIK,EAAI,CAAA,EAAIC,EAAI,GAAI,EAAI,GAAIC,EAAI,EAChC,MAAMC,EAAIhB,EAAE,OACZ,KAAOe,EAAIC,GAAK,CACd,MAAMC,EAAIjB,EAAEe,CAAC,EACb,GAAI,EAAG,CACL,GAAIE,IAAM,IAAK,CACb,GAAIjB,EAAEe,EAAI,CAAC,IAAM,IAAK,CACpBD,GAAK,IAAKC,GAAK,EACf,QACF,CACA,EAAI,GAAIA,GAAK,EACb,QACF,CACAD,GAAKG,EAAGF,GAAK,EACb,QACF,CACA,GAAIE,IAAM,IAAK,CACb,EAAI,GAAIF,GAAK,EACb,QACF,CACA,GAAIE,IAAMZ,EAAG,CACXQ,EAAE,KAAKC,CAAC,EAAGA,EAAI,GAAIC,GAAK,EACxB,QACF,CACA,GAAIE,IAAM,KAAM,CACdjB,EAAEe,EAAI,CAAC,IAAM;AAAA,IACbA,GAAK,GAAIF,EAAE,KAAKC,CAAC,EAAGN,EAAE,KAAKK,CAAC,EAAGA,EAAI,CAAA,EAAIC,EAAI,GAAIC,GAAK,EACpD,QACF,CACA,GAAIE,IAAM;AAAA,EACX,CACGJ,EAAE,KAAKC,CAAC,EAAGN,EAAE,KAAKK,CAAC,EAAGA,EAAI,CAAA,EAAIC,EAAI,GAAIC,GAAK,EAC3C,QACF,CACAD,GAAKG,EAAGF,GAAK,CACf,CACA,KAAMD,EAAE,OAAS,GAAKD,EAAE,OAAS,KAAOA,EAAE,KAAKC,CAAC,EAAGN,EAAE,KAAKK,CAAC,GAAIL,EAAE,OAAS,GAAK,CAC7E,MAAMS,EAAIT,EAAEA,EAAE,OAAS,CAAC,EACxB,GAAIS,EAAE,SAAW,GAAKA,EAAE,CAAC,IAAM,GAC7BT,EAAE,IAAG,MAEL,MACJ,CACA,IAAI,EAAI,GAAIU,EAAIV,EAChBP,GAAKO,EAAE,OAAS,IAAM,EAAIA,EAAE,CAAC,EAAGU,EAAIV,EAAE,MAAM,CAAC,GAC7C,MAAMW,EAAI,KAAK,IACb,EAAE,OACF,GAAGD,EAAE,IAAKD,GAAMA,EAAE,MAAM,EACxB,CACJ,EACE,UAAWA,KAAKC,EACd,KAAOD,EAAE,OAASE,GAAKF,EAAE,KAAK,EAAE,EAClC,MAAO,CACL,OAAQ,EACR,KAAMC,EACN,YAAaC,EACb,UAAWd,CACf,CACA,CACA,SAASe,GAAEpB,EAAG,CACZ,MAAM,EAAIA,aAAa,WAAaA,EAAI,IAAI,WAAWA,CAAC,EACxD,GAAI,EAAE,QAAU,GAAK,EAAE,CAAC,IAAM,KAAO,EAAE,CAAC,IAAM,KAAO,EAAE,CAAC,IAAM,IAC5D,OAAO,IAAI,YAAY,OAAO,EAAE,OAAO,CAAC,EAC1C,GAAI,EAAE,QAAU,GAAK,EAAE,CAAC,IAAM,KAAO,EAAE,CAAC,IAAM,IAC5C,OAAO,IAAI,YAAY,UAAU,EAAE,OAAO,CAAC,EAC7C,GAAI,EAAE,QAAU,GAAK,EAAE,CAAC,IAAM,KAAO,EAAE,CAAC,IAAM,IAC5C,OAAO,IAAI,YAAY,UAAU,EAAE,OAAO,CAAC,EAC7C,GAAI,CACF,OAAO,IAAI,YAAY,QAAS,CAAE,MAAO,EAAE,CAAE,EAAE,OAAO,CAAC,CACzD,MAAQ,CACR,CACA,GAAI,CACF,OAAO,IAAI,YAAY,KAAK,EAAE,OAAO,CAAC,CACxC,MAAQ,CACR,CACA,OAAO,IAAI,YAAY,QAAS,CAAE,MAAO,GAAI,EAAE,OAAO,CAAC,CACzD,CAEA,eAAeqB,GAAGrB,EAAG,EAAG,CACtB,MAAMK,EAAI,CAAC,CAAC,IAAM,YAAa,GAAK,SAAU,GAAIJ,EAAII,EAAI,EAAE,SAAW,MAAQ,MAAOG,EAAIH,EAAI,EAAE,KAAO,EAAGQ,EAAI,MAAMZ,EAAED,EAAGQ,CAAC,EAC1H,GAAI,CAACK,EAAE,GAAI,MAAM,IAAI,MAAM,SAASA,EAAE,MAAM,EAAE,EAC9C,MAAMC,EAAI,MAAMD,EAAE,YAAW,EAC7B,OAAOO,GAAEN,CAAC,CACZ,CACA,eAAeQ,GAAEtB,EAAG,EAAG,CACrB,GAAIA,EACF,OAAO,OAAOA,GAAK,WAAa,MAAMA,EAAE,CAAC,EAAIA,CACjD,CACA,SAASuB,GAAEvB,EAAG,EAAG,CACf,GAAI,CAACA,GAAK,CAAC,EAAG,OACd,GAAI,CAACA,EAAG,OAAO,EACf,GAAI,CAAC,EAAG,OAAOA,EACf,MAAMK,EAAI,IAAI,QAAQL,EAAE,SAAW,CAAA,CAAE,EACrC,OAAO,EAAE,SAAW,IAAI,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAACC,EAAGO,IAAM,CAC3DH,EAAE,IAAIG,EAAGP,CAAC,CACZ,CAAC,EAAG,CACF,GAAGD,EACH,GAAG,EACH,QAASK,CACb,CACA,CACA,SAASmB,GAAGxB,EAAG,CACb,MAAM,GAAKA,GAAK,KAAO,OAASA,EAAE,kBAAoB,CAACC,EAAGO,IAAM,MAAMP,EAAGO,CAAC,GAAIH,EAAIL,GAAK,KAAO,OAASA,EAAE,YACzG,MAAO,OAAOC,EAAGO,IAAM,CACrB,MAAMK,EAAI,MAAMS,GAAEjB,EAAGJ,CAAC,EAAGa,EAAIS,GAAEV,EAAGL,CAAC,EACnC,OAAO,EAAEP,EAAGa,CAAC,CACf,CACF,CACA,eAAeW,GAAGzB,EAAG,EAAI,MAAOK,EAAG,CACjC,MAAMJ,EAAI,MAAM,EAAED,EAAGK,CAAC,EACtB,GAAI,CAACJ,EAAE,GAAI,MAAM,IAAI,MAAM,SAASA,EAAE,MAAM,EAAE,EAC9C,MAAMO,EAAI,MAAMP,EAAE,KAAI,EACtB,OAAO,IAAI,gBAAgBO,CAAC,CAC9B,CACA,eAAekB,GAAG1B,EAAG,EAAGK,EAAI,MAAOJ,EAAG,CACpC,MAAMO,EAAI,MAAMH,EAAEL,EAAGC,CAAC,EACtB,GAAI,CAACO,EAAE,GAAI,MAAM,IAAI,MAAM,SAASA,EAAE,MAAM,EAAE,EAC9C,MAAMK,EAAI,MAAML,EAAE,KAAI,EAAIM,EAAI,IAAI,gBAAgBD,CAAC,EACnD,GAAI,CACF,MAAM,EAAI,SAAS,cAAc,GAAG,EACpC,EAAE,KAAOC,EAAG,EAAE,SAAW,EAAG,EAAE,MAAM,QAAU,OAAQ,SAAS,KAAK,YAAY,CAAC,EAAG,EAAE,MAAK,EAAI,SAAS,KAAK,YAAY,CAAC,CAC5H,QAAC,CACC,WAAW,IAAM,IAAI,gBAAgBA,CAAC,EAAG,GAAG,CAC9C,CACF,CACA,SAASa,GAAE3B,EAAG,CACZ,MAAM,EAAIA,EAAE,KAAI,EAAG,QAAQ,IAAK,GAAG,EAAGK,EAAI,EAAE,MAAM,GAAG,EAAE,IAAKJ,GAAMA,EAAE,MAAM,EAC1E,GAAII,EAAE,SAAW,EAAG,CAClB,KAAM,CAACJ,EAAGO,EAAGK,CAAC,EAAIR,EAClB,OAAO,OAAOJ,CAAC,EAAI,KAAO,OAAOO,CAAC,EAAI,GAAK,OAAOK,CAAC,CACrD,CACA,GAAIR,EAAE,SAAW,EAAG,CAClB,KAAM,CAACJ,EAAGO,CAAC,EAAIH,EACf,OAAO,OAAOJ,CAAC,EAAI,GAAK,OAAOO,CAAC,CAClC,CACA,OAAO,OAAO,CAAC,GAAK,CACtB,CACA,SAASoB,GAAG5B,EAAG,CACb,GAAI,CAAC,SAASA,CAAC,GAAKA,EAAI,EAAG,MAAO,eAClC,MAAM,EAAI,KAAK,MAAMA,EAAI,GAAG,EAAGK,EAAI,EAAI,IAAKJ,EAAI,KAAK,MAAM,EAAI,GAAG,EAAI,GAAIO,EAAI,KAAK,MAAM,EAAI,GAAG,EAAI,GAAIK,EAAI,KAAK,MAAM,EAAI,IAAI,EAAGC,EAAI,CAAC,EAAGC,EAAI,IAAM,EAAE,SAAQ,EAAG,SAASA,EAAG,GAAG,EAChL,MAAO,GAAGD,EAAED,CAAC,CAAC,IAAIC,EAAEN,CAAC,CAAC,IAAIM,EAAEb,CAAC,CAAC,IAAIa,EAAET,EAAG,CAAC,CAAC,EAC3C,CACA,MAAMwB,GAAI,sFAAuFC,GAAI,0CACrG,SAASC,GAAE/B,EAAG,CACZ,MAAM,EAAIA,EAAE,QAAQ,UAAW,EAAE,EAAE,UAAS,EAC5C,MAAO,UAAU,KAAK,CAAC,EAAI,MAAQ,WAAW,KAAK,CAAC,GAAK,eAAe,KAAK,CAAC,EAAI,OAAS,qBAAqB,KAAK,CAAC,GAAK,cAAc,KAAK,CAAC,EAAI,6BAA6B,KAAK,CAAC,EAAI,MAAQ,MAAQ8B,GAAE,KAAK,CAAC,GAAK,6CAA6C,KAAK,CAAC,EAAI,oCAAoC,KAAK,CAAC,EAAI,OAAS,MAAQ,KAC/U,CACA,SAASE,GAAEhC,EAAG,EAAG,CACf,MAAM,EAAIA,EAAE,QAAQ,SAAU;AAAA,CAC/B,EAAE,QAAQ,UAAW,EAAE,EAAE,MAAM;AAAA,CAC/B,EAAGQ,EAAI,CAAA,EACN,IAAIK,EAAG,EAAI,EACX,GAAI,IAAM,MAAO,CACf,MAAMoB,EAAI,CAAA,EACV,KAAO,EAAI,EAAE,QAAU,EAAE,CAAC,EAAE,KAAI,IAAO,IACrCA,EAAE,KAAK,EAAE,CAAC,CAAC,EAAG,IAChB,IAAKpB,EAAIoB,EAAE,KAAK;AAAA,CACnB,EAAG,EAAI,EAAE,QAAU,EAAE,CAAC,EAAE,KAAI,IAAO,IAAM,GACxC,CACA,KAAO,EAAI,EAAE,QAAU,CACrB,KAAO,EAAI,EAAE,QAAU,EAAE,CAAC,EAAE,KAAI,IAAO,IAAM,IAC7C,GAAI,GAAK,EAAE,OAAQ,MACnB,IAAIA,EAAGlB,EAAI,KACX,GAAIc,GAAE,KAAK,EAAE,CAAC,CAAC,EACbd,EAAI,EAAE,CAAC,EAAG,YACHkB,EAAI,EAAE,CAAC,EAAE,KAAI,GAAM,OAAQ,IAAK,EAAI,EAAE,QAAUJ,GAAE,KAAK,EAAE,CAAC,CAAC,EAClEd,EAAI,EAAE,CAAC,EAAG,QAEV,UACF,GAAI,CAACA,EAAG,SACR,MAAMC,EAAID,EAAE,MAAM,+BAA+B,EACjD,GAAI,CAACC,EAAG,SACR,MAAMkB,EAAIP,GAAEX,EAAE,CAAC,CAAC,EAAGE,EAAIS,GAAEX,EAAE,CAAC,CAAC,EAAGG,EAAI,CAAA,EACpC,KAAO,EAAI,EAAE,QAAU,EAAE,CAAC,EAAE,KAAI,IAAO,IACrCA,EAAE,KAAK,EAAE,CAAC,CAAC,EAAG,IAChBX,EAAE,KAAK,CAAE,GAAIyB,EAAG,MAAOC,EAAG,IAAKhB,EAAG,KAAMC,EAAE,KAAK;AAAA,CAClD,EAAG,CACF,CACA,MAAO,CAAE,OAAQ,EAAG,KAAMX,EAAG,OAAQK,CAAC,CACxC,CACA,SAASsB,GAAEnC,EAAG,EAAGK,EAAG,CAClB,MAAMJ,EAAI,OAAOD,CAAC,EAAGQ,EAAI,OAAO,CAAC,EACjC,IAAIK,EAAI,EACR,GAAIR,EAAG,CACL,MAAMS,GAAKT,EAAI,OAAO,MAAM,EAAG,CAAC,EAChCQ,EAAI,OAAOC,CAAC,CACd,CACA,OAAOb,EAAI,GAAKO,EAAIK,EAAI,GAC1B,CACA,SAASuB,GAAEpC,EAAG,EAAG,CACf,MAAMK,EAAI,mDAAmD,KAAKL,EAAE,KAAI,CAAE,EAC1E,GAAI,CAACK,EAAG,MAAO,GACf,MAAMJ,EAAII,EAAE,CAAC,EAAE,cAAeG,EAAIH,EAAE,CAAC,EAAE,KAAI,EAC3C,GAAI,EAAE,SAASJ,CAAC,EAAIO,EAAGP,IAAM,SAAU,CACrC,MAAMY,EAAI,OAAOL,CAAC,EAClB,MAAMK,CAAC,IAAM,EAAE,SAAWA,EAC5B,CACA,MAAO,EACT,CACA,SAASwB,GAAErC,EAAG,CACZ,MAAMK,EAAIL,EAAE,QAAQ,SAAU;AAAA,CAC/B,EAAE,QAAQ,UAAW,EAAE,EAAE,MAAM;AAAA,CAC/B,EAAG,EAAI,CAAE,SAAU,GAAI,SAAU,CAAC,EAAIQ,EAAI,6CAA8CK,EAAI,CAAA,EAC3F,UAAWE,KAAKV,EAAG,CACjB,MAAMW,EAAID,EAAE,KAAI,EAChB,GAAI,CAACC,GAAKoB,GAAEpB,EAAG,CAAC,EAAG,SACnB,MAAMkB,EAAI,CAAA,EACV,IAAIhB,EAAI,EACRV,EAAE,UAAY,EACd,IAAIW,EACJ,MAAQA,EAAIX,EAAE,KAAKQ,CAAC,KAAO,MAAQG,EAAE,QAAUD,GAC7CgB,EAAE,KAAKC,GAAEhB,EAAE,CAAC,EAAGA,EAAE,CAAC,EAAGA,EAAE,CAAC,CAAC,CAAC,EAAGD,EAAIC,EAAE,MAAQA,EAAE,CAAC,EAAE,OAClD,GAAIe,EAAE,SAAW,EAAG,SACpB,MAAMjB,EAAID,EAAE,MAAME,CAAC,EAAE,KAAI,EACzB,UAAW,KAAKgB,EACdrB,EAAE,KAAK,CAAE,MAAO,EAAG,KAAMI,EAAG,CAChC,CACAJ,EAAE,KAAK,CAACE,EAAGC,IAAMD,EAAE,MAAQC,EAAE,KAAK,EAClC,MAAM,EAAI,EAAE,SAAW,IACvB,MAAO,CAAE,OAAQ,MAAO,KAAMH,EAAE,IAAI,CAACE,EAAGC,IAAM,CAC5C,MAAMkB,EAAI,KAAK,IAAI,EAAGnB,EAAE,MAAQ,CAAC,EAAGG,EAAIL,EAAEG,EAAI,CAAC,EAAGG,EAAID,EAAI,KAAK,IAAIgB,EAAGhB,EAAE,MAAQ,CAAC,EAAIgB,EAAI,EACzF,MAAO,CAAE,MAAOA,EAAG,IAAKf,EAAG,KAAMJ,EAAE,IAAI,CACzC,CAAC,EAAG,SAAU,EAAE,QAAQ,CAC1B,CACA,SAASuB,GAAEtC,EAAG,CACZ,MAAMK,EAAIL,EAAE,QAAQ,SAAU;AAAA,CAC/B,EAAE,QAAQ,UAAW,EAAE,EAAE,MAAM;AAAA,CAC/B,EAAG,EAAI,CAAE,SAAU,CAAA,EAAI,SAAU,GAAKQ,EAAI,6CAA8CK,EAAI,2CAA4C,EAAI,CAAA,EAC3I,UAAWG,KAAKX,EAAG,CACjB,MAAM6B,EAAIlB,EAAE,KAAI,EAChB,GAAI,CAACkB,GAAKE,GAAEF,EAAG,CAAC,EAAG,SACnB,MAAMhB,EAAI,CAAA,EACV,IAAIC,EAAI,EACRX,EAAE,UAAY,EACd,IAAIS,EACJ,MAAQA,EAAIT,EAAE,KAAK0B,CAAC,KAAO,MAAQjB,EAAE,QAAUE,GAC7CD,EAAE,KAAKiB,GAAElB,EAAE,CAAC,EAAGA,EAAE,CAAC,EAAGA,EAAE,CAAC,CAAC,CAAC,EAAGE,EAAIF,EAAE,MAAQA,EAAE,CAAC,EAAE,OAClD,GAAIC,EAAE,SAAW,EAAG,SACpB,MAAM,EAAIgB,EAAE,MAAMf,CAAC,EACnB,UAAW,KAAKD,EACd,EAAE,KAAK,CAAE,MAAO,EAAG,IAAK,EAAG,CAC/B,CACA,EAAE,KAAK,CAACF,EAAGkB,IAAMlB,EAAE,MAAQkB,EAAE,KAAK,EAClC,MAAMD,EAAI,EAAE,SAAW,IACvB,MAAO,CAAE,OAAQ,OAAQ,KAAM,EAAE,IAAI,CAACjB,EAAGkB,IAAM,CAC7C,MAAMhB,EAAI,CAAA,EACV,IAAIC,EAAI,GAAIF,EAAI,EAAG,EAAI,KACvBJ,EAAE,UAAY,EACd,IAAI,EACJ,MAAQ,EAAIA,EAAE,KAAKG,EAAE,GAAG,KAAO,MAAQ,CACrC,MAAMuB,EAAIvB,EAAE,IAAI,MAAMC,EAAG,EAAE,KAAK,EAChC,IAAM,MAAQsB,GAAKrB,EAAE,KAAK,CAAE,MAAO,KAAK,IAAI,EAAG,EAAIe,CAAC,EAAG,KAAMM,CAAC,CAAE,EAAGpB,GAAKoB,EAAG,EAAIJ,GAAE,EAAE,CAAC,EAAG,EAAE,CAAC,EAAG,EAAE,CAAC,CAAC,EAAGlB,EAAI,EAAE,MAAQ,EAAE,CAAC,EAAE,MACzH,CACA,MAAMuB,EAAIxB,EAAE,IAAI,MAAMC,CAAC,EACvB,IAAM,MAAQuB,GAAKtB,EAAE,KAAK,CAAE,MAAO,KAAK,IAAI,EAAG,EAAIe,CAAC,EAAG,KAAMO,CAAC,CAAE,EAAGrB,GAAKqB,EACxE,MAAMC,EAAI,KAAK,IAAI,EAAGzB,EAAE,MAAQiB,CAAC,EAAGS,EAAI,EAAER,EAAI,CAAC,EAAGS,EAAID,EAAI,KAAK,IAAID,EAAGC,EAAE,MAAQT,CAAC,EAAIQ,EAAI,EACzF,MAAO,CACL,MAAOA,EACP,IAAKE,EACL,KAAMxB,EAAE,KAAI,EACZ,MAAOD,EAAE,OAASA,EAAI,MAC5B,CACE,CAAC,EAAG,SAAU,EAAE,QAAQ,CAC1B,CACA,SAAS0B,GAAE5C,EAAG,CACZ,MAAM,EAAIA,EAAE,KAAI,EAAG,MAAM,GAAG,EAC5B,OAAO,EAAE,SAAW,EAAI,EAAI,OAAO,EAAE,CAAC,CAAC,EAAI,KAAO,OAAO,EAAE,CAAC,CAAC,EAAI,GAAK,OAAO,EAAE,CAAC,EAAE,QAAQ,IAAK,GAAG,CAAC,CACrG,CACA,SAAS6C,GAAE7C,EAAG,EAAG,CACf,MAAM,EAAIA,EAAE,QAAQ,SAAU;AAAA,CAC/B,EAAE,QAAQ,UAAW,EAAE,EAAE,MAAM;AAAA,CAC/B,EACC,IAAIQ,EAAI,GAAIK,EAAI,CAAA,EAChB,MAAM,EAAI,GAAIoB,EAAI,CAAA,EAClB,UAAWlB,KAAK,EAAG,CACjB,MAAMC,EAAID,EAAE,QAAQ,OAAQ,EAAE,EAAGmB,EAAIlB,EAAE,KAAI,EAAIE,EAAI,oBAAoB,KAAKgB,CAAC,EAC7E,GAAIhB,EAAG,CACLV,EAAIU,EAAE,CAAC,EAAE,YAAW,EAAIe,EAAE,KAAKjB,CAAC,EAChC,QACF,CACA,GAAIR,IAAM,SAAU,CAClByB,EAAE,KAAKjB,CAAC,EACR,QACF,CACA,MAAMG,EAAI,oBAAoB,KAAKe,CAAC,EACpC,GAAIf,EAAG,CACLN,EAAIM,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,IAAK2B,GAAMA,EAAE,KAAI,CAAE,EACvC,QACF,CACA,MAAM7B,EAAI,gCAAgC,KAAKiB,CAAC,EAChD,GAAI,CAACjB,GAAKA,EAAE,CAAC,EAAE,YAAW,IAAO,WAAaJ,EAAE,SAAW,EAAG,SAC9D,MAAMkC,EAAIlC,EAAE,OAAQmC,EAAI/B,EAAE,CAAC,EAAE,MAAM,GAAG,EAAGuB,EAAIQ,EAAE,MAAM,EAAGD,EAAI,CAAC,EAAGN,EAAIO,EAAE,MAAMD,EAAI,CAAC,EAAE,KAAK,GAAG,EAAGL,EAAI,CAAA,EAClG7B,EAAE,QAAQ,CAACiC,EAAGG,IAAM,CAClBP,EAAEI,CAAC,EAAIG,IAAMF,EAAI,EAAIN,EAAID,EAAES,CAAC,GAAK,EACnC,CAAC,EACD,MAAMN,EAAIC,GAAEF,EAAE,OAAS,EAAE,EAAGH,EAAIK,GAAEF,EAAE,KAAO,EAAE,EAAGQ,GAAKR,EAAE,MAAQ,IAAI,QAAQ,OAAQ;AAAA,CACtF,EAAE,QAAQ,OAAQ;AAAA,CAClB,EAAE,QAAQ,OAAQ,GAAG,EAAE,QAAQ,aAAc,EAAE,EAC5C,EAAE,KAAK,CAAE,MAAOC,EAAG,IAAKJ,EAAG,KAAMW,EAAG,MAAOR,EAAE,KAAK,CAAE,CACtD,CACA,OAAO,EAAE,KAAK,CAAC3B,EAAGC,IAAMD,EAAE,MAAQC,EAAE,KAAK,EAAG,CAC1C,OAAQ,EACR,KAAM,EACN,OAAQiB,EAAE,KAAK;AAAA,CAClB,EAAE,KAAI,GAAM,MACb,CACA,CACA,SAASkB,GAAEnD,EAAG,CACZ,MAAM,EAAIA,EAAE,KAAI,EAChB,GAAI,CAAC,EAAG,MAAO,GACf,MAAMK,EAAI,mCAAmC,KAAK,CAAC,EACnD,GAAIA,EAAG,CACL,MAAMG,EAAI,OAAOH,EAAE,CAAC,CAAC,EAAGQ,EAAIR,EAAE,CAAC,EAAE,YAAW,EAC5C,OAAOQ,IAAM,IAAML,EAAI,KAAOK,IAAM,IAAML,EAAI,GAAKK,IAAM,KAAOL,EAAI,IAAMA,CAC5E,CACA,MAAMP,EAAI,EAAE,MAAM,GAAG,EACrB,OAAOA,EAAE,SAAW,EAAI,OAAOA,EAAE,CAAC,CAAC,EAAI,KAAO,OAAOA,EAAE,CAAC,CAAC,EAAI,GAAK,OAAOA,EAAE,CAAC,CAAC,EAAIA,EAAE,SAAW,EAAI,OAAOA,EAAE,CAAC,CAAC,EAAI,GAAK,OAAOA,EAAE,CAAC,CAAC,EAAI,OAAO,CAAC,GAAK,CACpJ,CACA,SAASmD,GAAEpD,EAAG,CACZ,GAAI,OAAO,UAAY,IACrB,MAAM,IAAI,MAAM,+CAA+C,EACjE,MAAM,EAAI,IAAI,UAAS,EAAG,gBAAgBA,EAAG,iBAAiB,EAC9D,GAAI,EAAE,qBAAqB,aAAa,EAAE,OAAS,EACjD,MAAM,IAAI,MAAM,sBAAsB,EACxC,MAAM,EAAI,EAAE,qBAAqB,GAAG,EAAGQ,EAAI,CAAA,EAC3C,QAASK,EAAI,EAAGA,EAAI,EAAE,OAAQA,IAAK,CACjC,MAAM,EAAI,EAAEA,CAAC,EAAGoB,EAAI,EAAE,aAAa,OAAO,GAAK,GAAIlB,EAAI,EAAE,aAAa,KAAK,GAAK,GAAIC,EAAI,EAAE,aAAa,KAAK,GAAK,GAAIkB,EAAIiB,GAAElB,CAAC,EAC5H,IAAIf,EACJH,EAAIG,EAAIiC,GAAEpC,CAAC,EAAIC,EAAIE,EAAIgB,EAAIiB,GAAEnC,CAAC,EAAIE,EAAIgB,EAAI,EAC1C,IAAIf,EAAI,GACR,EAAE,WAAW,QAAS4B,GAAM,CAC1B,GAAIA,EAAE,WAAa,EACjB5B,GAAK4B,EAAE,WAAa,WACbA,EAAE,WAAa,EAAG,CACzB,MAAMC,EAAID,EACVC,EAAE,QAAQ,gBAAkB,KAAO7B,GAAK;AAAA,EAC5CA,GAAK6B,EAAE,aAAe,EACpB,CACF,CAAC,EACD,MAAM/B,EAAIE,EAAE,QAAQ,UAAW,GAAG,EAAE,QAAQ,OAAQ;AAAA,CACvD,EAAE,KAAI,GACFF,GAAKiB,GAAKhB,IAAMV,EAAE,KAAK,CAAE,MAAO0B,EAAG,IAAKhB,EAAG,KAAMD,CAAC,CAAE,CACvD,CACA,OAAOT,EAAE,KAAK,CAACK,EAAG,IAAMA,EAAE,MAAQ,EAAE,KAAK,EAAG,CAAE,OAAQ,OAAQ,KAAML,CAAC,CACvE,CACA,SAAS6C,GAAGrD,EAAG,EAAG,CAChB,OAAQ,GAAK+B,GAAE/B,CAAC,EAAC,CACf,IAAK,MACH,OAAOqC,GAAErC,CAAC,EACZ,IAAK,OACH,OAAOsC,GAAEtC,CAAC,EACZ,IAAK,MACH,OAAO6C,GAAE7C,EAAG,KAAK,EACnB,IAAK,MACH,OAAO6C,GAAE7C,EAAG,KAAK,EACnB,IAAK,OACH,OAAOoD,GAAEpD,CAAC,EACZ,IAAK,MACH,OAAOgC,GAAEhC,EAAG,KAAK,EACnB,IAAK,MACL,QACE,OAAOgC,GAAEhC,EAAG,KAAK,CACvB,CACA,CACA,eAAesD,GAAGtD,EAAG,CACnB,OAAOuD,GAAE,UAAUvD,CAAC,CACtB,CACA,SAASwD,GAAGxD,EAAG,CACb,MAAM,EAAI,CAAA,EACV,OAAOA,EAAE,QAAQ,CAACK,EAAGJ,IAAM,CACzB,IAAIiB,EACJ,MAAMV,EAAIP,EAAE,IAAKY,EAAIL,GAAK,CAACH,EAAE,SAAS,GAAG,EAAIA,EAAI,IAAMA,EAAGS,EAAIN,EAAIK,EAAE,QAAQ,MAAO,EAAE,EAAIA,EAAGoB,EAAInB,EAAE,YAAY,GAAG,EAAGC,EAAIkB,GAAK,EAAInB,EAAE,MAAMmB,EAAI,CAAC,EAAInB,EAAGE,EAAIiB,GAAK,EAAInB,EAAE,MAAM,EAAGmB,CAAC,EAAI,GAAIC,EAAI1B,EAAI,IAAMU,EAAIjB,EAAE,QAAU,KAAO,OAASiB,EAAE,mBAAqB,EAC3P,EAAE,KAAK,CACL,KAAML,EACN,KAAME,EACN,IAAKC,EACL,MAAOR,EACP,KAAM0B,EACN,KAAMjC,EAAE,IACd,CAAK,CACH,CAAC,EAAG,CACN,CACA,SAASwD,GAAGzD,EAAG,CACb,MAAM,EAAI,CAAE,KAAM,GAAI,KAAM,GAAI,MAAO,GAAI,SAAU,CAAA,EAAI,KAAM,CAAC,EAAIK,EAAoB,IAAI,IAC5FA,EAAE,IAAI,GAAI,CAAC,EACX,MAAMJ,EAAKY,GAAM,CACf,GAAIR,EAAE,IAAIQ,CAAC,EAAG,OAAOR,EAAE,IAAIQ,CAAC,EAC5B,MAAMC,EAAID,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO,EACrC,IAAI,EAAI,EAAGE,EAAI,GACf,UAAWC,KAAKF,EAAG,CACjBC,EAAIA,EAAI,GAAGA,CAAC,IAAIC,CAAC,GAAKA,EACtB,IAAI,EAAIX,EAAE,IAAIU,CAAC,EACf,IAAM,EAAI,CAAE,KAAMC,EAAG,KAAMD,EAAI,IAAK,MAAO,GAAI,SAAU,CAAA,EAAI,KAAM,CAAC,EAAI,EAAE,SAAS,KAAK,CAAC,EAAGV,EAAE,IAAIU,EAAG,CAAC,GAAI,EAAI,CAChH,CACA,OAAO,CACT,EACA,UAAWF,KAAKb,EAAG,CACjB,GAAIa,EAAE,MAAO,CACXZ,EAAEY,EAAE,KAAK,QAAQ,MAAO,EAAE,CAAC,EAC3B,QACF,CACAZ,EAAEY,EAAE,GAAG,EAAE,SAAS,KAAK,CACrB,KAAMA,EAAE,KACR,KAAMA,EAAE,KACR,MAAO,GACP,KAAMA,EAAE,IACd,CAAK,CACH,CACA,MAAML,EAAKK,GAAM,CACf,GAAIA,EAAE,SAAU,CACdA,EAAE,SAAS,KAAK,CAACC,EAAG,IAAMA,EAAE,QAAU,EAAE,MAAQA,EAAE,MAAQ,GAAK,EAAIA,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,EAC/F,UAAWA,KAAKD,EAAE,SAAUL,EAAEM,CAAC,CACjC,CACF,EACA,OAAON,EAAE,CAAC,EAAG,CACf,CAOA,eAAekD,GAAG1D,EAAG,EAAGK,EAAG,CACzB,MAAMJ,EAAID,EAAE,KAAK,CAAC,EAClB,GAAI,CAACC,EAAG,MAAM,IAAI,MAAM,wBAAwB,CAAC,EAAE,EACnD,MAAMO,EAAI,MAAMP,EAAE,MAAM,aAAa,EACrC,OAAO,IAAI,KAAK,CAACO,CAAC,EAAGH,EAAI,CAAE,KAAMA,CAAC,EAAK,MAAM,CAC/C,CACA,SAASsD,GAAE3D,EAAG,CACZ,OAAOA,EAAIA,EAAE,WAAW,GAAG,EAAIA,EAAIA,EAAE,SAAW,EAAI,IAAMA,EAAE,UAAU,CAAC,EAAIA,EAAE,SAAW,EAAI,IAAMA,EAAI,UAAY,SACpH,CACA,MAAM4D,GAAI,CACR,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACF,EAAGC,GAAI,CACL,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACF,EACA,SAASC,GAAE9D,EAAG,EAAG,CACf,MAAMK,EAAI,SAASL,EAAE,UAAU,EAAG,CAAC,EAAG,EAAE,EAAGC,EAAI,SAASD,EAAE,UAAU,EAAG,CAAC,EAAG,EAAE,EAAGQ,EAAI,SAASR,EAAE,UAAU,EAAG,CAAC,EAAG,EAAE,EAAGa,EAAKG,GAAM,EAAI,EAAI,KAAK,MAAMA,GAAK,EAAI,EAAE,EAAI,KAAK,MAAMA,GAAK,IAAMA,GAAK,CAAC,EAAGF,EAAI,KAAK,IAAI,IAAK,KAAK,IAAI,EAAGD,EAAER,CAAC,CAAC,CAAC,EAAG,EAAI,KAAK,IAAI,IAAK,KAAK,IAAI,EAAGQ,EAAEZ,CAAC,CAAC,CAAC,EAAGc,EAAI,KAAK,IAAI,IAAK,KAAK,IAAI,EAAGF,EAAEL,CAAC,CAAC,CAAC,EAChT,OAAOM,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EAAI,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EAAIC,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAC3G,CACA,SAASgD,GAAE/D,EAAG,CACZ,GAAIA,GAAKA,EAAE,OAAS,WAAaA,EAAE,UAAY,QAAS,CACtD,MAAM,EAAIA,EAAE,QACZ,GAAI,EACF,OAAOgE,GAAE,CAAC,CACd,CACF,CACA,SAASA,GAAEhE,EAAG,CACZ,GAAIA,EAAG,CACL,GAAI,SAAUA,GAAK,OAAOA,EAAE,MAAQ,UAAYA,EAAE,KAChD,OAAO2D,GAAE3D,EAAE,IAAI,EACjB,GAAI,UAAWA,GAAK,OAAOA,EAAE,OAAS,SAAU,CAC9C,MAAM,EAAI4D,GAAE5D,EAAE,KAAK,GAAK,SAAUK,EAAI,SAAUL,GAAK,OAAOA,EAAE,MAAQ,SAAWA,EAAE,KAAO,EAC1F,MAAO,KAAOK,IAAM,EAAIyD,GAAE,EAAGzD,CAAC,EAAI,EACpC,CACA,GAAI,YAAaL,GAAK,OAAOA,EAAE,SAAW,SAAU,CAClD,MAAM,EAAI6D,GAAE7D,EAAE,OAAO,EACrB,GAAI,EAAG,MAAO,IAAM,CACtB,CACF,CACF,CACA,SAASiE,GAAEjE,EAAG,CACZ,GAAI,CAACA,GAAK,CAACA,EAAE,MAAO,OACpB,MAAM,EAAIgE,GAAEhE,EAAE,KAAK,GAAK,UACxB,MAAO,CAACA,EAAE,MAAO,CAAC,CACpB,CACA,SAASkE,GAAGlE,EAAG,CACb,MAAM,EAAI,CAAA,EACV,IAAIK,EAAI,GACR,GAAIL,EAAE,KAAM,CACV,MAAMQ,EAAIR,EAAE,KACZ,IAAKQ,EAAE,MAAQA,EAAE,MAAQA,EAAE,MAAQA,EAAE,UAAYH,EAAI,GAAI,EAAE,KAAO,GAAIG,EAAE,OAAS,EAAE,KAAK,KAAOA,EAAE,MAAOA,EAAE,OAAS,EAAE,KAAK,KAAOA,EAAE,MAAOA,EAAE,OAAS,EAAE,KAAK,KAAO,IAAKA,EAAE,SAAW,EAAE,KAAK,OAAS,KAAMA,EAAE,MAAO,CAClN,MAAMK,EAAImD,GAAExD,EAAE,KAAK,EACnBK,IAAMR,EAAI,GAAI,EAAE,MAAQQ,EAC1B,CACAL,EAAE,YAAcH,EAAI,GAAI,EAAE,UAAY,IAAKG,EAAE,SAAWH,EAAI,GAAI,EAAE,OAAS,GAC7E,CACA,MAAMJ,EAAI8D,GAAE/D,EAAE,IAAI,EAClB,GAAIC,IAAMI,EAAI,GAAI,EAAE,QAAUJ,GAAID,EAAE,UAAW,CAC7C,MAAMQ,EAAIR,EAAE,UACZQ,EAAE,aAAeH,EAAI,GAAI,EAAE,MAAQG,EAAE,YAAaA,EAAE,WAAaH,EAAI,GAAI,EAAE,OAASG,EAAE,UAAWA,EAAE,WAAaH,EAAI,GAAI,EAAE,SAAW,GACvI,CACA,GAAIL,EAAE,OAAQ,CACZ,MAAMQ,EAAI,CAAA,EACV,IAAIK,EAAI,GACR,MAAMC,EAAI,CAAC,MAAO,SAAU,OAAQ,OAAO,EAC3C,UAAW,KAAKA,EAAG,CACjB,MAAMC,EAAIkD,GAAEjE,EAAE,OAAO,CAAC,CAAC,EACvBe,IAAMP,EAAE,CAAC,EAAIO,EAAGF,EAAI,GACtB,CACAA,IAAMR,EAAI,GAAI,EAAE,OAASG,EAC3B,CACA,OAAOH,EAAI,EAAI,IACjB,CACA,SAAS8D,GAAGnE,EAAG,CACb,OAAO,KAAK,UAAUA,CAAC,CACzB,CACA,SAASoE,GAAGpE,EAAG,EAAGK,EAAG,CACnB,MAAMJ,EAAIiE,GAAGlE,CAAC,EACd,GAAI,CAACC,EAAG,MAAO,GACf,MAAMO,EAAI2D,GAAGlE,CAAC,EAAGY,EAAIR,EAAE,IAAIG,CAAC,EAC5B,GAAIK,IAAM,OAAQ,OAAOA,EACzB,MAAMC,EAAI,EAAE,OACZ,OAAO,EAAE,KAAKb,CAAC,EAAGI,EAAE,IAAIG,EAAGM,CAAC,EAAGA,CACjC,CACA,SAASuD,GAAGrE,EAAG,CACb,MAAM,EAAIA,EAAE,MACZ,GAAI,GAAK,KAAM,MAAO,GACtB,GAAI,OAAO,GAAK,SAAU,OAAO,EACjC,GAAI,OAAO,GAAK,SAAU,OAAO,OAAO,CAAC,EACzC,GAAI,OAAO,GAAK,UAAW,OAAO,EAAI,OAAS,QAC/C,GAAI,aAAa,KACf,OAAO,EAAE,mBAAkB,EAC7B,GAAI,OAAO,GAAK,UAAY,YAAa,EAAG,CAC1C,MAAMK,EAAI,EAAE,OACZ,OAAOA,GAAK,KAAO,OAAOA,CAAC,EAAI,EACjC,CACA,OAAO,OAAO,GAAK,UAAY,aAAc,EAAI,EAAE,SAAS,IAAK,GAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAI,OAAO,GAAK,UAAY,cAAe,EAAI,EAAE,MAAQ,GAAK,OAAO,GAAK,UAAY,UAAW,EAAI,OAAO,EAAE,KAAK,EAAI,OAAO,CAAC,CACvN,CACA,SAASiE,GAAGtE,EAAG,CACb,MAAM,EAAIA,EAAE,MAAM,GAAG,EAAGK,EAAIkE,GAAE,EAAE,CAAC,CAAC,EAAGtE,EAAI,EAAE,CAAC,EAAIsE,GAAE,EAAE,CAAC,CAAC,EAAIlE,EAC1D,MAAO,CACL,IAAKA,EAAE,IACP,KAAMA,EAAE,IACR,OAAQJ,EAAE,IACV,MAAOA,EAAE,GACb,CACA,CACA,SAASsE,GAAEvE,EAAG,CACZ,MAAM,EAAIA,EAAE,MAAM,iBAAiB,EACnC,GAAI,CAAC,EAAG,MAAO,CAAE,IAAK,EAAG,IAAK,CAAC,EAC/B,MAAMK,EAAI,EAAE,CAAC,EAAGJ,EAAI,SAAS,EAAE,CAAC,EAAG,EAAE,EACrC,IAAIO,EAAI,EACR,QAASK,EAAI,EAAGA,EAAIR,EAAE,OAAQQ,IAC5BL,EAAIA,EAAI,IAAMH,EAAE,WAAWQ,CAAC,EAAI,IAClC,MAAO,CAAE,IAAKZ,EAAG,IAAKO,CAAC,CACzB,CACA,SAASgE,GAAGxE,EAAG,CACb,MAAM,EAAI,CAAA,EACV,OAAOA,EAAE,UAAWK,GAAM,CACxB,MAAMJ,EAAI,CAAA,EAAIO,EAAoB,IAAI,IAAOK,EAAI,CAAA,EAAIC,EAAI,CAAA,EAAI,EAAI,CAAA,EAAIC,EAAIV,EAAE,YAC3E,QAASc,EAAI,EAAGA,GAAKJ,EAAGI,IAAK,CAC3B,MAAMF,EAAIZ,EAAE,UAAUc,CAAC,EACvBF,EAAE,QAAU,EAAE,OAAOE,EAAI,CAAC,CAAC,EAAI,CAAE,MAAO,KAAK,MAAMF,EAAE,MAAQ,GAAG,CAAC,EACnE,CACA,EAAE,IAAM,KAAK,IAAIF,EAAG,EAAE,EACtB,MAAMC,EAAoB,IAAI,IAAO,EAAIX,EAAE,MAAOa,GAAK,GAAK,KAAO,OAAS,EAAE,SAAW,CAAA,EACzF,UAAWC,KAAKD,EAAG,CACjBL,EAAE,KAAKM,CAAC,EACR,KAAM,CAAE,IAAKF,EAAG,KAAM8B,EAAG,OAAQC,EAAG,MAAOR,CAAC,EAAK8B,GAAGnD,CAAC,EAAGsB,EAAIO,EAAI/B,EAAGyB,EAAIF,EAAIO,EAC3E/B,EAAE,IAAI,GAAGC,EAAI,CAAC,IAAI8B,EAAI,CAAC,GAAI,CAACN,EAAGC,CAAC,CAAC,CACnC,CACArC,EAAE,QAAQ,CAAE,aAAc,EAAE,EAAI,CAACc,EAAGF,IAAM,CACxC,MAAM8B,EAAI9B,EAAI,EAAG+B,EAAI,CAAA,EACrB7B,EAAE,SAAS,CAAE,aAAc,EAAE,EAAI,CAACsB,EAAGC,IAAM,CACzC,MAAM,EAAIA,EAAI,EACd,GAAID,EAAE,UAAYA,EAAE,SAAWA,EAAG,OAClC,MAAMF,EAAI8B,GAAG5B,CAAC,EAAGS,EAAIkB,GAAG3B,EAAGxC,EAAGO,CAAC,EAAGsC,EAAI,CAAE,KAAMP,CAAC,EAC/CW,IAAM,KAAOJ,EAAE,MAAQI,GACvB,MAAMD,EAAI,GAAGF,CAAC,IAAI,CAAC,GACnB/B,EAAE,IAAIiC,CAAC,IAAMH,EAAE,MAAQ9B,EAAE,IAAIiC,CAAC,GAAID,EAAE,OAAO,CAAC,CAAC,EAAIF,CACnD,CAAC,EACD,MAAMN,EAAI,CAAE,MAAOQ,CAAC,EACpB7B,EAAE,SAAWqB,EAAE,OAAS,KAAK,MAAMrB,EAAE,OAAS,KAAK,GAAIL,EAAE,OAAOiC,CAAC,CAAC,EAAIP,CACxE,CAAC,EAAG,EAAE,KAAK,CACT,KAAMnC,EAAE,KACR,OAAQJ,EACR,OAAQY,EACR,KAAMC,EACN,KAAM,CACZ,CAAK,CACH,CAAC,EAAG,CACN,CACA,SAAS2D,GAAGzE,EAAG,EAAGK,EAAI,SAAU,CAC9B,MAAMJ,EAAID,EAAE,OAAS,EAAGa,EAAIZ,EAAI,CAAC,CAAE,KAAM,CAAE,KAAM,EAAE,CAAE,CAAE,EAAI,CAAA,EAAI,EAAI,CAAA,EACnE,GAAIA,EAAG,CACL,MAAMc,EAAI,CAAA,EACVf,EAAE,QAAQ,CAACgB,EAAGkB,IAAM,CAClBnB,EAAE,OAAOmB,CAAC,CAAC,EAAI,CAAE,KAAMlB,EAAG,MAAO,CAAC,CACpC,CAAC,EAAG,EAAE,CAAC,EAAI,CAAE,MAAOD,CAAC,CACvB,CACA,MAAMkB,EAAIhC,EAAI,EAAI,EAClB,OAAO,EAAE,QAAQ,CAACc,EAAGC,IAAM,CACzB,MAAMkB,EAAI,CAAA,EACVnB,EAAE,QAAQ,CAACG,EAAGC,IAAM,CAClBD,IAAM,QAAUA,IAAM,KAAOgB,EAAE,OAAOf,CAAC,CAAC,EAAI,CAAE,KAAMD,CAAC,EACvD,CAAC,EAAG,EAAE,OAAOF,EAAIiB,CAAC,CAAC,EAAI,CAAE,MAAOC,CAAC,CACnC,CAAC,EAAG,CAAC,CAAE,KAAM7B,EAAG,OAAQQ,EAAG,KAAM,EAAG,CACtC,CAWA,MAAM6D,GAAK,CAET,kBAAmB,KACnB,eAAgB,KAChB,iBAAkB,MAClB,uBAAwB,OACxB,6BAA8B,sBAE9B,kBAAmB,KACnB,mBAAoB,KACpB,sBAAuB,OACvB,uBAAwB,OACxB,gBAAiB,KACjB,wBAAyB,OACzB,wBAAyB,OACzB,cAAe,KACf,oBAAqB,MACrB,oBAAqB,MACrB,qBAAsB,OACtB,uBAAwB,OACxB,kBAAmB,OACnB,mBAAoB,MACpB,iBAAkB,KAClB,kBAAmB,KAEnB,oBAAqB,SAErB,kBAAmB,aAEnB,oBAAqB,cAErB,eAAgB,gBAChB,mBAAoB,aACpB,oBAAqB,eACrB,iBAAkB,cAElB,eAAgB,cAChB,mBAAoB,WACpB,oBAAqB,aACrB,iBAAkB,YAClB,sBAAuB,iBACvB,gBAAiB,cACjB,eAAgB,kBAEhB,mBAAoB,iBACpB,yBAA0B,SAC1B,iBAAkB,UAElB,mBAAoB,cAEpB,mBAAoB,4BAEpB,gBAAiB,WACjB,oBAAqB,SACrB,+BAAgC,kBAEhC,kBAAmB,KACnB,mBAAoB,KACpB,wBAAyB,UACzB,yBAA0B,UAC1B,kBAAmB,KACnB,oBAAqB,OACrB,qBAAsB,OACtB,sBAAuB,OACvB,sBAAuB,OACvB,oBAAqB,KAErB,uBAAwB,kBACxB,qBAAsB,OACtB,kBAAmB,MAEnB,mBAAoB,cACpB,aAAc,QACd,YAAa,OAEb,cAAe,cACf,kBAAmB,aACnB,mBAAoB,WAEpB,kBAAmB,aAEnB,uBAAwB,WACxB,wBAAyB,SACzB,iBAAkB,QAClB,gBAAiB,OACjB,sBAAuB,KACvB,uBAAwB,MACxB,sBAAuB,KACvB,uBAAwB,KACxB,mBAAoB,KACpB,uBAAwB,KACxB,uBAAwB,KACxB,uBAAwB,MACxB,wBAAyB,KAEzB,kBAAmB,aACnB,mBAAoB,WAEpB,mBAAoB,UACtB,EAAGC,GAAK,CAEN,kBAAmB,WACnB,eAAgB,QAChB,iBAAkB,UAClB,uBAAwB,gBACxB,6BAA8B,oDAE9B,kBAAmB,UACnB,mBAAoB,WACpB,sBAAuB,cACvB,uBAAwB,eACxB,gBAAiB,QACjB,wBAAyB,gBACzB,wBAAyB,gBACzB,cAAe,oBACf,oBAAqB,gBACrB,oBAAqB,YACrB,qBAAsB,aACtB,uBAAwB,eACxB,kBAAmB,YACnB,mBAAoB,UACpB,iBAAkB,SAClB,kBAAmB,UAEnB,oBAAqB,uBAErB,kBAAmB,qBAEnB,oBAAqB,gCAErB,eAAgB,mBAChB,mBAAoB,uBACpB,oBAAqB,6BACrB,iBAAkB,uBAElB,eAAgB,iBAChB,mBAAoB,qBACpB,oBAAqB,2BACrB,iBAAkB,qBAClB,sBAAuB,0CACvB,gBAAiB,8BACjB,eAAgB,yDAEhB,mBAAoB,kCACpB,yBAA0B,0BAC1B,iBAAkB,oBAElB,mBAAoB,sBAEpB,mBAAoB,gEAEpB,gBAAiB,mBACjB,oBAAqB,uBACrB,+BAAgC,gCAEhC,kBAAmB,OACnB,mBAAoB,QACpB,wBAAyB,qBACzB,yBAA0B,kBAC1B,kBAAmB,OACnB,oBAAqB,SACrB,qBAAsB,cACtB,sBAAuB,eACvB,sBAAuB,oBACvB,oBAAqB,SAErB,uBAAwB,0BACxB,qBAAsB,YACtB,kBAAmB,SAEnB,mBAAoB,sBACpB,aAAc,QACd,YAAa,OAEb,cAAe,iBACf,kBAAmB,qBACnB,mBAAoB,sBAEpB,kBAAmB,qBAEnB,uBAAwB,0BACxB,wBAAyB,2BACzB,iBAAkB,QAClB,gBAAiB,OACjB,sBAAuB,QACvB,uBAAwB,SACxB,sBAAuB,QACvB,uBAAwB,SACxB,mBAAoB,KACpB,uBAAwB,SACxB,uBAAwB,SACxB,uBAAwB,SACxB,wBAAyB,UAEzB,kBAAmB,qBACnB,mBAAoB,sBAEpB,mBAAoB,0BACtB,EAAGC,GAAI,CACL,QAASF,GACT,QAASC,EACX,EAAGE,GAAK,aACR,SAASC,GAAG9E,EAAG,EAAG,CAChB,OAAO,EAAIA,EAAE,QAAQ6E,GAAI,CAACxE,EAAGJ,IAAM,CACjC,MAAMO,EAAI,EAAEP,CAAC,EACb,OAAOO,IAAM,OAAS,IAAIP,CAAC,IAAM,OAAOO,CAAC,CAC3C,CAAC,EAAIR,CACP,CACA,SAAS+E,GAAG/E,EAAG,CACb,IAAIc,EACJ,MAAMX,EAAIH,EAAE,gBAAkB,QAASK,EAAIuE,GAAE5E,EAAE,MAAM,GAAK4E,GAAEzE,CAAC,GAAKyE,GAAE,OAAO,EAAG3E,GAAKa,EAAId,EAAE,WAAa,KAAO,OAASc,EAAEd,EAAE,MAAM,EAAGQ,EAAIP,EAAI,CAAE,GAAGI,EAAG,GAAGJ,CAAC,EAAKI,EAAGQ,EAAI+D,GAAE,OAAO,EAC5K,MAAO,CAAC,EAAG7D,IAAM,CACf,MAAMC,EAAIR,EAAE,CAAC,GAAKK,EAAE,CAAC,GAAK,EAC1B,OAAOiE,GAAG9D,EAAGD,CAAC,CAChB,CACF,CCxnCA,MAAMiE,GAAgBC,EAAAA,cAAyC,IAAI,EAUtDC,GAAgD,CAAC,CAC5D,OAAAC,EAAS,QACT,SAAAC,EACA,SAAAC,CACF,IAAM,CACJ,MAAMC,EAAQC,EAAAA,QAA4B,IAAM,CAC9C,MAAMpF,EAAIqF,GAAiB,CAAE,OAAAL,EAAQ,SAAAC,EAAU,EAC/C,MAAO,CAAE,OAAAD,EAAQ,EAAAhF,CAAA,CACnB,EAAG,CAACgF,EAAQC,CAAQ,CAAC,EAErB,OAAOK,EAAAA,IAACT,GAAc,SAAd,CAAuB,MAAAM,EAAe,SAAAD,CAAA,CAAS,CACzD,EAMA,IAAIK,GAAwC,KAC5C,SAASC,IAAoC,CAC3C,OAAKD,KACHA,GAAqBF,GAAiB,CAAE,OAAQ,OAAA,CAAS,GAEpDE,EACT,CAOO,SAASE,GAA4B,CAC1C,MAAMC,EAAMC,EAAAA,WAAWd,EAAa,EACpC,OAAOa,GAAA,YAAAA,EAAK,IAAKF,GAAA,CACnB,CAKO,SAASI,IAAoB,CAClC,MAAMF,EAAMC,EAAAA,WAAWd,EAAa,EACpC,OAAOa,GAAA,YAAAA,EAAK,SAAU,OACxB,CC3DA,MAAMG,GAAef,EAAAA,cAAoC,IAAI,EAOhDgB,GAA8C,CAAC,CAAE,MAAAC,EAAO,SAAAb,WAC3DW,GAAa,SAAb,CAAsB,MAAOE,EAAQ,SAAAb,EAAS,EAWjD,SAASc,IAAkC,CAChD,OAAOL,EAAAA,WAAWE,EAAY,GAAK,MACrC,CCrBA,MAAMI,GAAqD,CAAC,CAAE,UAAAC,CAAA,IAC5DZ,EAAAA,IAAC,MAAA,CACC,MAAM,6BACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QACf,UAAAY,EAEA,eAAC,OAAA,CAAK,EAAE,KAAK,EAAE,OAAO,WAAW,SAAS,SAAS,KAAK,WAAW,OAAO,KAAK,eAAe,OAAO,OAAO,SAAA,KAAA,CAE5G,CAAA,CACF,EAeK,SAASC,GAAsBT,EAA0C,CAC9E,MAAO,CACL,CACE,MAAO,CACL,CAAE,KAAM,SAAU,WAAOU,EAAAA,QAAA,CAAQ,UAAU,kBAAkB,EAAI,QAASV,EAAI,EAAE,kBAAkB,EAAG,OAAQA,EAAI,UAAW,SAAUA,EAAI,MAAQ,GAAA,EAClJ,CAAE,KAAM,OAAQ,QAAS,GAAG,KAAK,MAAMA,EAAI,KAAO,GAAG,CAAC,IAAK,SAAU,MAAA,EACrE,CAAE,KAAM,SAAU,WAAOW,EAAAA,OAAA,CAAO,UAAU,kBAAkB,EAAI,QAASX,EAAI,EAAE,iBAAiB,EAAG,OAAQA,EAAI,SAAU,SAAUA,EAAI,MAAQ,EAAA,CAAG,CACpJ,EAEF,CACE,MAAO,CACL,CAAE,KAAM,SAAU,KAAMJ,EAAAA,IAACgB,EAAAA,MAAK,UAAU,iBAAA,CAAkB,EAAI,QAASZ,EAAI,EAAE,uBAAuB,EAAG,OAAQA,EAAI,YAAA,EACnH,CAAE,KAAM,SAAU,KAAMJ,EAAAA,IAACW,IAAiB,UAAU,iBAAA,CAAkB,EAAI,QAASP,EAAI,EAAE,uBAAuB,EAAG,OAAQA,EAAI,cAAA,CAAe,CAChJ,EAEF,CACE,MAAO,CACL,CAAE,KAAM,SAAU,KAAMJ,EAAAA,IAACiB,EAAAA,WAAU,UAAU,iBAAA,CAAkB,EAAI,QAASb,EAAI,EAAE,qBAAqB,EAAG,OAAQA,EAAI,YAAA,EACtH,CAAE,KAAM,SAAU,KAAMJ,EAAAA,IAACkB,EAAAA,UAAS,UAAU,iBAAA,CAAkB,EAAI,QAASd,EAAI,EAAE,sBAAsB,EAAG,OAAQA,EAAI,aAAA,CAAc,CACtI,EAEF,CACE,MAAO,CACL,CAAE,KAAM,SAAU,KAAMJ,EAAAA,IAACmB,EAAAA,WAAU,UAAU,iBAAA,CAAkB,EAAI,QAASf,EAAI,EAAE,eAAe,EAAG,OAAQA,EAAI,OAAA,CAAQ,CAC1H,CACF,CAEJ,CCjDO,SAASgB,GAAoBhB,EAAwC,CAC1E,MAAO,CACL,CACE,MAAO,CACL,CAAE,KAAM,SAAU,WAAOU,EAAAA,QAAA,CAAQ,UAAU,kBAAkB,EAAI,QAASV,EAAI,EAAE,kBAAkB,EAAG,OAAQA,EAAI,UAAW,SAAUA,EAAI,MAAQ,GAAA,EAClJ,CAAE,KAAM,OAAQ,QAAS,GAAG,KAAK,MAAMA,EAAI,KAAO,GAAG,CAAC,IAAK,SAAU,MAAA,EACrE,CAAE,KAAM,SAAU,WAAOW,EAAAA,OAAA,CAAO,UAAU,kBAAkB,EAAI,QAASX,EAAI,EAAE,iBAAiB,EAAG,OAAQA,EAAI,SAAU,SAAUA,EAAI,MAAQ,EAAA,CAAG,CACpJ,EAEF,CACE,MAAO,CACL,CAAE,KAAM,SAAU,KAAMJ,EAAAA,IAACmB,EAAAA,WAAU,UAAU,iBAAA,CAAkB,EAAI,QAASf,EAAI,EAAE,eAAe,EAAG,OAAQA,EAAI,OAAA,CAAQ,CAC1H,CACF,CAEJ,CCbO,SAASiB,GAAqBjB,EAAyC,CAC5E,MAAO,CACL,CACE,MAAO,CACL,CAAE,KAAM,SAAU,WAAOkB,EAAAA,KAAA,CAAK,UAAU,kBAAkB,EAAI,QAASlB,EAAI,EAAE,aAAa,EAAG,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,YAAU,CAAE,CAC9I,EAEF,CACE,MAAO,CACL,CAAE,KAAM,SAAU,WAAOC,EAAAA,YAAA,CAAY,UAAU,kBAAkB,EAAI,QAASpB,EAAI,EAAE,mBAAmB,EAAG,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,WAAS,EACtJ,CAAE,KAAM,OAAQ,QAAS,GAAGnB,EAAI,OAAO,MAAMA,EAAI,KAAK,GAAI,SAAU,MAAA,EACpE,CAAE,KAAM,SAAU,WAAOqB,EAAAA,aAAA,CAAa,UAAU,kBAAkB,EAAI,QAASrB,EAAI,EAAE,mBAAmB,EAAG,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,WAAS,CAAE,CAC3J,EAEF,CACE,MAAO,CACL,CACE,KAAM,SACN,KAAMnB,EAAI,UAAYJ,EAAAA,IAAC0B,EAAAA,UAAA,CAAU,UAAU,iBAAA,CAAkB,EAAK1B,EAAAA,IAAC2B,EAAAA,UAAA,CAAU,UAAU,iBAAA,CAAkB,EACzG,QAASvB,EAAI,UAAYA,EAAI,EAAE,sBAAsB,EAAIA,EAAI,EAAE,oBAAoB,EACnF,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,kBAAgB,CACrD,CACF,CACF,CAEJ,CCzBO,SAASK,GAAqBxB,EAAyC,CAC5E,MAAO,CACL,CACE,MAAO,CACL,CACE,KAAM,SACN,KAAMJ,EAAAA,IAACsB,EAAAA,KAAA,CAAK,UAAU,iBAAA,CAAkB,EACxC,QAASlB,EAAI,EAAE,aAAa,EAC5B,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,YAAU,CAC/C,CACF,EAEF,CACE,MAAO,CACL,CACE,KAAM,SACN,KAAMvB,EAAAA,IAACwB,EAAAA,YAAA,CAAY,UAAU,iBAAA,CAAkB,EAC/C,QAASpB,EAAI,EAAE,mBAAmB,EAClC,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,WAAS,EAE9C,CACE,KAAM,OACN,QAAS,GAAGnB,EAAI,OAAO,MAAMA,EAAI,KAAK,GACtC,SAAU,MAAA,EAEZ,CACE,KAAM,SACN,KAAMJ,EAAAA,IAACyB,EAAAA,aAAA,CAAa,UAAU,iBAAA,CAAkB,EAChD,QAASrB,EAAI,EAAE,mBAAmB,EAClC,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,WAAS,CAC9C,CACF,EAEF,CACE,MAAO,CACL,CACE,KAAM,SACN,KAAMnB,EAAI,UACNJ,EAAAA,IAAC0B,EAAAA,UAAA,CAAU,UAAU,iBAAA,CAAkB,EACvC1B,EAAAA,IAAC2B,EAAAA,UAAA,CAAU,UAAU,iBAAA,CAAkB,EAC3C,QAASvB,EAAI,UAAYA,EAAI,EAAE,sBAAsB,EAAIA,EAAI,EAAE,oBAAoB,EACnF,OAAQ,IAAA,OAAM,OAAAmB,EAAAnB,EAAI,QAAQ,UAAZ,YAAAmB,EAAqB,kBAAgB,CACrD,CACF,CACF,CAEJ,CC7CO,SAASM,GAAoB,CAAE,MAAAC,GAA4C,CAChF,OAAKA,EACE,CACL,CACE,MAAO,CACL,CACE,KAAM,OACN,QAAS,GAAGA,EAAM,KAAK,YAAYA,EAAM,IAAI,WAAWC,GAAeD,EAAM,IAAI,CAAC,GAClF,SAAU,OAAA,CACZ,CACF,CACF,EAViB,CAAA,CAYrB,CCfO,SAASE,GAAqB5B,EAAyC,CAC5E,MAAM6B,EAAyB,CAC7B,CACE,MAAO,CACL,CACE,KAAM,SACN,KAAMjC,EAAAA,IAACkC,EAAAA,SAAA,CAAS,UAAU,iBAAA,CAAkB,EAC5C,QAAS9B,EAAI,SAAWA,EAAI,EAAE,kBAAkB,EAAIA,EAAI,EAAE,iBAAiB,EAC3E,OAAQA,EAAI,YAAA,CACd,CACF,CACF,EAGF,OAAIA,EAAI,QACN6B,EAAO,KAAK,CACV,MAAO,CACL,CACE,KAAM,SACN,KAAM7B,EAAI,YACNJ,EAAAA,IAACmC,EAAAA,KAAA,CAAK,UAAU,iBAAA,CAAkB,EAClCnC,EAAAA,IAACoC,EAAAA,IAAA,CAAI,UAAU,iBAAA,CAAkB,EACrC,QAAShC,EAAI,YAAcA,EAAI,EAAE,gBAAgB,EAAIA,EAAI,EAAE,iBAAiB,EAC5E,OAAQA,EAAI,mBAAA,CACd,CACF,CACD,EAGI6B,CACT,CCjCO,SAASI,GAAyBjC,EAA6C,CACpF,MAAO,CACL,CACE,MAAO,CACL,CACE,KAAM,SACN,KAAMA,EAAI,WAAa,UACnBJ,EAAAA,IAACmC,EAAAA,KAAA,CAAK,UAAU,iBAAA,CAAkB,EAClCnC,EAAAA,IAACoC,EAAAA,IAAA,CAAI,UAAU,iBAAA,CAAkB,EACrC,QAAShC,EAAI,WAAa,UAAYA,EAAI,EAAE,gBAAgB,EAAIA,EAAI,EAAE,iBAAiB,EACvF,OAAQA,EAAI,gBAAA,CACd,CACF,CACF,CAEJ,CCVA,MAAMkC,GAAoC,CACxC,QAAS,CAACC,EAAKC,IAAS,MAAMD,EAAKC,CAAI,CACzC,EAEMC,GAAiBjD,EAAAA,cAAmC8C,EAAY,EASzDI,GAAkD,CAAC,CAC9D,YAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,SAAAjD,CACF,IAAM,CACJ,MAAMC,EAAQC,EAAAA,QACZ,KAAO,CACL,QAASgD,GAAc,CAAE,YAAAH,EAAa,eAAAC,EAAgB,EACtD,kBAAAC,CAAA,GAEF,CAACF,EAAaC,EAAgBC,CAAiB,CAAA,EAEjD,OACE7C,EAAAA,IAACyC,GAAe,SAAf,CAAwB,MAAA5C,EAAe,SAAAD,CAAA,CAAS,CAErD,EAMO,SAASmD,IAAsB,CACpC,OAAO1C,EAAAA,WAAWoC,EAAc,EAAE,OACpC,CASO,SAASO,GAAeC,EAAuC,CACpE,KAAM,CAAE,QAAAC,EAAS,kBAAAL,GAAsBxC,EAAAA,WAAWoC,EAAc,EAC1DU,EAAW,CAAC,EAAEF,IAAQJ,GAAA,MAAAA,EAAoBI,KAC1C,CAACG,EAAUC,CAAW,EAAIC,EAAAA,SAAiB,IAC9CL,EAAYE,EAAW,GAAKF,EAAK,IAA1B,EAA0B,EAE9BM,EAAaC,EAAAA,OAAsB,IAAI,EAE7CC,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAACR,EAAM,CACTI,EAAY,EAAE,EACd,MACF,CACA,GAAI,CAACF,EAAU,CACbE,EAAYJ,EAAK,GAAG,EACpB,MACF,CACA,IAAIS,EAAY,GAChB,OAAAL,EAAY,EAAE,EACdM,GAAeV,EAAK,IAAKC,CAAO,EAC7B,KAAMU,GAAY,CACjB,GAAIF,EAAW,CACb,IAAI,gBAAgBE,CAAO,EAC3B,MACF,CACIL,EAAW,SACb,IAAI,gBAAgBA,EAAW,OAAO,EAExCA,EAAW,QAAUK,EACrBP,EAAYO,CAAO,CACrB,CAAC,EACA,MAAOC,GAAQ,CACTH,IACH,QAAQ,MAAM,0CAA2CG,CAAG,EAC5DR,EAAYJ,EAAK,GAAG,EAExB,CAAC,EACI,IAAM,CACXS,EAAY,EACd,CACF,EAAG,CAACT,GAAA,YAAAA,EAAM,GAAIA,GAAA,YAAAA,EAAM,IAAKE,EAAUD,CAAO,CAAC,EAG3CO,EAAAA,UAAU,IACD,IAAM,CACPF,EAAW,UACb,IAAI,gBAAgBA,EAAW,OAAO,EACtCA,EAAW,QAAU,KAEzB,EACC,CAAA,CAAE,EAEEH,CACT,CC1FO,MAAMU,GAAgDC,EAAAA,KAAK,IAChE,QAAA,QAAA,EAAA,KAAA,IAAAC,EAAA,EAAkB,KAAM1G,IAAO,CAAE,QAASA,EAAE,eAAgB,CAC9D,EAEa2G,GAA4CF,EAAAA,KAAK,IAC5D,QAAA,QAAA,EAAA,KAAA,IAAAG,EAAA,EAAgB,KAAM5G,IAAO,CAAE,QAASA,EAAE,aAAc,CAC1D,EAEa6G,GAA8CJ,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAK,EAAA,EAAiB,KAAM9G,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,EAEa+G,GAA8CN,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAO,EAAA,EAAiB,KAAMhH,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,EAEaiH,GAA8CR,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAS,EAAA,EAAiB,KAAMlH,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,EAEamH,GAA4CV,EAAAA,KAAK,IAC5D,QAAA,QAAA,EAAA,KAAA,IAAAW,EAAA,EAAgB,KAAMpH,IAAO,CAAE,QAASA,EAAE,aAAc,CAC1D,EAEaqH,GAA8CZ,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAa,EAAA,EAAiB,KAAMtH,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,EAEauH,GAA8Cd,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAe,EAAA,EAAiB,KAAMxH,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,EAEayH,GAAgDhB,EAAAA,KAAK,IAChE,QAAA,QAAA,EAAA,KAAA,IAAAiB,EAAA,EAAkB,KAAM1H,IAAO,CAAE,QAASA,EAAE,eAAgB,CAC9D,EAEa2H,GAAgDlB,EAAAA,KAAK,IAChE,QAAA,QAAA,EAAA,KAAA,IAAAmB,EAAA,EAAkB,KAAM5H,IAAO,CAAE,QAASA,EAAE,eAAgB,CAC9D,EAEa6H,GAAsDpB,EAAAA,KAAK,IACtE,QAAA,QAAA,EAAA,KAAA,IAAAqB,EAAA,EAAqB,KAAM9H,IAAO,CAAE,QAASA,EAAE,kBAAmB,CACpE,EAEa+H,GAA8CtB,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAuB,EAAA,EAAiB,KAAMhI,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,EAEaiI,GAA4CxB,EAAAA,KAAK,IAC5D,QAAA,QAAA,EAAA,KAAA,IAAAyB,EAAA,EAAgB,KAAMlI,IAAO,CAAE,QAASA,EAAE,aAAc,CAC1D,EAEamI,GAA4C1B,EAAAA,KAAK,IAC5D,QAAA,QAAA,EAAA,KAAA,IAAA2B,EAAA,EAAgB,KAAMpI,IAAO,CAAE,QAASA,EAAE,aAAc,CAC1D,EAEaqI,GAAsD5B,EAAAA,KAAK,IACtE,QAAA,QAAA,EAAA,KAAA,IAAA6B,EAAA,EAAqB,KAAMtI,IAAO,CAAE,QAASA,EAAE,kBAAmB,CACpE,EAEauI,GAA4C9B,EAAAA,KAAK,IAC5D,QAAA,QAAA,EAAA,KAAA,IAAA+B,EAAA,EAAgB,KAAMxI,IAAO,CAAE,QAASA,EAAE,aAAc,CAC1D,EAEayI,GAA8ChC,EAAAA,KAAK,IAC9D,QAAA,QAAA,EAAA,KAAA,IAAAiC,EAAA,EAAiB,KAAM1I,IAAO,CAAE,QAASA,EAAE,cAAe,CAC5D,ECjFa2I,GAA0D,CAAC,CACtE,SAAAC,EACA,SAAAC,EACA,WAAAC,CACF,IAAM,CACJ,MAAM1L,EAAIyF,EAAA,EACV,OACEkG,EAAAA,KAAC,MAAA,CAAI,UAAU,oGACb,SAAA,CAAArG,EAAAA,IAAC,OAAI,UAAU,mGACb,eAACsG,EAAAA,aAAA,CAAa,UAAU,0CAA0C,CAAA,CACpE,EAEAD,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAArG,EAAAA,IAAC,IAAA,CAAE,UAAU,uCAAwC,SAAAkG,EAAS,EAC9DlG,EAAAA,IAAC,IAAA,CAAE,UAAU,wBAAyB,SAAAtF,EAAE,6BAA8B,CAAE,KAAMyL,CAAA,CAAU,CAAA,CAAE,CAAA,EAC5F,EAEAE,EAAAA,KAAC,SAAA,CACC,QAASD,EACT,UAAU,2LAEV,SAAA,CAAApG,EAAAA,IAACuG,EAAAA,SAAA,CAAS,UAAU,iBAAA,CAAkB,EACrC7L,EAAE,iBAAiB,CAAA,CAAA,CAAA,CACtB,EACF,CAEJ,EChCa8L,GAA4B,IAAM,CAC7C,MAAM9L,EAAIyF,EAAA,EACV,aACG,MAAA,CAAI,UAAU,uFACb,SAAAkG,EAAAA,KAAC,MAAA,CAAI,UAAU,mDACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,6GAAA,CAA8G,QAC5H,OAAA,CAAK,UAAU,cAAe,SAAAtF,EAAE,gBAAgB,GAAK,YAAA,CAAa,CAAA,CAAA,CACrE,CAAA,CACF,CAEJ,ECiCM+L,GAAwB,EAoCjBC,GAAyDC,GAAU,CAC9E,KAAM,CAAE,YAAAhE,EAAa,eAAAC,EAAgB,kBAAAC,CAAA,EAAsB8D,EAC3D,OACE3G,EAAAA,IAAC0C,GAAA,CACC,YAAAC,EACA,eAAAC,EACA,kBAAAC,EAEA,SAAA7C,EAAAA,IAAC4G,GAAA,CAAyB,GAAGD,CAAA,CAAO,CAAA,CAAA,CAG1C,EAEMC,GAA6D,CAAC,CAClE,MAAAC,EACA,aAAAC,EACA,WAAAC,EACA,gBAAAC,EAAkB,CAAA,EAClB,KAAAC,EAAO,QACP,QAAAC,EACA,gBAAAC,EAAkB,EAClB,OAAAzH,EAAS,QACT,SAAU0H,EACV,SAAAC,EAAW,GACX,MAAA5G,EAAQ,OACR,cAAA6G,EACA,WAAAlB,EAEA,YAAamB,EACb,eAAgBC,EAChB,kBAAmBC,CACrB,IAAM,CACJ,MAAM/M,EAAgBoF,EAAAA,QACpB,IAAMC,GAAiB,CAAE,OAAAL,EAAQ,SAAU0H,EAAc,EACzD,CAAC1H,EAAQ0H,CAAY,CAAA,EAGjB,CAACM,EAAYC,CAAa,EAAIrE,EAAAA,SAAS,IAC3C,OAAO,OAAW,IACd,OAAO,WAAW,8BAA8B,EAAE,QAClD,EAAA,EAGNG,EAAAA,UAAU,IAAM,CACd,GAAIhD,IAAU,OAAQ,OACtB,MAAMmH,EAAM,OAAO,WAAW,8BAA8B,EACtDC,EAAWtN,IAA2BoN,EAAcpN,GAAE,OAAO,EACnE,OAAAqN,EAAI,iBAAiB,SAAUC,CAAO,EAC/B,IAAMD,EAAI,oBAAoB,SAAUC,CAAO,CACxD,EAAG,CAACpH,CAAK,CAAC,EAEV,MAAMqH,EAAgBrH,IAAU,OAAUiH,EAAa,OAAS,QAAWjH,EAErE,CAACsH,EAAMC,CAAO,EAAI1E,EAAAA,SAAS,CAAC,EAC5B,CAAC2E,EAAUC,CAAW,EAAI5E,EAAAA,SAAS,CAAC,EACpC,CAAC6E,EAAaC,CAAc,EAAI9E,EAAAA,SAAS,CAAC,EAC1C,EAAG+E,CAAa,EAAI/E,EAAAA,SAAS,CAAC,EAC9B,CAACgF,EAAqBC,CAAsB,EAAIjF,EAAAA,SAAS,CAAC,EAC1D,CAACkF,EAAsBC,CAAuB,EAAInF,EAAAA,SAAS,CAAC,EAC5D,CAACoF,EAAeC,CAAgB,EAAIrF,EAAAA,SAAS,CAAC,EAC9CsF,EAAapF,EAAAA,OAAuB,IAAI,EACxCqF,EAAUrF,EAAAA,OAAuB,IAAI,EACrCsF,EAAUtF,EAAAA,OAA2B,IAAI,EACzC,CAACuF,EAAaC,CAAc,EAAI1F,EAAAA,SAAS,CAAC,EAC1C,CAAC2F,EAAWC,CAAY,EAAI5F,EAAAA,SAAS,CAAC,EACtC,CAAC6F,EAAeC,CAAgB,EAAI9F,EAAAA,SAAS,EAAK,EAClD+F,EAAU7F,EAAAA,OAA2B,IAAI,EACzC,CAAC8F,GAAaC,CAAc,EAAIjG,EAAAA,SAAS,CAAC,EAC1C,CAACkG,GAAWC,CAAY,EAAInG,EAAAA,SAAS,CAAC,EACtC,CAACoG,GAAeC,CAAgB,EAAIrG,EAAAA,SAAS,EAAK,EAClD,CAACsG,GAAUC,EAAW,EAAIvG,EAAAA,SAAiC,IAAI,EAC/D,CAACwG,GAAcC,EAAe,EAAIzG,EAAAA,SAAS,EAAI,EAC/C,CAAC0G,GAAiBC,EAAkB,EAAI3G,EAAAA,SAAS,EAAK,EACtD,CAAC4G,GAAkBC,EAAmB,EAAI7G,EAAAA,SAA+B,SAAS,EAGlF,CAAC8G,GAAYC,EAAa,EAAI/G,EAAAA,SAAS,EAAI,EAC3CgH,GAAkB9G,EAAAA,OAAsB,IAAI,EAC5C+G,GAAiB,IAEjBC,GAAgBC,EAAAA,YAAY,IAAM,CACtCJ,GAAc,EAAI,EACdC,GAAgB,SAClB,aAAaA,GAAgB,OAAO,EAEtCA,GAAgB,QAAU,OAAO,WAAW,IAAM,CAChDD,GAAc,EAAK,CACrB,EAAGE,EAAc,CACnB,EAAG,CAAA,CAAE,EAECG,GAAkBD,EAAAA,YAAY,IAAM,CACxCD,GAAA,CACF,EAAG,CAACA,EAAa,CAAC,EAGZG,GAAkB7K,EAAAA,QAAQ,IAAM8K,GAAe/D,CAAK,EAAG,CAACA,CAAK,CAAC,EAE9DgE,EAAcF,GAAgB7D,CAAY,EAG1CgE,GAAc9H,GAAe6H,CAAW,EAGxCE,GAAiBjL,EAAAA,QAAQ,IACxB+K,EACE7D,EAAgB,KAAKgE,GAAYA,EAAS,KAAKH,CAAW,CAAC,EADzC,KAExB,CAACA,EAAa7D,CAAe,CAAC,EAE3Bb,EAAW0E,EAAcI,GAAYJ,CAAW,EAAI,cAGpDK,GAAaT,EAAAA,YACjB,CAACU,EAAcC,IAAsB,CAC9BP,IACLvD,GAAA,MAAAA,EAAgB,CAAE,KAAA6D,EAAM,QAAAC,EAAS,KAAMP,IACzC,EACA,CAACA,EAAavD,CAAa,CAAA,EAIvB+D,GAAYvL,EAAAA,QAChB,KAAO,CACL,KAAMoL,GACN,EAAAxQ,EACA,MAAOoN,EACP,OAAApI,CAAA,GAEF,CAACwL,GAAYxQ,EAAGoN,EAAepI,CAAM,CAAA,EAIvC+D,EAAAA,UAAU,IAAM,CACduE,EAAQ,CAAC,EACTE,EAAY,CAAC,EACbE,EAAe,CAAC,EAChBC,EAAc,CAAC,EACfE,EAAuB,CAAC,EACxBE,EAAwB,CAAC,EACzB4B,GAAc,EAAI,EACdC,GAAgB,SAClB,aAAaA,GAAgB,OAAO,CAExC,EAAG,CAACxD,CAAY,CAAC,EAGjBrD,EAAAA,UAAU,IAAM,CACd,GAAI0C,IAAa,SAAWmC,EAAsB,GAAKE,EAAuB,GAAKI,EAAW,QAAS,CACrG,MAAM0C,EAAiB1C,EAAW,QAAQ,YACpC2C,EAAkB3C,EAAW,QAAQ,aACrC4C,GAASF,EAAiBhD,EAC1BmD,GAASF,EAAkB/C,EAC3BkD,GAAU,KAAK,IAAIF,GAAQC,EAAM,EACvCzD,EAAQ,KAAK,IAAI,IAAM,KAAK,IAAI,GAAI0D,EAAO,CAAC,CAAC,CAC/C,CACF,EAAG,CAACvF,EAAUmC,EAAqBE,CAAoB,CAAC,EAGxD/E,EAAAA,UAAU,KACJkH,GAAgB,OAAS,GAC3BH,GAAA,EAEK,IAAM,CACPF,GAAgB,SAClB,aAAaA,GAAgB,OAAO,CAExC,GACC,CAACK,GAAgB,OAAQH,EAAa,CAAC,EAK1C/G,EAAAA,UAAU,IAAM,CACd,MAAMkI,EAAiBpR,GAAqB,CACtCA,EAAE,MAAQ,UAAY0M,IAAS,QACjCC,GAAA,MAAAA,IACS3M,EAAE,MAAQ,aAAeuM,EAAe,EACjDC,GAAA,MAAAA,EAAaD,EAAe,GACnBvM,EAAE,MAAQ,cAAgBuM,EAAe6D,GAAgB,OAAS,IAC3E5D,GAAA,MAAAA,EAAaD,EAAe,GAEhC,EAEA,GAAIG,IAAS,QACX,cAAO,iBAAiB,UAAW0E,CAAa,EACzC,IAAM,OAAO,oBAAoB,UAAWA,CAAa,EAC3D,CACL,MAAMC,EAAK/C,EAAQ,QACnB,OAAK+C,GACLA,EAAG,iBAAiB,UAAWD,CAA8B,EACtD,IAAMC,EAAG,oBAAoB,UAAWD,CAA8B,GAFpE,MAGX,CACF,EAAG,CAAC1E,EAAMH,EAAc6D,GAAgB,OAAQzD,EAASH,CAAU,CAAC,EAEpE,MAAM8E,GAAepB,EAAAA,YAAY,IAAM,CACrCzC,EAAS8D,GAAS,KAAK,IAAIA,EAAO,GAAK,EAAE,CAAC,CAC5C,EAAG,CAAA,CAAE,EAECC,GAAgBtB,EAAAA,YAAY,IAAM,CACtCzC,EAAS8D,GAAS,KAAK,IAAIA,EAAO,GAAK,GAAI,CAAC,CAC9C,EAAG,CAAA,CAAE,EAECE,GAAevB,EAAAA,YAAY,IAAM,CACrCvC,EAAa4D,GAASA,EAAO,EAAE,CACjC,EAAG,CAAA,CAAE,EAECG,GAAmBxB,EAAAA,YAAY,IAAM,CACzCvC,EAAa4D,GAASA,EAAO,EAAE,CACjC,EAAG,CAAA,CAAE,EAECI,GAAmBzB,EAAAA,YAAY,IAAM,CACzC,GAAI7B,EAAW,SAAWN,EAAsB,GAAKE,EAAuB,EAAG,CAC7E,MAAM8C,EAAiB1C,EAAW,QAAQ,YACpC2C,EAAkB3C,EAAW,QAAQ,aACrC4C,GAASF,EAAiBhD,EAC1BmD,GAASF,EAAkB/C,EAC3BkD,GAAU,KAAK,IAAIF,GAAQC,EAAM,EACvCzD,EAAQ,KAAK,IAAI,IAAM,KAAK,IAAI,GAAI0D,EAAO,CAAC,CAAC,CAC/C,MACE1D,EAAQ,CAAC,EAEXE,EAAY,CAAC,EACbS,EAAiBlO,GAAKA,EAAI,CAAC,CAC7B,EAAG,CAAC6N,EAAqBE,CAAoB,CAAC,EAExC2D,GAAqB1B,EAAAA,YAAY,IAAM,CAC3CzC,EAAQ,CAAC,EACTE,EAAY,CAAC,EACbS,EAAiBlO,GAAKA,EAAI,CAAC,CAC7B,EAAG,CAAA,CAAE,EAEC2R,GAAmB3B,cAAaiB,GAAoB,CACxD1D,EAAQ0D,CAAO,CACjB,EAAG,CAAA,CAAE,EAECW,GAAc5B,EAAAA,YAAY,IAAM,CACpCzC,EAAQ,CAAC,EACTE,EAAY,CAAC,EACbS,EAAiBlO,GAAKA,EAAI,CAAC,CAC7B,EAAG,CAAA,CAAE,EAECyI,GAAUH,GAAA,EACVuJ,GAAiB7B,EAAAA,YAAY,SAAY,CAC7C,GAAKI,EACL,IAAIzE,EAAY,CACd,MAAMA,EAAWyE,CAAW,EAC5B,MACF,CACA,GAAI,CACF,MAAM0B,GAAwB1B,EAAY,IAAKA,EAAY,KAAM3H,EAAO,CAC1E,OAASW,EAAK,CACZ,QAAQ,MAAM,kCAAmCA,CAAG,CACtD,EACF,EAAG,CAACgH,EAAazE,EAAYlD,EAAO,CAAC,EAE/BsJ,GAA0B/B,EAAAA,YAAY,CAACgC,EAAiBC,IAAkB,CAC9E1D,EAAeyD,CAAO,EACtBvD,EAAawD,CAAK,CACpB,EAAG,CAAA,CAAE,EAECC,GAA0BlC,EAAAA,YAAY,CAACgC,EAAiBC,IAAkB,CAC9EnD,EAAekD,CAAO,EACtBhD,EAAaiD,CAAK,CACpB,EAAG,CAAA,CAAE,EAECE,GAAuBnC,cAAa3I,GAAkC,CAC1E+H,GAAY/H,CAAK,CACnB,EAAG,CAAA,CAAE,EAEL,GAAI,CAAC+I,EAAa,OAAO,KAEzB,MAAMgC,GAAkB5F,IAAS,SAAW,CAAC,CAACC,EAGxC4F,IAA8B,IAAM,SACxC,GAAI/B,GACF,QAAOxJ,EAAAwJ,GAAe,mBAAf,YAAAxJ,EAAA,KAAAwJ,GAAkCF,EAAaQ,MAAc,CAAA,EAEtE,GAAIlF,IAAa,QACf,OAAOtF,GAAsB,CAC3B,KAAAkH,EACA,SAAU8D,GACV,UAAWE,GACX,aAAcG,GACd,eAAgBC,GAChB,aAAcF,GACd,cAAeD,GACf,QAASK,GACT,EAAA3R,CAAA,CACD,EAEH,GAAIyL,IAAa,MACf,OAAO/E,GAAoB,CACzB,KAAA2G,EACA,SAAU8D,GACV,UAAWE,GACX,QAASM,GACT,EAAA3R,CAAA,CACD,EAEH,GAAIyL,IAAa,OACf,OAAO9E,GAAqB,CAC1B,QAAAyH,EACA,QAASC,EACT,MAAOE,EACP,UAAWE,EACX,EAAAzO,CAAA,CACD,EAEH,GAAIyL,IAAa,OACf,OAAOvE,GAAqB,CAC1B,QAAAyH,EACA,QAASC,GACT,MAAOE,GACP,UAAWE,GACX,EAAAhP,CAAA,CACD,EAEH,GAAIyL,IAAa,MACf,OAAOtE,GAAoB,CAAE,MAAO+H,EAAY,CAAC,EAEnD,GAAIzD,IAAa,OAAQ,CACvB,MAAM4G,KAAMC,EAAAnC,EAAY,KAAK,MAAM,GAAG,EAAE,IAAA,IAA5B,YAAAmC,EAAmC,gBAAiB,GAChE,OAAOhL,GAAqB,CAC1B,SAAU8H,GACV,aAAc,IAAMC,GAAgB+B,IAAQ,CAACA,EAAI,EACjD,OAAQiB,KAAQ,QAAUA,KAAQ,MAClC,YAAa/C,GACb,oBAAqB,IAAMC,GAAmB6B,IAAQ,CAACA,EAAI,EAC3D,EAAApR,CAAA,CACD,CACH,CACA,OAAIyL,IAAa,WACR9D,GAAyB,CAC9B,SAAU6H,GACV,iBAAkB,IAAMC,OAA4B2B,KAAS,UAAY,SAAW,SAAS,EAC7F,EAAApR,CAAA,CACD,EAEI,CAAA,CACT,GAAA,EAGMuS,GAA+B,CACnC,CACE,MAAO,CACL,CAAE,KAAM,SAAU,WAAO1G,EAAAA,SAAA,CAAS,UAAU,iBAAA,CAAkB,EAAI,QAAS7L,EAAE,iBAAiB,EAAG,OAAQ4R,EAAA,CAAe,CAC1H,EAEF,GAAIO,GAAkB,CAAC,CACrB,MAAO,CACL,CAAE,KAAM,SAAmB,WAAOzO,EAAAA,EAAA,CAAE,UAAU,iBAAA,CAAkB,EAAI,QAAS1D,EAAE,cAAc,EAAG,OAAQwM,CAAA,CAAS,CACnH,CACD,EAAI,CAAA,CAAC,EAGFgG,GAAqB,CAACjL,EAAwBkL,IAClDlL,EAAO,IAAI,CAACmL,GAAOC,GAAIC,KACrBjH,EAAAA,KAACkH,EAAM,SAAN,CACE,SAAA,CAAAH,GAAM,MAAM,IAAI,CAACI,GAAMC,KACtBD,GAAK,OAAS,SACZxN,EAAAA,IAAC0N,GAAA,CAEC,KAAMF,GAAK,KACX,MAAOA,GAAK,QACZ,QAASA,GAAK,OACd,SAAUA,GAAK,QAAA,EAJV,GAAGH,EAAE,IAAII,EAAE,EAAA,EAOlBzN,EAAAA,IAAC,OAAA,CAEC,UAAU,oFACV,MAAO,CAAE,SAAUwN,GAAK,UAAY,MAAA,EAEnC,SAAAA,GAAK,OAAA,EAJD,GAAGH,EAAE,IAAII,EAAE,EAAA,CAKlB,EAGHJ,GAAKC,GAAI,OAAS,SAAM,MAAA,CAAI,UAAW,kCAAkCH,CAAY,EAAA,CAAI,CAAA,CAAA,EApBvEE,EAqBrB,CACD,EAEH,OACErN,EAAAA,IAACP,IAAe,OAAAC,EAAgB,SAAU0H,EAC1C,SAAApH,EAAAA,IAACQ,GAAA,CAAc,MAAOsH,EACtB,SAAAzB,EAAAA,KAAC,MAAA,CACC,IAAKwC,EACL,SAAU5B,IAAS,QAAU,EAAI,GACjC,aAAYa,EACZ,UAAU,gGAGT,SAAA,CAAA,CAACT,GACFhB,EAAAA,KAACsH,GAAAA,OAAO,IAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAAS,CAAA,EACpB,KAAM,CAAE,QAAS,CAAA,EACjB,UAAU,sGACV,MAAO,CAAE,WAAY,+BAAA,EAGrB,SAAA,CAAAtH,EAAAA,KAAC,MAAA,CAAI,UAAU,8FAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,wEACb,SAAA,CAAArG,EAAAA,IAAC,KAAA,CAAG,UAAU,8EACX,SAAA6K,EAAY,KACf,EACAxE,EAAAA,KAAC,OAAA,CAAK,UAAU,2DACb,SAAA,CAAAS,EAAe,EAAE,IAAE6D,GAAgB,MAAA,CAAA,CACtC,CAAA,EACF,QAGC,MAAA,CAAI,UAAU,sEACZ,SAAAuC,GAAmBD,GAAc,YAAY,EAChD,EAGA5G,EAAAA,KAAC,MAAA,CAAI,UAAU,sEACZ,SAAA,CAAA6G,GAAmBJ,GAAY,UAAU,EACzCA,GAAW,OAAS,GAAK9M,EAAAA,IAAC,MAAA,CAAI,UAAU,0CAA0C,EAClFkN,GAAmBD,GAAc,UAAU,CAAA,CAAA,CAC9C,CAAA,EACF,EAGCH,GAAW,OAAS,GACnB9M,EAAAA,IAAC,MAAA,CAAI,UAAU,2GACZ,SAAAkN,GAAmBJ,GAAY,YAAY,CAAA,CAC9C,CAAA,CAAA,CAAA,EAMJ9M,EAAAA,IAAC,MAAA,CACC,IAAK4I,EACL,UAAU,4EACV,YAAa8B,GAEZ,SAAAK,GACCA,GAAe,OAAOF,EAAaQ,EAAS,EAE5ChF,EAAAA,KAACuH,EAAAA,SAAA,CAAS,SAAU5N,EAAAA,IAACwG,GAAA,CAAA,CAAgB,EAClC,SAAA,CAAAL,IAAa,SACZnG,EAAAA,IAAC8D,GAAA,CACC,IAAKgH,GACL,KAAA/C,EACA,SAAAE,EACA,SAAUS,EACV,SAAUmC,EAAY,KACtB,aAAcuB,GACd,qBAAsB7D,EACtB,sBAAuBE,CAAA,CAAA,EAG1BtC,IAAa,OACZnG,EAAAA,IAACiE,GAAA,CACC,IAAK6G,GACL,KAAA/C,EACA,YAAAI,EACA,aAAcC,EACd,mBAAoBC,EACpB,kBAAmBE,CAAA,CAAA,EAGtBpC,IAAa,QAAUnG,EAAAA,IAACmE,GAAA,CAAa,IAAK2G,GAAa,EACvD3E,IAAa,QAAUnG,EAAAA,IAACqE,GAAA,CAAa,IAAKyG,GAAa,EACvD3E,IAAa,QAAUnG,EAAAA,IAACuE,GAAA,CAAa,IAAKuG,GAAa,EACvD3E,IAAa,OAASnG,EAAAA,IAACyE,GAAA,CAAY,IAAKqG,GAAa,EACrD3E,IAAa,QACZnG,EAAAA,IAAC2E,GAAA,CACC,IAAKmE,EACL,IAAKgC,GACL,gBAAiB0B,GACjB,kBAAmBpD,CAAA,CAAA,EAGtBjD,IAAa,QACZnG,EAAAA,IAAC6E,GAAA,CACC,IAAKwE,EACL,IAAKyB,GACL,gBAAiB6B,GACjB,kBAAmBhD,CAAA,CAAA,EAGtBxD,IAAa,SAAWnG,EAAAA,IAAC+E,GAAA,CAAc,IAAK+F,GAAa,EACzD3E,IAAa,SACZnG,EAAAA,IAACiF,GAAA,CAAc,IAAK6F,GAAa,SAAUD,EAAY,KAAM,EAE9D1E,IAAa,YAAcnG,EAAAA,IAACmF,IAAiB,IAAK2F,GAAa,SAAUZ,GAAkB,EAC3F/D,IAAa,QACZnG,EAAAA,IAACqF,GAAA,CAAa,IAAKyF,GAAa,SAAUD,EAAY,KAAM,EAE7D1E,IAAa,OACZnG,EAAAA,IAACuF,GAAA,CAAY,IAAKuF,GAAa,SAAUD,EAAY,KAAM,EAE5D1E,IAAa,OACZnG,EAAAA,IAACyF,GAAA,CAAY,IAAKqF,GAAa,SAAUD,EAAY,KAAM,EAE5D1E,IAAa,YACZnG,EAAAA,IAAC2F,GAAA,CAAiB,IAAKmF,GAAa,SAAUD,EAAY,KAAM,EAEjE1E,IAAa,QACZgB,GAAmBV,GACjBzG,EAAAA,IAACiG,GAAA,CACC,SAAU4E,EAAY,KACtB,SAAUA,EAAY,KACtB,WAAYyB,EAAA,CAAA,QAGbzG,GAAA,CAAY,IAAKiF,GAAa,cAAe8B,GAAsB,aAAczF,CAAA,CAAiB,GAGtGhB,IAAa,QACZnG,EAAAA,IAAC+F,GAAA,CACC,IAAK+E,GACL,SAAUD,EAAY,KACtB,SAAUf,GACV,YAAaE,EAAA,CAAA,EAGhB7D,IAAa,eACZnG,EAAAA,IAACiG,GAAA,CACC,SAAU4E,EAAY,KACtB,SAAUA,EAAY,KACtB,WAAYyB,EAAA,CAAA,CACd,CAAA,CAEJ,CAAA,CAAA,EAKH,CAACjF,GAAYsD,GAAgB,OAAS,GACrCtE,OAAAwH,EAAAA,SAAA,CACG,SAAA,CAAA/G,EAAe,GACd9G,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAASvD,GAAa,EAAI,EAAG,EAAGA,GAAa,EAAI,GAAA,EAC5D,WAAY,CAAE,SAAU,EAAA,EACxB,QAAS,IAAMrD,GAAA,YAAAA,EAAaD,EAAe,GAC3C,aAAc,IAAMuD,GAAc,EAAI,EACtC,MAAO,CAAE,cAAeD,GAAa,OAAS,MAAA,EAC9C,UAAU,qVAEV,SAAApK,EAAAA,IAACwB,EAAAA,YAAA,CAAY,UAAU,uCAAA,CAAwC,CAAA,CAAA,EAIlEsF,EAAe6D,GAAgB,OAAS,GACvC3K,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAASvD,GAAa,EAAI,EAAG,EAAGA,GAAa,EAAI,EAAA,EAC5D,WAAY,CAAE,SAAU,EAAA,EACxB,QAAS,IAAMrD,GAAA,YAAAA,EAAaD,EAAe,GAC3C,aAAc,IAAMuD,GAAc,EAAI,EACtC,MAAO,CAAE,cAAeD,GAAa,OAAS,MAAA,EAC9C,UAAU,uVAEV,SAAApK,EAAAA,IAACyB,EAAAA,aAAA,CAAa,UAAU,uCAAA,CAAwC,CAAA,CAAA,CAClE,CAAA,CAEJ,CAAA,CAAA,CAAA,EAGJ,CAAA,CACA,CAEJ,EAUMiM,GAA8C,CAAC,CAAE,KAAAI,EAAM,MAAAC,EAAO,QAAAC,EAAS,SAAAC,KAEzE5H,EAAAA,KAAC,SAAA,CACC,QAAA2H,EACA,SAAAC,EACA,UAAW,iGACTA,EACI,8CACA,oEACN,GAEC,SAAA,CAAAH,EACDzH,EAAAA,KAAC,OAAA,CAAK,UAAU,wUACd,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,UAAU,2GAAA,CAA4G,EAC5HA,EAAAA,IAAC,OAAA,CAAK,UAAU,eAAgB,SAAA+N,CAAA,CAAM,CAAA,CAAA,CACxC,CAAA,CAAA,CAAA,sHCjoBOG,GAAoD,CAAC,CAChE,MAAArH,EACA,aAAAC,EACA,OAAAqH,EACA,QAAAjH,EACA,WAAAH,EACA,gBAAAC,EAAkB,CAAA,EAClB,OAAAtH,EACA,SAAAC,EACA,SAAA0H,EACA,MAAA5G,EAAQ,OACR,cAAA6G,EACA,YAAA3E,EACA,eAAAC,EACA,kBAAAC,EACA,WAAAuD,CACF,IAAM,CACJ,KAAM,CAACsB,EAAYC,CAAa,EAAIrE,EAAAA,SAAS,IAC3C,OAAO,OAAW,IACd,OAAO,WAAW,8BAA8B,EAAE,QAClD,EAAA,EAGNG,EAAAA,UAAU,IAAM,CACd,GAAIhD,IAAU,OAAQ,OACtB,MAAMmH,EAAM,OAAO,WAAW,8BAA8B,EACtDC,EAAWtN,GAA2BoN,EAAcpN,EAAE,OAAO,EACnE,OAAAqN,EAAI,iBAAiB,SAAUC,CAAO,EAC/B,IAAMD,EAAI,oBAAoB,SAAUC,CAAO,CACxD,EAAG,CAACpH,CAAK,CAAC,EAEV,MAAMqH,EAAgBrH,IAAU,OAAUiH,EAAa,OAAS,QAAWjH,EAsB3E,GAnBAgD,EAAAA,UAAU,IAAM,CACd,GAAI0K,EAAQ,CACV,MAAMC,EAAmB,SAAS,KAAK,MAAM,SACvCC,EAAuB,SAAS,KAAK,MAAM,aAE3CC,EAAiB,OAAO,WAAa,SAAS,gBAAgB,YAEpE,gBAAS,KAAK,MAAM,SAAW,SAC3BA,EAAiB,IACnB,SAAS,KAAK,MAAM,aAAe,GAAGA,CAAc,MAG/C,IAAM,CACX,SAAS,KAAK,MAAM,SAAWF,EAC/B,SAAS,KAAK,MAAM,aAAeC,CACrC,CACF,CACF,EAAG,CAACF,CAAM,CAAC,EAEP,CAACA,EAAQ,OAAO,KAEpB,MAAMI,QACH,MAAA,CAAI,UAAU,WAAW,aAAYzG,EACpC,SAAA9H,EAAAA,IAACwO,GAAAA,gBAAA,CACE,SAAAL,GACCnO,EAAAA,IAAC2N,GAAAA,OAAO,IAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAAS,CAAA,EACpB,KAAM,CAAE,QAAS,CAAA,EACjB,UAAU,kJACV,QAASzG,EACT,QAAU3M,GAAMA,EAAE,gBAAA,EAElB,SAAAyF,EAAAA,IAAC,MAAA,CACC,UAAU,qCACV,QAAUzF,GAAMA,EAAE,gBAAA,EAElB,SAAAyF,EAAAA,IAAC0G,GAAA,CACC,KAAK,QACL,MAAAG,EACA,aAAAC,EACA,QAAAI,EACA,WAAAH,EACA,gBAAAC,EACA,OAAAtH,EACA,SAAAC,EACA,SAAA0H,EACA,MAAA5G,EACA,cAAA6G,EACA,YAAA3E,EACA,eAAAC,EACA,kBAAAC,EACA,WAAAuD,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EAGN,CAAA,CACF,EAGF,OAAOqI,gBAAaF,EAAc,SAAS,IAAI,CACjD,EC9FaG,GAAoD,CAAC,CAChE,MAAA7H,EACA,aAAAC,EAAe,EACf,WAAAC,EACA,gBAAAC,EAAkB,CAAA,EAClB,MAAA2H,EAAQ,OACR,OAAAC,EAAS,OACT,UAAAhO,EACA,MAAAiO,EACA,OAAAnP,EACA,SAAAC,EACA,SAAA0H,EACA,MAAA5G,EAAQ,OACR,cAAA6G,EACA,YAAA3E,EACA,eAAAC,EACA,kBAAAC,EACA,WAAAuD,CACF,IAAM,CACJ,KAAM,CAACsB,EAAYC,CAAa,EAAIrE,EAAAA,SAAS,IAC3C,OAAO,OAAW,IACd,OAAO,WAAW,8BAA8B,EAAE,QAClD,EAAA,EAGNG,EAAAA,UAAU,IAAM,CACd,GAAIhD,IAAU,OAAQ,OACtB,MAAMmH,EAAM,OAAO,WAAW,8BAA8B,EACtDC,EAAWtN,GAA2BoN,EAAcpN,EAAE,OAAO,EACnE,OAAAqN,EAAI,iBAAiB,SAAUC,CAAO,EAC/B,IAAMD,EAAI,oBAAoB,SAAUC,CAAO,CACxD,EAAG,CAACpH,CAAK,CAAC,EAEV,MAAMqH,EAAgBrH,IAAU,OAAUiH,EAAa,OAAS,QAAWjH,EAE3E,OACET,EAAAA,IAAC,MAAA,CACC,UAAW,YAAYY,GAAa,EAAE,GACtC,MAAO,CAAE,MAAA+N,EAAO,OAAAC,EAAQ,GAAGC,CAAA,EAC3B,aAAY/G,EAEZ,SAAA9H,EAAAA,IAAC,MAAA,CAAI,UAAU,gFACb,SAAAA,EAAAA,IAAC0G,GAAA,CACC,KAAK,QACL,MAAAG,EACA,aAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,OAAAtH,EACA,SAAAC,EACA,SAAA0H,EACA,MAAA5G,EACA,cAAA6G,EACA,YAAA3E,EACA,eAAAC,EACA,kBAAAC,EACA,WAAAuD,CAAA,CAAA,CACF,CACF,CAAA,CAAA,CAGN,ECrDO,SAAS0I,GAAeC,EAA4B,CACzD,GAAI,OAAO,OAAW,IAAa,OAEnC,KAAM,CACJ,UAAAC,EAAY,gCAAgCC,SAAM,OAAO,4BACzD,QAAAC,EAAU,gCAAgCD,SAAM,OAAO,UACvD,WAAAE,EAAa,EAAA,EACXJ,GAAW,CAAA,EAEfE,SAAM,oBAAoB,UAAYD,EAEtCC,SAAM,oBAAoB,QAAUC,EAEpCD,SAAM,oBAAoB,WAAaE,CACzC,CAGAL,GAAA,ECtDO,MAAMM,GAAUC,GAAY,QCQtBvL,GAA8C,CAAC,CAC1D,IAAAvB,EACA,KAAAwF,EACA,SAAAE,EACA,SAAAqH,EACA,SAAAC,EACA,aAAAC,EACA,qBAAAC,EACA,sBAAAC,CACF,IAAM,CACJ,MAAMhV,EAAIyF,EAAA,EACJ,CAACwP,EAAQC,CAAS,EAAItM,EAAAA,SAAS,EAAK,EACpC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAACyM,EAAUC,CAAW,EAAI1M,EAAAA,SAAS,CAAE,EAAG,EAAG,EAAG,EAAG,EACjD,CAAC2M,EAAYC,CAAa,EAAI5M,EAAAA,SAAS,EAAK,EAC5C,CAAC6M,EAAWC,CAAY,EAAI9M,EAAAA,SAAS,CAAE,EAAG,EAAG,EAAG,EAAG,EACnD,CAAC+M,EAAcC,CAAe,EAAIhN,EAAAA,SAAS,CAAC,EAC5C,CAACiN,EAAaC,CAAc,EAAIlN,EAAAA,SAAS,CAAE,MAAO,EAAG,OAAQ,EAAG,EAChEmN,EAASjN,EAAAA,OAAyB,IAAI,EACtCkN,EAAelN,EAAAA,OAAuB,IAAI,EAEhDC,EAAAA,UAAU,IAAM,CACdmM,EAAU,EAAK,EACfE,EAAS,IAAI,EACbE,EAAY,CAAE,EAAG,EAAG,EAAG,EAAG,EAC1BM,EAAgB,CAAC,CACnB,EAAG,CAAC/N,CAAG,CAAC,EAGRkB,EAAAA,UAAU,IAAM,CACd6M,EAAgBvI,CAAI,CACtB,EAAG,CAACA,CAAI,CAAC,EAGTtE,EAAAA,UAAU,IAAM,CACV6L,IAAa,QACfU,EAAY,CAAE,EAAG,EAAG,EAAG,EAAG,CAE9B,EAAG,CAACV,CAAQ,CAAC,EAEb,MAAMqB,EAAcpW,GAA8C,CAChEqV,EAAU,EAAI,EACd,MAAMgB,EAAMrW,EAAE,cACdiW,EAAe,CAAE,MAAOI,EAAI,aAAc,OAAQA,EAAI,cAAe,EACrEnB,GAAA,MAAAA,EAAuBmB,EAAI,cAC3BlB,GAAA,MAAAA,EAAwBkB,EAAI,cAC9B,EAGMC,EAAgBpG,EAAAA,YAAY,CAACqG,EAA+BC,IAAwB,CACxF,MAAMC,EAAYN,EAAa,QAC/B,GAAI,CAACM,GAAaT,EAAY,QAAU,EAAG,OAAOO,EAElD,MAAMG,EAAaD,EAAU,YACvBE,EAAaF,EAAU,aACvBG,EAAOZ,EAAY,MAAQQ,EAC3BK,EAAOb,EAAY,OAASQ,EAG5BM,EAAS,KAAK,IAAI,GAAIJ,EAAa,IAAMC,EAAa,GAAI,EAC1DI,GAAUL,EAAaE,GAAQ,EAAIE,EACnCE,GAAUL,EAAaE,GAAQ,EAAIC,EAEzC,MAAO,CACL,EAAGC,EAAS,EAAI,KAAK,IAAI,CAACA,EAAQ,KAAK,IAAIA,EAAQR,EAAI,CAAC,CAAC,EAAI,EAC7D,EAAGS,EAAS,EAAI,KAAK,IAAI,CAACA,EAAQ,KAAK,IAAIA,EAAQT,EAAI,CAAC,CAAC,EAAI,CAAA,CAEjE,EAAG,CAACP,CAAW,CAAC,EAEViB,EAAc,IAAM,CACxB1B,EAASpV,EAAE,mBAAmB,CAAC,EAC/BkV,EAAU,EAAI,CAChB,EAGM6B,EAAoB,IAAM,CAC9BzB,EAAY,CAAE,EAAG,EAAG,EAAG,EAAG,EAC1BM,EAAgB,CAAC,EACjBd,GAAA,MAAAA,EAAe,EACjB,EAKA/L,EAAAA,UAAU,IAAM,CACd,MAAMuN,EAAYN,EAAa,QAC/B,GAAI,CAACM,EAAW,OAEhB,MAAMU,EAAqBnX,GAAkB,CAC3CA,EAAE,eAAA,EACFA,EAAE,gBAAA,EAEF,MAAMoX,EAAOX,EAAU,sBAAA,EACjBY,EAASrX,EAAE,QAAUoX,EAAK,KAAOA,EAAK,MAAQ,EAC9CE,EAAStX,EAAE,QAAUoX,EAAK,IAAMA,EAAK,OAAS,EAE9CG,EAAQvX,EAAE,OAAS,EAAI,KAAQ,IAErC+V,EAAgBxE,GAAQ,CACtB,MAAMJ,EAAU,KAAK,IAAI,IAAM,KAAK,IAAI,GAAII,EAAOgG,CAAK,CAAC,EACnDC,EAAQrG,EAAUI,EAExB,OAAAkE,KAAmBa,EAAc,CAC/B,EAAGe,EAASG,GAASH,EAASd,EAAI,GAClC,EAAGe,EAASE,GAASF,EAASf,EAAI,EAAA,EACjCpF,CAAO,CAAC,EAEX8D,GAAA,MAAAA,EAAe9D,GACRA,CACT,CAAC,CACH,EAEA,OAAAsF,EAAU,iBAAiB,QAASU,EAAmB,CAAE,QAAS,GAAO,EAClE,IAAMV,EAAU,oBAAoB,QAASU,CAAiB,CACvE,EAAG,CAAClC,EAAcqB,CAAa,CAAC,EAEhC,MAAMmB,EAAkBvH,cAAalQ,GAAwB,CACvDA,EAAE,SAAW,IACjB2V,EAAc,EAAI,EAClBE,EAAa,CACX,EAAG7V,EAAE,QAAUwV,EAAS,EACxB,EAAGxV,EAAE,QAAUwV,EAAS,CAAA,CACzB,EACH,EAAG,CAACA,CAAQ,CAAC,EAEPrF,EAAkBD,cAAalQ,GAAwB,CACtD0V,GACLD,EAAYa,EAAc,CACxB,EAAGtW,EAAE,QAAU4V,EAAU,EACzB,EAAG5V,EAAE,QAAU4V,EAAU,CAAA,EACxBE,CAAY,CAAC,CAClB,EAAG,CAACJ,EAAYE,EAAWE,EAAcQ,CAAa,CAAC,EAEjDoB,EAAgBxH,EAAAA,YAAY,IAAM,CACtCyF,EAAc,EAAK,CACrB,EAAG,CAAA,CAAE,EAEL,OACE7J,EAAAA,KAAC,MAAA,CACC,IAAKqK,EACL,UAAU,sGACV,YAAasB,EACb,YAAatH,EACb,UAAWuH,EACX,aAAcA,EACd,MAAO,CAAE,OAAQhC,EAAa,WAAa,MAAA,EAE1C,SAAA,CAAA,CAACN,GAAU,CAACE,GACX7P,EAAAA,IAAC,MAAA,CAAI,UAAU,+CACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,mHAAA,CAAoH,CAAA,CACrI,EAGD6P,GACC7P,EAAAA,IAAC,MAAA,CAAI,UAAU,wCACb,eAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,CAAA,CACpC,EAGF7P,EAAAA,IAAC2N,GAAAA,OAAO,IAAP,CACC,IAAK8C,EACL,IAAKlO,EACL,IAAI,UACJ,UAAW,kCAAmCoN,EAAwB,GAAf,YAAiB,GACxE,MAAO,CACL,UAAW,aAAaI,EAAS,CAAC,OAAOA,EAAS,CAAC,aAAaM,CAAY,YAAYpI,CAAQ,OAChG,gBAAiB,SACjB,WAAYgI,EAAa,OAAS,yBAAA,EAEpC,OAAQU,EACR,QAASa,EACT,cAAeC,EACf,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAAS9B,EAAS,EAAI,CAAA,EACjC,WAAY,CAAE,SAAU,EAAA,EACxB,UAAW,EAAA,CAAA,EAIZA,GAAU,CAACE,GAASU,EAAY,MAAQ,GACvClK,EAAAA,KAAC,MAAA,CAAI,UAAU,0LACZ,SAAA,CAAAkK,EAAY,MAAM,MAAIA,EAAY,OAAQhB,GAAY,MAAQ,MAAMA,EAAW,KAAO,GAAGA,CAAQ,KAAOA,EAAW,KAAO,KAAO,IAAIA,EAAW,MAAM,QAAQ,CAAC,CAAC,MAAQ,IAAIA,GAAY,KAAO,OAAO,QAAQ,CAAC,CAAC,KAAK,EAAA,CAAA,CACxN,CAAA,CAAA,CAAA,CAIR,iHCzLatL,GAA0C,CAAC,CACtD,IAAA1B,EACA,KAAAwF,EACA,YAAAI,EACA,aAAA+J,EACA,mBAAAC,EACA,kBAAAC,CACF,IAAM,CACJ,MAAM1X,EAAIyF,EAAA,EACJ,CAACkS,EAAUC,CAAW,EAAIhP,EAAAA,SAAiB,CAAC,EAC5C,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChDoN,EAAelN,EAAAA,OAAuB,IAAI,EAC1C+O,EAAW/O,EAAAA,OAAoC,IAAI,GAAK,EAE9DC,EAAAA,UAAU,IAAM,CACdqM,EAAS,IAAI,CACf,EAAG,CAACvN,CAAG,CAAC,EAER,MAAMiQ,EAAwB,CAAC,CAAE,SAAAH,KAAqC,CACpEC,EAAYD,CAAQ,EACpBF,EAAmBE,CAAQ,EAC3BH,EAAa,CAAC,CAChB,EAEMO,EAAuB5C,GAAiB,CAC5C,QAAQ,MAAM,YAAaA,CAAK,EAChCC,EAASpV,EAAE,iBAAiB,CAAC,CAC/B,EAGMgY,EAAejI,EAAAA,YAAY,IAAM,CACrC,GAAI,CAACiG,EAAa,QAAS,OAE3B,MAAMM,EAAYN,EAAa,QACzBiC,EAAY3B,EAAU,UACtBzF,EAAkByF,EAAU,aAC5B4B,EAAeD,EAAYpH,EAAkB,EAGnD,IAAIsH,EAAqB,EACrBC,EAAc,IAElBP,EAAS,QAAQ,QAAQ,CAACQ,EAAaC,IAAe,CACpD,MAAMrB,EAAOoB,EAAY,sBAAA,EACnBE,EAAgBjC,EAAU,sBAAA,EAC1BkC,EAAavB,EAAK,IAAMsB,EAAc,IAAMtB,EAAK,OAAS,EAAIgB,EAC9DQ,EAAW,KAAK,IAAID,EAAaN,CAAY,EAE/CO,EAAWL,IACbA,EAAcK,EACdN,EAAqBG,EAEzB,CAAC,EAEGH,IAAuB1K,GACzB+J,EAAaW,CAAkB,CAEnC,EAAG,CAAC1K,EAAa+J,CAAY,CAAC,EAG9BzO,EAAAA,UAAU,IAAM,CACd,MAAMuN,EAAYN,EAAa,QAC/B,GAAKM,EAEL,OAAAA,EAAU,iBAAiB,SAAU0B,CAAY,EAC1C,IAAM1B,EAAU,oBAAoB,SAAU0B,CAAY,CACnE,EAAG,CAACA,CAAY,CAAC,EAGjB,MAAMU,EAAa3I,EAAAA,YAAY,CAACuI,EAAoBK,IAAmC,CACjFA,EACFd,EAAS,QAAQ,IAAIS,EAAYK,CAAO,EAExCd,EAAS,QAAQ,OAAOS,CAAU,CAEtC,EAAG,CAAA,CAAE,EAEL,OACE3M,EAAAA,KAAC,MAAA,CACC,IAAKqK,EACL,UAAU,2HAET,SAAA,CAAAb,GACC7P,EAAAA,IAAC,OAAI,UAAU,wCACb,eAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,CAAA,CACpC,EAGD,CAACA,GACA7P,EAAAA,IAACsT,GAAAA,SAAA,CACC,KAAM/Q,EACN,cAAeiQ,EACf,YAAaC,EACb,cACG,MAAA,CAAI,UAAU,gEACb,SAAAzS,EAAAA,IAAC,MAAA,CAAI,UAAU,mHAAA,CAAoH,CAAA,CACrI,EAGF,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,kCACZ,SAAA,MAAM,KAAK,IAAI,MAAMqS,CAAQ,EAAG,CAAC5U,EAAGuI,IAAU,CAC7C,MAAMgN,EAAahN,EAAQ,EAC3B,OACEK,EAAAA,KAAC,MAAA,CAEC,IAAMuF,GAAOwH,EAAWJ,EAAYpH,CAAE,EACtC,UAAU,eAEV,SAAA,CAAA5L,EAAAA,IAACuT,GAAAA,KAAA,CACC,WAAAP,EACA,MAAOjL,EACP,cACG,MAAA,CAAI,UAAU,yGACb,SAAA/H,EAAAA,IAAC,MAAA,CAAI,UAAU,iHAAA,CAAkH,CAAA,CACnI,EAEF,gBAAiB,GACjB,sBAAuB,GACvB,UAAU,iBACV,gBAAkBwT,GAAS,CACrBR,IAAe,GAAKZ,GAEtBA,EAAkBoB,EAAK,eAAiBA,EAAK,MAAQzL,CAAI,CAE7D,CAAA,CAAA,EAGF/H,EAAAA,IAAC,MAAA,CAAI,UAAU,sJACZ,SAAAgT,CAAA,CACH,CAAA,CAAA,EAzBK,QAAQA,CAAU,EAAA,CA4B7B,CAAC,CAAA,CACH,CAAA,CAAA,EAKHX,EAAW,GACVhM,OAAC,MAAA,CAAI,UAAU,sRAAsR,SAAA,CAAA,KAChS8B,EAAY,UAAQkK,EAAS,IAAA,CAAA,CAClC,CAAA,CAAA,CAAA,CAIR,+GCvJMoB,GAAc,KACdC,GAAiB,GACjBC,GAAiB,GACjBC,GAAsBH,GAAcC,GAAiB,EACrDG,GAAW,GAEXC,GAAoC,CACxC,WAAY,uCACZ,WAAY,MACZ,MAAO,MACT,EAEa3P,GAA4C,CAAC,CAAE,IAAA5B,KAAU,CACpE,MAAM,EAAIpC,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACgR,EAAMC,CAAO,EAAI1Q,EAAAA,SAAiB,EAAE,EACrC,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAAC6Q,EAAOC,CAAQ,EAAI9Q,EAAAA,SAAmB,CAAA,CAAE,EACzC+Q,EAAa7Q,EAAAA,OAAuB,IAAI,EAE9CC,EAAAA,UAAU,IAAM,EACG,SAAY,CAC3ByQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACbkE,EAAQ,EAAE,EAEV,GAAI,CACF,MAAMM,EAAW,MAAMpR,EAAQX,CAAG,EAClC,GAAI,CAAC+R,EAAS,GACZ,MAAM,IAAI,MAAM,QAAQ,EAG1B,MAAMC,EAAc,MAAMD,EAAS,YAAA,EAC7BE,EAAS,MAAMC,GAAQ,cAAc,CAAE,YAAAF,EAAa,EAC1DP,EAAQQ,EAAO,KAAK,CACtB,OAAS3Q,EAAK,CACZ,QAAQ,MAAM,aAAcA,CAAG,EAC/BiM,EAAS,EAAE,mBAAmB,CAAC,CACjC,QAAA,CACEoE,EAAW,EAAK,CAClB,CACF,GAEA,CACF,EAAG,CAAC3R,EAAKW,EAAS,CAAC,CAAC,EAEpB,MAAMwR,EAAWjK,EAAAA,YAAY,IAAM,CACjC,MAAMuG,EAAYqD,EAAW,QAC7B,GAAI,CAACrD,GAAa,CAAC+C,EAAM,OAEzB,MAAMnU,EAAW,MAAM,KAAKoR,EAAU,QAAQ,EAC9C,GAAIpR,EAAS,SAAW,EAAG,CACzBwU,EAAS,CAACL,CAAI,CAAC,EACf,MACF,CAEA,MAAMS,EAAqB,CAAC,EAAE,EAC9B,IAAIG,EAAkB,EAEtB,UAAWC,KAAShV,EAAU,CAC5B,MAAMrC,EAAIqX,EAAM,aAIZD,EAAkB,GAAKA,EAAkBpX,EAAIqW,KAC/CY,EAAO,KAAK,EAAE,EACdG,EAAkB,GAGpBH,EAAOA,EAAO,OAAS,CAAC,EAAE,KAAKI,EAAM,SAAS,EAC9CD,GAAmBpX,CACrB,CAGIiX,EAAO,SAAW,GAAGA,EAAO,KAAK,CAAA,CAAE,EAEvCJ,EAASI,EAAO,IAAIK,GAAUA,EAAO,KAAK,EAAE,CAAC,CAAC,CAChD,EAAG,CAACd,CAAI,CAAC,EAST,OAPAtQ,EAAAA,UAAU,IAAM,CACV,CAACsQ,GAAQ,CAACM,EAAW,SACzB,sBAAsB,IAAM,CAC1BK,EAAA,CACF,CAAC,CACH,EAAG,CAACX,EAAMW,CAAQ,CAAC,EAEfT,EAEAjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIA6P,EAEA7P,EAAAA,IAAC,MAAA,CAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,EACpC,EACF,EAKFxJ,EAAAA,KAAC,MAAA,CACC,UAAU,0CACV,MAAO,CAAE,WAAY,qBAAA,EAGrB,SAAA,CAAArG,EAAAA,IAAC,MAAA,CACC,IAAKqU,EACL,wBAAyB,CAAE,OAAQN,CAAA,EACnC,MAAO,CACL,GAAGD,GACH,SAAU,WACV,WAAY,SACZ,MAAO,GAAG,IAAMH,GAAiB,CAAC,KAClC,cAAe,MAAA,CACjB,CAAA,EAIF3T,EAAAA,IAAC,MAAA,CACC,UAAU,+DACV,MAAO,CAAE,IAAK,GAAG6T,EAAQ,IAAA,EAEvB,UAAAM,EAAM,OAAS,EAAIA,EAAQ,CAAC,EAAE,GAAG,IAAI,CAACW,EAAUzZ,IAChD2E,EAAAA,IAAC,MAAA,CAEC,MAAO,CACL,MAAO,OACP,SAAU,QACV,UAAW,GAAGyT,EAAW,KACzB,WAAY,QACZ,UAAW,iCACX,WAAY,EACZ,QAAS,GAAGC,EAAc,MAAMC,EAAc,IAAA,EAGhD,SAAA3T,EAAAA,IAAC,MAAA,CACC,wBAAyB,CAAE,OAAQ8U,CAAA,EACnC,MAAOhB,EAAA,CAAA,CACT,EAdKzY,CAAA,CAgBR,CAAA,CAAA,CACH,CAAA,CAAA,CAGN,gHCnJagJ,GAA4C,CAAC,CAAE,IAAA9B,KAAU,CACpE,MAAM,EAAIpC,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACkR,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChDoN,EAAelN,EAAAA,OAAuB,IAAI,EAC1CuR,EAAiBvR,EAAAA,OAA2B,IAAI,EAChDwR,EAAexR,EAAAA,OAAyC,IAAI,EAC5DyR,EAAoBzR,EAAAA,OAA8B,IAAI,EACtD0R,EAAmB1R,EAAAA,OAAsB,IAAI,EAC7C2R,EAAoB3R,EAAAA,OAAO,CAAE,MAAO,EAAG,OAAQ,EAAG,EAElD4R,EAAsB3K,EAAAA,YAAY,IAAM,CAC5C,GAAI,CAACiG,EAAa,QAAS,MAAO,CAAE,MAAO,IAAK,OAAQ,GAAA,EACxD,MAAM2E,EAAW3E,EAAa,QAAQ,YAChC4E,EAAY5E,EAAa,QAAQ,aACjC/B,EAAQ0G,EAAW,IAAMA,EAAW,IACpCzG,EAAS0G,EAAY,IAAMA,EAAY,IAC7C,MAAO,CAAE,MAAA3G,EAAO,OAAAC,CAAA,CAClB,EAAG,CAAA,CAAE,EAEC2G,EAAmB9K,EAAAA,YAAY,IAAM,CACzC,GAAI,CAACiG,EAAa,SAAW,CAACsE,EAAa,QAAS,OAGpDtE,EAAa,QAAQ,UAAY,GACjCqE,EAAe,QAAU,KAEzB,KAAM,CAAE,MAAApG,EAAO,OAAAC,CAAA,EAAWwG,EAAA,EACpBI,EAAW7G,EAAQ,IAEnBrT,EAAI,IAAIma,GAAY/E,EAAa,QAAS,CAC9C,KAAM,OACN,YAAa,GACb,gBAAiB,GACjB,SAAU,GACV,IAAK,CACH,IAAK,IACL,OAAQ,EAAA,EAEV,IAAK,CACH,IAAK,GACL,MAAO8E,EAAW,GAAK,IACvB,WAAYA,EAAW,GAAK,GAC5B,SAAUA,EAAW,GAAK,EAAA,EAE5B,KAAM,CACJ,OAAQ,IAAM5G,EACd,MAAO,IAAMD,CAAA,CACf,CACD,EAEDrT,EAAE,SAAS0Z,EAAa,OAA6C,EACrED,EAAe,QAAUzZ,CAC3B,EAAG,CAAC8Z,CAAmB,CAAC,EAGxB3R,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAACiN,EAAa,QAAS,OAE3B,IAAIgF,EAAkB,GAEtB,MAAMC,EAAmB,IAAM,CAC7B,GAAID,EAAiB,CACnBA,EAAkB,GAClBP,EAAkB,QAAUC,EAAA,EAC5B,MACF,CAEA,MAAMQ,EAAgBR,EAAA,EAChBS,EAAiBV,EAAkB,QACnCW,EAAY,KAAK,IAAID,EAAe,MAAQD,EAAc,KAAK,EAC/DG,EAAa,KAAK,IAAIF,EAAe,OAASD,EAAc,MAAM,EAEpEE,EAAY,IAAMC,EAAa,KAEnCZ,EAAkB,QAAUS,EAExBV,EAAiB,SACnB,aAAaA,EAAiB,OAAO,EAGvCA,EAAiB,QAAU,OAAO,WAAW,IAAM,CAC7CF,EAAa,SACfO,EAAA,CAEJ,EAAG,GAAG,EACR,EAEA,OAAAN,EAAkB,QAAU,IAAI,eAAe,IAAM,CACnDU,EAAA,CACF,CAAC,EAEDV,EAAkB,QAAQ,QAAQvE,EAAa,OAAO,EAE/C,IAAM,CACPuE,EAAkB,SACpBA,EAAkB,QAAQ,WAAA,EAExBC,EAAiB,SACnB,aAAaA,EAAiB,OAAO,CAEzC,CACF,EAAG,CAACE,EAAqBG,CAAgB,CAAC,EAE1C9R,EAAAA,UAAU,IAAM,CACd,IAAIuS,EAAY,GAEhB,MAAMC,EAAY,SAAY,CAC5B,GAAKvF,EAAa,QAElB,CAAAwD,EAAW,EAAI,EACfpE,EAAS,IAAI,EAEb,GAAI,CACF,MAAMwE,EAAW,MAAMpR,EAAQX,EAAK,CAClC,KAAM,OACN,YAAa,OACb,SAAU,QAAA,CACX,EAED,GAAI,CAAC+R,EAAS,GACZ,MAAIA,EAAS,SAAW,IAChB,IAAI,MAAM,EAAE,gBAAgB,CAAC,EAC1BA,EAAS,SAAW,IACvB,IAAI,MAAM,UAAU,EAEpB,IAAI,MAAM,WAAWA,EAAS,MAAM,GAAG,EAIjD,MAAMC,EAAc,MAAMD,EAAS,YAAA,EAEnC,GAAIC,EAAY,aAAe,EAC7B,MAAM,IAAI,MAAM,MAAM,EAIxB,MAAM2B,EAAW,IAAIC,GAAQ,SAC7B,MAAMD,EAAS,KAAK,KAAK3B,CAAW,EAGpC,MAAM6B,EAAYC,GAAiCH,CAAQ,EAE3D,GAAI,CAACF,EAAW,OAEhBhB,EAAa,QAAUoB,EAGvBb,EAAA,EAEArB,EAAW,EAAK,CAClB,OAASrQ,EAAK,CACZ,GAAImS,EAAW,CACb,QAAQ,MAAM,cAAenS,CAAG,EAChC,IAAIyS,EAAW,EAAE,mBAAmB,EAChCzS,aAAe,QACjByS,EAAWzS,EAAI,SAEjBiM,EAASwG,CAAQ,EACjBpC,EAAW,EAAK,CAClB,CACF,EACF,EAEMqC,EAAQ,WAAW,IAAM,CAC7B,sBAAsB,IAAM,CAC1BN,EAAA,CACF,CAAC,CACH,EAAG,GAAG,EAEN,MAAO,IAAM,CACXD,EAAY,GACZ,aAAaO,CAAK,EAClBvB,EAAa,QAAU,KACnBtE,EAAa,UACfA,EAAa,QAAQ,UAAY,IAEnCqE,EAAe,QAAU,IAC3B,CACF,EAAG,CAACxS,EAAKgT,CAAgB,CAAC,EAGxBlP,EAAAA,KAAC,MAAA,CAAI,UAAU,4EAEZ,SAAA,CAAA4N,SACE,MAAA,CAAI,UAAU,6HACb,SAAA5N,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,gKAAA,CAAiK,QAC/K,IAAA,CAAE,UAAU,mEAAoE,SAAA,EAAE,cAAc,CAAA,CAAE,CAAA,CAAA,CACrG,CAAA,CACF,EAID6P,GAAS,CAACoE,GACTjU,EAAAA,IAAC,MAAA,CAAI,UAAU,6HACb,SAAAqG,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAArG,EAAAA,IAAC,OAAI,UAAU,yPACb,eAACwW,EAAAA,gBAAA,CAAgB,UAAU,gEAAgE,CAAA,CAC7F,QACC,IAAA,CAAE,UAAU,sFAAuF,SAAA,EAAE,kBAAkB,EAAE,EAC1HxW,EAAAA,IAAC,IAAA,CAAE,UAAU,uEACV,SAAA6P,EACH,EACAxJ,EAAAA,KAAC,IAAA,CACC,KAAM9D,EACN,SAAQ,GACR,UAAU,uRAEV,SAAA,CAAAvC,EAAAA,IAAC,OAAI,UAAU,wCAAwC,KAAK,OAAO,OAAO,eAAe,QAAQ,YAC/F,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,iEAAiE,CAAA,CACxI,EACC,EAAE,iBAAiB,CAAA,CAAA,CAAA,EAEtBA,EAAAA,IAAC,IAAA,CAAE,UAAU,qDAAqD,SAAA,kCAAA,CAElE,CAAA,CAAA,CACF,CAAA,CACF,EAID,CAAC6P,GACA7P,EAAAA,IAAC,MAAA,CACC,IAAK0Q,EACL,UAAU,mDACV,MAAO,CAAE,QAASuD,EAAU,EAAI,CAAA,CAAE,CAAA,CACpC,EAEJ,CAEJ,gHCzOa1P,GAA4C,CAAC,CAAE,IAAAhC,EAAK,MAAAkU,EAAQ,MAAW,CAClF,MAAM/b,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACkR,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAACoT,EAAYC,CAAa,EAAIrT,EAAAA,SAAS,CAAC,EACxCoN,EAAelN,EAAAA,OAAuB,IAAI,EAC1CoT,EAAepT,EAAAA,OAAuC,IAAI,EAC1DyR,EAAoBzR,EAAAA,OAA8B,IAAI,EACtDqT,EAAiBrT,EAAAA,OAA2B,IAAI,EAChD0R,EAAmB1R,EAAAA,OAAsB,IAAI,EAC7C2R,EAAoB3R,EAAAA,OAAO,CAAE,MAAO,EAAG,OAAQ,EAAG,EAGlD4R,EAAsB3K,EAAAA,YAAY,IAAM,OAC5C,GAAI,CAACiG,EAAa,QAAS,MAAO,CAAE,MAAO,IAAK,OAAQ,GAAA,EACxD,MAAM2E,EAAW3E,EAAa,QAAQ,YAChCoG,IAAcvV,EAAAmP,EAAa,QAAQ,gBAArB,YAAAnP,EAAoC,cAAe,EAEjE+J,EAAiB+J,EAAW,IAAMA,EAAYyB,EAAc,IAAMA,EAAc,IAEhFlI,EAAS,KAAK,MAAMtD,EAAiB,EAAI,EAAE,EACjD,MAAO,CAAE,MAAOA,EAAgB,OAAAsD,CAAA,CAClC,EAAG,CAAA,CAAE,EAGCmI,EAAwBtM,EAAAA,YAAY,SAAY,CACpD,GAAI,GAACiG,EAAa,SAAW,CAACmG,EAAe,SAAWH,IAAe,GAEvE,GAAI,CAEF,GAAIE,EAAa,QACf,GAAI,CACFA,EAAa,QAAQ,QAAA,CACvB,MAAQ,CAER,CAIFlG,EAAa,QAAQ,UAAY,GAGjC,MAAMsG,EAAoB5B,EAAA,EAGpB6B,EAAYzU,GAAAA,KAAKkO,EAAa,QAAS,CAC3C,MAAOsG,EAAkB,MACzB,OAAQP,EAAQO,EAAkB,OAASN,EAAaM,EAAkB,OAC1E,KAAMP,EAAQ,OAAS,OAAA,CACxB,EACDG,EAAa,QAAUK,EAGvB,MAAMA,EAAU,QAAQJ,EAAe,OAAO,CAChD,MAAQ,CAER,CACF,EAAG,CAACzB,EAAqBqB,EAAOC,CAAU,CAAC,EAG3CjT,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAACiN,EAAa,QAAS,OAE3B,IAAIgF,EAAkB,GAEtB,MAAMC,EAAmB,IAAM,CAE7B,GAAID,EAAiB,CACnBA,EAAkB,GAClBP,EAAkB,QAAUC,EAAA,EAC5B,MACF,CAEA,MAAMQ,EAAgBR,EAAA,EAGhBS,EAAiBV,EAAkB,QACnCW,EAAY,KAAK,IAAID,EAAe,MAAQD,EAAc,KAAK,EAC/DG,EAAa,KAAK,IAAIF,EAAe,OAASD,EAAc,MAAM,EAEpEE,EAAY,IAAMC,EAAa,KAKnCZ,EAAkB,QAAUS,EAGxBV,EAAiB,SACnB,aAAaA,EAAiB,OAAO,EAIvCA,EAAiB,QAAU,OAAO,WAAW,IAAM,CAC7C0B,EAAa,SAAWC,EAAe,SACzCE,EAAA,CAEJ,EAAG,GAAG,EACR,EAGA,OAAA9B,EAAkB,QAAU,IAAI,eAAe,IAAM,CACnDU,EAAA,CACF,CAAC,EAGDV,EAAkB,QAAQ,QAAQvE,EAAa,OAAO,EAE/C,IAAM,CACPuE,EAAkB,SACpBA,EAAkB,QAAQ,WAAA,EAExBC,EAAiB,SACnB,aAAaA,EAAiB,OAAO,CAEzC,CACF,EAAG,CAACE,EAAqB2B,CAAqB,CAAC,EAE/CtT,EAAAA,UAAU,IAAM,CACd,IAAIuS,EAAY,GACZkB,EAAkD,KAEtD,MAAMC,EAAW,SAAY,CAC3B,GAAKzG,EAAa,QAElB,CAAAwD,EAAW,EAAI,EACfpE,EAAS,IAAI,EAGboH,EAAY,WAAW,IAAM,CACvBlB,IACFlG,EAASpV,EAAE,cAAc,CAAC,EAC1BwZ,EAAW,EAAK,EAEpB,EAAG,GAAK,EAER,GAAI,CAEF,MAAMI,EAAW,MAAMpR,EAAQX,EAAK,CAClC,KAAM,OACN,YAAa,OACb,SAAU,QAAA,CACX,EAED,GAAI,CAAC+R,EAAS,GACZ,MAAIA,EAAS,SAAW,IAChB,IAAI,MAAM5Z,EAAE,gBAAgB,CAAC,EAC1B4Z,EAAS,SAAW,IACvB,IAAI,MAAM,UAAU,EACjBA,EAAS,QAAU,IACtB,IAAI,MAAM,aAAa,EAEvB,IAAI,MAAM,WAAWA,EAAS,MAAM,GAAG,EAIjD,MAAMC,EAAc,MAAMD,EAAS,YAAA,EAGnC,GAAIC,EAAY,aAAe,EAC7B,MAAM,IAAI,MAAM,MAAM,EAKxB,GAFAsC,EAAe,QAAUtC,EAErB,CAACyB,EAAW,OAGhB,MAAMoB,EAAkB,SAAS,cAAc,KAAK,EACpDA,EAAgB,MAAM,QAAU,+DAChC,SAAS,KAAK,YAAYA,CAAe,EAEzC,GAAI,CAEF,MAAMC,EAAgB7U,GAAAA,KAAK4U,EAAiB,CAC1C,MAAO,IACP,OAAQ,IACR,KAAM,OAAA,CACP,EAED,GAAI,CACF,MAAMC,EAAc,QAAQ9C,CAAW,CACzC,MAAQ,CACN,MAAM,IAAI,MAAM7Z,EAAE,qBAAqB,CAAC,CAC1C,CAEA,MAAM4c,EAAQD,EAAc,WAE5B,GAAI,CAACC,GAASA,IAAU,EACtB,MAAM,IAAI,MAAM5c,EAAE,eAAe,CAAC,EAMpC,GAFA2c,EAAc,QAAA,EAEV,CAACrB,EAAW,OAGhBW,EAAcW,CAAK,EAGf5G,EAAa,UACfA,EAAa,QAAQ,UAAY,IAGnC,MAAMsG,EAAoB5B,EAAA,EAGpB6B,EAAYzU,GAAAA,KAAKkO,EAAa,QAAS,CAC3C,MAAOsG,EAAkB,MACzB,OAAQP,EAAQO,EAAkB,OAASM,EAAQN,EAAkB,OACrE,KAAMP,EAAQ,OAAS,OAAA,CACxB,EACDG,EAAa,QAAUK,EAGvB,MAAMA,EAAU,QAAQ1C,CAAW,EAG/B2C,IACF,aAAaA,CAAS,EACtBA,EAAY,MAGVlB,GACF9B,EAAW,EAAK,CAEpB,QAAA,CAEM,SAAS,KAAK,SAASkD,CAAe,GACxC,SAAS,KAAK,YAAYA,CAAe,CAE7C,CACF,OAASvT,EAAK,CAOZ,GALIqT,IACF,aAAaA,CAAS,EACtBA,EAAY,MAGVlB,EAAW,CACb,IAAIM,EAAW5b,EAAE,mBAAmB,EAChCmJ,aAAe,MACjByS,EAAWzS,EAAI,QACN,OAAOA,GAAQ,WACxByS,EAAWzS,GAEbiM,EAASwG,CAAQ,EACjBpC,EAAW,EAAK,CAClB,CACF,EACF,EAGMqC,EAAQ,WAAW,IAAM,CAC7B,sBAAsB,IAAM,CAC1B,sBAAsB,IAAM,CAC1BY,EAAA,CACF,CAAC,CACH,CAAC,CACH,EAAG,GAAG,EAGN,MAAO,IAAM,CAQX,GAPAnB,EAAY,GACZ,aAAaO,CAAK,EACdW,GACF,aAAaA,CAAS,EAExBL,EAAe,QAAU,KACzBF,EAAc,CAAC,EACXC,EAAa,QACf,GAAI,CACFA,EAAa,QAAQ,QAAA,CACvB,MAAQ,CAER,CAEFA,EAAa,QAAU,IACzB,CACF,EAAG,CAACrU,EAAK6S,EAAqBqB,CAAK,CAAC,EAGlCpQ,EAAAA,KAAC,MAAA,CAAI,UAAU,4EAEZ,SAAA,CAAA4N,SACE,MAAA,CAAI,UAAU,6HACb,SAAA5N,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,gKAAA,CAAiK,QAC/K,IAAA,CAAE,UAAU,mEAAoE,SAAAtF,EAAE,cAAc,CAAA,CAAE,CAAA,CAAA,CACrG,CAAA,CACF,EAIDmV,GAAS,CAACoE,GACTjU,EAAAA,IAAC,MAAA,CAAI,UAAU,6HACb,SAAAqG,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAArG,EAAAA,IAAC,OAAI,UAAU,sPACb,eAACuX,EAAAA,aAAA,CAAa,UAAU,gEAAgE,CAAA,CAC1F,QACC,IAAA,CAAE,UAAU,sFAAuF,SAAA7c,EAAE,kBAAkB,EAAE,EAC1HsF,EAAAA,IAAC,IAAA,CAAE,UAAU,uEACV,SAAA6P,EACH,EACAxJ,EAAAA,KAAC,IAAA,CACC,KAAM9D,EACN,SAAQ,GACR,UAAU,uRAEV,SAAA,CAAAvC,EAAAA,IAAC,OAAI,UAAU,wCAAwC,KAAK,OAAO,OAAO,eAAe,QAAQ,YAC/F,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,iEAAiE,CAAA,CACxI,EACCtF,EAAE,iBAAiB,CAAA,CAAA,CAAA,EAEtBsF,EAAAA,IAAC,IAAA,CAAE,UAAU,qDAAqD,SAAA,uCAAA,CAElE,CAAA,CAAA,CACF,CAAA,CACF,EAID,CAAC6P,GACA7P,EAAAA,IAAC,MAAA,CACC,IAAK0Q,EACL,UAAU,0DACV,MAAO,CAAE,QAASuD,EAAU,EAAI,CAAA,CAAE,CAAA,CACpC,EAEJ,CAEJ,gHC9UA,SAASuD,GAAiBC,EAAsCC,EAAmC,CACjG,OAAKD,EACEA,EACJ,OAAQ1c,GAAMA,EAAE,YAAc2c,CAAI,EAClC,IAAK3c,GAAM,CACV,MAAMoQ,EAAOpQ,EAAE,MAAQ,GACjB4c,EAAQ5c,EAAE,aAAeA,EAAE,OAAS,GAC1C,OAAIoQ,GAAQwM,GAASxM,IAASwM,EACrB,GAAGxM,CAAI,KAAKwM,CAAK,IAEnBxM,GAAQwM,CACjB,CAAC,EACA,OAAO,OAAO,EACd,KAAK,IAAI,EAZY,EAa1B,CAEA,SAASC,GAAWC,EAAqC,CACvD,GAAI,CAACA,EAAS,MAAO,GACrB,GAAI,CACF,MAAMC,EAAO,IAAI,KAAKD,CAAO,EAC7B,OAAI,MAAMC,EAAK,QAAA,CAAS,EAAUD,EAC3BC,EAAK,eAAA,CACd,MAAQ,CACN,OAAOD,CACT,CACF,CAEA,SAASE,GAAeC,EAAoBC,EAA+B,CAEzE,GAAID,EAAO,SACT,OAAOA,EAAO,SAGhB,GAAIA,EAAO,KACT,GAAI,CAEF,OADgB,IAAI,YAAY,OAAO,EACxB,OAAOA,EAAO,IAAI,CACnC,MAAQ,CAER,CAGF,OAAIA,EAAO,KACF,kGAAkGA,EAAO,KAAK,QAAQ,KAAM,OAAO,EAAE,QAAQ,QAAS,MAAM,EAAE,QAAQ,KAAM,MAAM,CACvL,SAEG,2BAA2BC,CAAa,MACjD,CAEA,SAASC,GAAmBC,EAA0C,CACpE,OAAKA,EACoC,CACvC,WAAY,QACZ,iBAAkB,kBAClB,iCAAkC,eAClC,kBAAmB,cACnB,+BAAgC,kBAChC,gCAAiC,uBACjC,cAAe,UACf,WAAY,OACZ,iBAAkB,aAAA,EAEJA,CAAY,GAAKA,EAZP,EAa5B,CAEA,MAAMC,GAAkC,CACtC,WAAY,EACZ,MAAO,UACP,WAAY,IACZ,YAAa,MACb,WAAY,QACd,EAEMC,GAAgC,CACpC,QAAS,OACT,WAAY,aACZ,IAAK,MACL,QAAS,OACX,EAEMC,GAAqC,CACzC,WAAY,EACZ,QAAS,OACT,WAAY,SACZ,OAAQ,OACV,EAEMC,GAAiC,CACrC,WAAY,EACZ,MAAO,SACT,EAEMC,GAAkC,CACtC,MAAO,UACP,UAAW,aACX,KAAM,CACR,EAEa/T,GAA0C,CAAC,CAAE,IAAAlC,KAAU,CAClE,MAAM,EAAIpC,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACkR,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAAC0U,EAAQS,CAAS,EAAInV,EAAAA,SAA4B,IAAI,EA6B5D,GA3BAG,EAAAA,UAAU,IAAM,EACE,SAAY,CAC1ByQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb2I,EAAU,IAAI,EAEd,GAAI,CACF,MAAMnE,EAAW,MAAMpR,EAAQX,CAAG,EAClC,GAAI,CAAC+R,EAAS,GACZ,MAAM,IAAI,MAAM,QAAQ,EAG1B,MAAMC,EAAc,MAAMD,EAAS,YAAA,EAE7BoE,EADY,IAAIC,GAAUpE,CAAW,EAChB,YAAA,EAC3BkE,EAAUC,CAAQ,CACpB,OAAS7U,EAAK,CACZ,QAAQ,MAAM,YAAaA,CAAG,EAC9BiM,EAAS,EAAE,kBAAkB,CAAC,CAChC,QAAA,CACEoE,EAAW,EAAK,CAClB,CACF,GAEA,CACF,EAAG,CAAC3R,CAAG,CAAC,EAEJ0R,EACF,OACEjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIJ,GAAI6P,GAAS,CAACmI,EACZ,aACG,MAAA,CAAI,UAAU,qEACb,SAAAhY,EAAAA,IAAC,OAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,GAAS,EAAE,wBAAwB,EAAE,EACnE,CAAA,CACF,EAIJ,MAAM+I,EAAQpB,GAAiBQ,EAAO,WAAY,IAAI,EAChDa,EAAQrB,GAAiBQ,EAAO,WAAY,IAAI,EAChDc,EAAStB,GAAiBQ,EAAO,WAAY,KAAK,EAClDe,EAAaf,EAAO,YAAc,GAClCgB,EAAchB,EAAO,mBAAqBA,EAAO,aAAe,GAChEiB,EAASF,GAAcC,GAAeD,IAAeC,EACvD,GAAGD,CAAU,KAAKC,CAAW,IAC7BD,GAAcC,EACZE,EAAWtB,GAAWI,EAAO,gBAAgB,EAC7CmB,EAAevB,GAAWI,EAAO,mBAAmB,EACpDoB,EAAcxB,GAAWI,EAAO,YAAY,EAC5CqB,EAAezB,GAAWI,EAAO,oBAAoB,EACrDsB,EAAUtB,EAAO,SAAW,QAC5BuB,GAAevB,EAAO,aAAe,CAAA,GAAI,OAAQ5c,GAAM,CAACA,EAAE,gBAAgB,EAC1Eoe,EAAWzB,GAAeC,EAAQ,EAAE,gBAAgB,CAAC,EACrDG,EAAeD,GAAmBF,EAAO,YAAY,EACrDyB,EAAYzB,EAAO,WAAa,GAChC0B,EAAY1B,EACZ2B,EAAa,OAAOD,EAAU,YAAe,SAAWA,EAAU,WAAa,OAC/EE,EAAkBD,IAAe,EAAI,OAASA,IAAe,EAAI,MAAQ,GACzEE,EAAc,OAAOH,EAAU,aAAgB,SAAWA,EAAU,YAAc,OAOlFI,EAAmBD,IAAgB,QAAaA,IAAgB,GANpB,CAChD,EAAG,SACH,EAAG,WACH,EAAG,UACH,EAAG,cAAA,EAEuFA,CAAW,GAAK,GAE5G,OACE7Z,EAAAA,IAAC,MAAA,CACC,UAAU,0CACV,MAAO,CAAE,WAAY,OAAA,EAErB,SAAAqG,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,WAAY,QACZ,UAAW,MAAA,EAIb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,aAAc,oBAAqB,QAAS,gDAAiD,WAAY,SAAA,EAErH,SAAA,CAAArG,EAAAA,IAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,aAAc,SAAU,2BAA4B,WAAY,IAAK,MAAO,UAAW,WAAY,KACrH,SAAAsZ,EACH,EAGAjT,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,SAAU,2BAA4B,MAAO,SAAA,EAClG,SAAA,CAAA4S,GACC5S,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAAC+Z,QAAK,KAAM,GAAI,MAAOxB,EAAA,CAAW,CAAA,CAAE,EAChElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,OAAI,EAC7BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAS,CAAA,CAAO,CAAA,CAAA,CACnC,CAAA,EACF,EAGDL,GACCvS,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACga,SAAM,KAAM,GAAI,MAAOzB,EAAA,CAAW,CAAA,CAAE,EACjElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,KAAE,EAC3BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAI,CAAA,CAAM,CAAA,CAAA,CAClC,CAAA,EACF,EAGDC,GACCxS,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACga,SAAM,KAAM,GAAI,MAAOzB,EAAA,CAAW,CAAA,CAAE,EACjElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,KAAE,EAC3BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAK,CAAA,CAAM,CAAA,CAAA,CAClC,CAAA,EACF,EAGDC,GACCzS,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACga,SAAM,KAAM,GAAI,MAAOzB,EAAA,CAAW,CAAA,CAAE,EACjElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,MAAG,EAC5BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAM,CAAA,CAAO,CAAA,CAAA,CACnC,CAAA,EACF,EAGDI,GACC7S,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACia,YAAS,KAAM,GAAI,MAAO1B,EAAA,CAAW,CAAA,CAAE,EACpElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,OAAI,EAC7BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAU,CAAA,CAAS,CAAA,CAAA,CACrC,CAAA,EACF,EAGDC,GAAgBA,IAAiBD,GAChC7S,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACka,SAAM,KAAM,GAAI,MAAO3B,EAAA,CAAW,CAAA,CAAE,EACjElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,WAAQ,EACjCpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAW,CAAA,CAAa,CAAA,CAAA,CACzC,CAAA,EACF,EAGD,CAACD,GAAY,CAACC,GAAgBC,GAC7B/S,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACia,YAAS,KAAM,GAAI,MAAO1B,EAAA,CAAW,CAAA,CAAE,EACpElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,OAAI,EAC7BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAY,CAAA,CAAY,CAAA,CAAA,CACxC,CAAA,EACF,EAGDQ,GACCvT,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACma,OAAI,KAAM,GAAI,MAAO5B,EAAA,CAAW,CAAA,CAAE,EAC/DlS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,aAAU,EACnCpY,MAAC,QAAK,MAAO,CACX,GAAGwY,GACH,MAAOmB,IAAe,EAAI,UAAY,UACtC,WAAY,GAAA,EAEX,SAAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EACF,EAGDE,GACCzT,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACma,OAAI,KAAM,GAAI,MAAO5B,EAAA,CAAW,CAAA,CAAE,EAC/DlS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,cAAW,EACpCpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAsB,CAAA,CAAiB,CAAA,CAAA,CAC7C,CAAA,EACF,EAGD3B,GAAgBA,IAAiB,SAChC9R,EAAAA,KAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACoa,QAAK,KAAM,GAAI,MAAO7B,EAAA,CAAW,CAAA,CAAE,EAChElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,OAAI,EAC7BpY,EAAAA,IAAC,OAAA,CAAK,MAAOwY,GAAa,SAAAL,CAAA,CAAa,CAAA,CAAA,CACzC,CAAA,EACF,EAGDoB,EAAY,OAAS,GACpBlT,EAAAA,KAAC,OAAI,MAAO,CAAE,GAAGgS,GAAU,UAAW,oBAAqB,UAAW,MAAO,WAAY,QACvF,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACqa,aAAU,KAAM,GAAI,MAAO9B,EAAA,CAAW,CAAA,CAAE,EACrElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,cAAW,QACnC,MAAA,CAAI,MAAO,CAAE,GAAGI,GAAY,QAAS,OAAQ,SAAU,OAAQ,IAAK,KAAA,EAClE,WAAY,IAAI,CAACpd,EAAGC,IAAM,CACzB,MAAM8P,EAAO/P,EAAE,UAAYA,EAAE,MAAQ,OAC/Bkf,EAAOlf,EAAE,cACTmf,EAAUD,EACZA,EAAO,QACL,IAAIA,EAAO,SAAS,QAAQ,CAAC,CAAC,MAC9BA,EAAO,KACL,IAAIA,EAAO,MAAM,QAAQ,CAAC,CAAC,MAC3B,GAAGA,CAAI,KACX,GACJ,OACEjU,EAAAA,KAAC,OAAA,CAEC,MAAO,CACL,QAAS,cACT,WAAY,SACZ,IAAK,MACL,QAAS,UACT,WAAY,UACZ,aAAc,MACd,SAAU,OACV,MAAO,UACP,OAAQ,mBAAA,EAGT,SAAA,CAAA8E,EACAoP,UACE,OAAA,CAAK,MAAO,CAAE,MAAO,UAAW,SAAU,MAAA,EAAU,SAAA,CAAA,IAAEA,EAAQ,GAAA,CAAA,CAAC,CAAA,CAAA,EAf7Dlf,CAAA,CAmBX,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EACF,EAGDoe,GACCpT,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,GAAGgS,GAAU,UAAWkB,EAAY,OAAS,EAAI,OAAS,oBAAqB,UAAW,MAAO,WAAY,QACzH,SAAA,CAAAvZ,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACwa,QAAK,KAAM,GAAI,MAAOjC,EAAA,CAAW,CAAA,CAAE,EAChElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,aAAU,EACnCpY,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,GAAGwY,GAAY,SAAU,OAAQ,MAAO,UAAW,WAAY,WAAA,EAAgB,SAAAiB,CAAA,CAAU,CAAA,CAAA,CAC1G,CAAA,EACF,EAGDJ,GAAgBA,IAAiBH,GAAYG,IAAiBF,GAC7D9S,OAAC,MAAA,CAAI,MAAOgS,GACV,SAAA,CAAArY,EAAAA,IAAC,OAAA,CAAK,MAAOsY,GAAe,SAAAtY,EAAAA,IAACka,SAAM,KAAM,GAAI,MAAO3B,EAAA,CAAW,CAAA,CAAE,EACjElS,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,KAAM,GACnC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAOoY,GAAY,SAAA,WAAQ,EACjCpY,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,GAAGwY,GAAY,SAAU,OAAQ,MAAO,WAAc,SAAAa,CAAA,CAAa,CAAA,CAAA,CACpF,CAAA,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EACF,EAGArZ,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,gDACT,WAAY,uCACZ,WAAY,MACZ,MAAO,OACP,UAAW,MAAA,EAEb,wBAAyB,CAAE,OAAQwZ,CAAA,CAAS,CAAA,CAC9C,CAAA,CAAA,CACF,CAAA,CAGN,+GCrYA,GAAI,OAAO,SAAa,KAAe,CAAC,SAAS,eAAe,iBAAiB,EAAG,CAClF,MAAMiB,EAAU,SAAS,cAAc,OAAO,EAC9CA,EAAQ,GAAK,kBACbA,EAAQ,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQtB,SAAS,KAAK,YAAYA,CAAO,CACnC,CA+CA,MAAMC,GAAW,IAEJ/V,GAAegW,EAAAA,WAC1B,CAAC,CAAE,IAAApY,EAAK,gBAAAqY,EAAiB,kBAAAC,CAAA,EAAqBC,IAAQ,CACpD,MAAMpgB,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACVgY,EAAYvX,EAAAA,OAAuB,IAAI,EACvCwX,EAAUxX,EAAAA,OAAwB,IAAI,EACtCyX,EAAezX,EAAAA,OAA6B,IAAI,EAChD0X,EAAqB1X,EAAAA,OAAOoX,CAAe,EAC3CO,EAAuB3X,EAAAA,OAAOqX,CAAiB,EACrDK,EAAmB,QAAUN,EAC7BO,EAAqB,QAAUN,EAE/B,MAAMO,EAAoB5X,EAAAA,OAAO,CAAC,EAC5B6X,EAAa7X,EAAAA,OAAsB,IAAI,EACvC8X,EAAiB9X,EAAAA,OAAO,EAAK,EAE7B,CAACyQ,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAACiY,EAAaC,CAAc,EAAIlY,EAAAA,SAAS,EAAK,EAC9C,CAACmY,EAAKC,CAAM,EAAIpY,EAAAA,SAAoB,CAAA,CAAE,EACtC,CAACqY,EAASC,CAAU,EAAItY,EAAAA,SAAS,EAAK,EACtC,CAACuY,EAAeC,CAAgB,EAAIxY,EAAAA,SAAiB,EAAE,EACvDyY,EAASvY,EAAAA,OAAkB,EAAE,EACnCuY,EAAO,QAAUN,EAEjBH,EAAe,QAAUC,EAEzB,MAAMS,EAAavR,EAAAA,YAAY,IAAM,QACnClJ,EAAA0Z,EAAa,UAAb,MAAA1Z,EAAsB,MACxB,EAAG,CAAA,CAAE,EAEC0a,EAAaxR,EAAAA,YAAY,IAAM,QACnClJ,EAAA0Z,EAAa,UAAb,MAAA1Z,EAAsB,MACxB,EAAG,CAAA,CAAE,EAGC2a,EAAqB1Y,EAAAA,OAAuB,IAAI,EAChD2Y,EAAe3Y,EAAAA,OAAO,CAAC,EAEvB4Y,EAAc5Y,SAAQ6Y,GAAe,UACzC,MAAMrL,EAAYkL,EAAmB,QACrC,GAAI,CAAClL,EAAW,OAChB,MAAMpF,EAAKoF,EAEX,GADmBpF,EAAG,UAAYA,EAAG,cAAgBA,EAAG,aAAe,IAErE,GAAI,CACF,MAAM0Q,GAAO/a,EAAA0Z,EAAa,UAAb,YAAA1Z,EAA4G,SACzHyL,GAAAsP,GAAA,YAAAA,EAAK,QAAL,MAAAtP,GAAA,KAAAsP,EAAa,IAAK,IACpB,MAAQ,CAAe,CAE3B,CAAC,EAEKC,EAAyB9R,EAAAA,YAAY,IAAM,CAE3CyR,EAAmB,UACrBA,EAAmB,QAAQ,oBAAoB,SAAUE,EAAY,OAAO,EAC5EF,EAAmB,QAAU,MAE/B,qBAAqBC,EAAa,OAAO,EAEzC,MAAMK,EAAY,IAAM,OACtB,MAAMxL,IAAYzP,EAAAwZ,EAAU,UAAV,YAAAxZ,EAAmB,cAAc,qBAAsB,KACzE,GAAI,CAACyP,EAAW,CACdmL,EAAa,QAAU,sBAAsBK,CAAS,EACtD,MACF,CACAN,EAAmB,QAAUlL,EAC7BA,EAAU,iBAAiB,SAAUoL,EAAY,QAAS,CAAE,QAAS,GAAM,CAC7E,EACAD,EAAa,QAAU,sBAAsBK,CAAS,CACxD,EAAG,CAAA,CAAE,EAECC,EAAkBhS,EAAAA,YAAY,IAAM,OACxC,MAAMiS,EAAS,CAACpB,EAAe,QAC/BE,EAAekB,CAAM,GACrBnb,EAAA4Z,EAAqB,UAArB,MAAA5Z,EAAA,KAAA4Z,EAA+BuB,GAE/B,WAAW,IAAM,CACf,MAAMC,EAAS5B,EAAU,QACnB6B,EAAY3B,EAAa,QAC3B,CAAC0B,GAAU,CAACC,IAChBA,EAAU,OAAOD,EAAO,YAAaA,EAAO,YAAY,EAEpDtB,EAAW,SACbuB,EAAU,QAAQvB,EAAW,OAAO,EAGtCkB,EAAA,EACF,EAAG,GAAG,CACR,EAAG,CAACA,CAAsB,CAAC,EAErBM,EAAYpS,EAAAA,YAAY,IAAM,CAClCmR,EAAW9P,GAAQ,CAACA,CAAI,CAC1B,EAAG,CAAA,CAAE,EAECgR,EAAiBrS,cAAasS,GAAiB,OACnDjB,EAAiBiB,CAAI,GACrBxb,EAAA0Z,EAAa,UAAb,MAAA1Z,EAAsB,QAAQwb,GAC9BnB,EAAW,EAAK,CAClB,EAAG,CAAA,CAAE,EAELoB,EAAAA,oBAAoBlC,EAAK,KAAO,CAC9B,SAAUkB,EACV,SAAUC,EACV,gBAAAQ,EACA,UAAAI,CAAA,GACE,CAACb,EAAYC,EAAYQ,EAAiBI,CAAS,CAAC,EAExDpZ,EAAAA,UAAU,IAAM,CACd,MAAMkZ,EAAS5B,EAAU,QACzB,GAAI,CAAC4B,EAAQ,OAEbzI,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb4L,EAAO,CAAA,CAAE,EACTE,EAAW,EAAK,EAChBe,EAAO,UAAY,GACnBtB,EAAW,QAAU,KACrBD,EAAkB,QAAU,EAE5B,IAAI1X,EAAY,GAGhB,MAAMuZ,EAAY,OAAO,WAAW,IAAM,CACpCvZ,GACJwZ,EAAA,CACF,EAAG,CAAC,EAEEA,EAAO,SAAY,OACvB,GAAI,CACF,IAAIC,GAAkC5a,EAClCA,EAAI,WAAW,OAAO,IAExB4a,GAAY,MADC,MAAMja,EAAQX,CAAG,GACP,YAAA,GAGzB,MAAM6a,EAAOC,GAAKF,EAAS,EAC3BnC,EAAQ,QAAUoC,EAElB,MAAMR,GAAYQ,EAAK,SAAST,EAAQ,CACtC,QAAS,aACT,KAAM,WACN,MAAO,OACP,OAAQ,MAAA,CACT,EACD1B,EAAa,QAAU2B,GAEvBA,GAAU,OAAO,SAAS,UAAW,CACnC,KAAM,CACJ,WAAY,qBACZ,MAAO,qBACP,cAAe,uFACf,YAAa,kBACb,cAAe,eACf,QAAS,uBACT,YAAa,kBACb,aAAc,wBACd,aAAc,wBACd,gBAAiB,uBAAA,EAEnB,EAAG,CAAE,cAAe,iBAAkB,OAAQ,oBAAA,EAC9C,GAAI,CAAE,aAAc,oBAAqB,OAAQ,wBAAA,EACjD,GAAI,CAAE,OAAQ,0BAAA,EACd,GAAI,CAAE,OAAQ,wBAAA,EACd,IAAK,CAAE,YAAa,kBAAmB,OAAQ,iBAAA,EAC/C,EAAG,CAAE,MAAO,qBAAsB,kBAAmB,iBAAA,CAAkB,CACxE,EACDA,GAAU,OAAO,OAAO,SAAS,EAEjC,MAAMQ,EAAK,MAGXA,EAAK,UAAU,SAAS,IAAI,EAAE,KAAK,IAAM,cACvC,GAAI1Z,EAAW,OACf0X,EAAkB,QAAUgC,EAAK,UAAU,OAAA,EAE3C,MAAME,IAAM/b,GAAA0Z,EAAa,UAAb,YAAA1Z,GAAsB,kBAC5Bgc,IAAMvQ,GAAAsQ,IAAA,YAAAA,GAAK,QAAL,YAAAtQ,GAAY,WAAY,GACpCwQ,GAAAtC,EAAmB,UAAnB,MAAAsC,GAAA,KAAAtC,EAA6BqC,EAAM,EAAGnC,EAAkB,QAC1D,CAAC,EAAE,MAAM,IAAM,CAAe,CAAC,EAG/B,MAAMqC,EAAM,MAAML,EAAK,OAAO,WAO9B,GANI,CAAC1Z,GAAa,MAAM,QAAQ+Z,GAAA,YAAAA,EAAK,GAAG,GACtC/B,EAAO+B,EAAI,GAAG,EAGhB,MAAMb,GAAU,QAAA,EAEZlZ,EAAW,OAEfwQ,EAAW,EAAK,GAChB3S,EAAA2Z,EAAmB,UAAnB,MAAA3Z,EAAA,KAAA2Z,EAA6B,EAAGE,EAAkB,SAAW,GAE7DwB,GAAU,GAAG,YAAcc,IAAsB,iBAC/C,MAAMJ,EAAMI,GAIZ,IAHInc,GAAA+b,GAAA,YAAAA,EAAK,QAAL,MAAA/b,GAAY,MACd8Z,EAAW,QAAUiC,EAAI,MAAM,MAE7BtQ,GAAAsQ,GAAA,YAAAA,EAAK,QAAL,MAAAtQ,GAAY,KAAM,CAEpB,MAAM2Q,GAAYL,EAAI,MAAM,KACtBM,GAAoB,CAAA,EACpBC,GAAWC,IAAqB,CACpC,UAAWtQ,MAAQsQ,GAAO,CACxB,MAAMC,GAAOvQ,GAAK,KAAK,MAAM,GAAG,EAAE,CAAC,EAC/BuQ,KAASJ,KAAcI,IAAQJ,GAAU,SAAS,IAAMI,EAAI,GAAKJ,GAAU,SAASI,EAAI,IAC1FH,GAAQ,KAAKpQ,GAAK,IAAI,EAEpBA,GAAK,UAAUqQ,GAAQrQ,GAAK,QAAQ,CAC1C,CACF,EACAqQ,GAAQ9B,EAAO,OAAO,EAClB6B,GAAQ,SAAW,GAErB9B,EAAiB8B,GAAQ,CAAC,CAAC,CAG/B,CACA,MAAML,IAAMC,GAAAF,GAAA,YAAAA,EAAK,QAAL,YAAAE,GAAY,SAClB9Q,GAAQ0O,EAAkB,QAC5B,OAAOmC,IAAQ,UAAY7Q,GAAQ,KACrCsR,GAAA9C,EAAmB,UAAnB,MAAA8C,GAAA,KAAA9C,EAA6BqC,GAAM,EAAG7Q,IAE1C,CAAC,CAEH,OAAS7I,GAAK,CACZ,QAAQ,MAAM,aAAcA,EAAG,EAC1BH,IACHoM,EAASpV,EAAE,kBAAkB,CAAC,EAC9BwZ,EAAW,EAAK,EAEpB,CACF,EAEA,MAAO,IAAM,YACXxQ,EAAY,GACZ,OAAO,aAAauZ,CAAS,EAC7B,GAAI,EAAEjQ,IAAAzL,EAAA0Z,EAAa,UAAb,YAAA1Z,EAAsB,UAAtB,MAAAyL,GAAA,KAAAzL,EAAmC,MAAQ,CAAe,CAChE,GAAI,EAAEic,EAAAxC,EAAQ,UAAR,MAAAwC,EAAiB,SAAW,MAAQ,CAAe,CACzDvC,EAAa,QAAU,KACvBD,EAAQ,QAAU,IACpB,CACF,EAAG,CAACzY,CAAG,CAAC,EAERkB,EAAAA,UAAU,IAAM,CACd,MAAMwa,EAAW,IAAM,CACrB,MAAMtB,EAAS5B,EAAU,QACrB,CAAC4B,GAAU,CAAC1B,EAAa,SAC7BA,EAAa,QAAQ,OAAO0B,EAAO,YAAaA,EAAO,YAAY,CACrE,EACA,cAAO,iBAAiB,SAAUsB,CAAQ,EACnC,IAAM,OAAO,oBAAoB,SAAUA,CAAQ,CAC5D,EAAG,CAAA,CAAE,EAELxa,EAAAA,UAAU,KACR8Y,EAAA,EACO,IAAM,OACX,qBAAqBJ,EAAa,OAAO,GACzC5a,EAAA2a,EAAmB,UAAnB,MAAA3a,EAA4B,oBAAoB,SAAU6a,EAAY,QACxE,GACC,CAAC7Z,EAAKga,CAAsB,CAAC,EAEhC,MAAM2B,EAAWzT,cAAasS,GACrBA,IAASlB,EACf,CAACA,CAAa,CAAC,EAEZsC,EAAiB,CAACL,EAAkBM,EAAQ,IAChDpe,MAAC,MAAG,MAAO,CAAE,WAAYoe,EAAQ,EAAI,GAAK,GACvC,WAAM,IAAI,CAAC5Q,EAAMnS,IAAM,CACtB,MAAMgjB,EAASH,EAAS1Q,EAAK,IAAI,EACjC,cACG,KAAA,CACC,SAAA,CAAAxN,EAAAA,IAAC,SAAA,CACC,QAAS,IAAM8c,EAAetP,EAAK,IAAI,EACvC,UAAW,sGAAsG6Q,EAC3G,uDACA,wEACJ,GACF,MAAO7Q,EAAK,MAEX,SAAAA,EAAK,MAAM,KAAA,CAAK,CAAA,EAElBA,EAAK,UAAYA,EAAK,SAAS,OAAS,GAAK2Q,EAAe3Q,EAAK,SAAU4Q,EAAQ,CAAC,CAAA,CAAA,EAX9E,GAAG5Q,EAAK,IAAI,IAAInS,CAAC,EAY1B,CAEJ,CAAC,CAAA,CACH,EAGF,OACEgL,EAAAA,KAAC,MAAA,CAAI,UAAU,sGACZ,SAAA,CAAAwJ,GACC7P,EAAAA,IAAC,OAAI,UAAU,8GACb,eAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,CAAA,CACpC,EAGDoE,GAAW,CAACpE,GACX7P,EAAAA,IAAC,MAAA,CAAI,UAAU,iFACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,mHAAA,CAAoH,CAAA,CACrI,EAIDyb,EAAI,OAAS,GACZpV,EAAAA,KAAC,MAAA,CACC,UAAU,qFACV,MAAO,CACL,QAASsV,EAAU,EAAI,EACvB,cAAeA,EAAU,OAAS,MAAA,EAGpC,SAAA,CAAAtV,EAAAA,KAAC,MAAA,CACC,UAAU,mMACV,MAAO,CAAE,UAAWsV,EAAU,gBAAkB,mBAAA,EAEhD,SAAA,CAAAtV,EAAAA,KAAC,MAAA,CAAI,UAAU,sHACb,SAAA,CAAArG,MAAC,OAAA,CAAK,UAAU,kDAAmD,SAAAtF,EAAE,aAAa,EAAE,EACpFsF,EAAAA,IAAC,SAAA,CACC,QAAS,IAAM4b,EAAW,EAAK,EAC/B,UAAU,uEAEV,SAAA5b,EAAAA,IAAC5B,EAAAA,EAAA,CAAE,UAAU,iBAAA,CAAkB,CAAA,CAAA,CACjC,EACF,QACC,MAAA,CAAI,UAAU,mDACZ,SAAA+f,EAAe1C,CAAG,CAAA,CACrB,CAAA,CAAA,CAAA,EAEFzb,EAAAA,IAAC,MAAA,CACC,UAAU,qDACV,MAAO,CAAE,WAAY2b,EAAU,kBAAoB,aAAA,EACnD,QAAS,IAAMC,EAAW,EAAK,CAAA,CAAA,CACjC,CAAA,CAAA,EAIH,CAAC/L,GACA7P,EAAAA,IAAC,MAAA,CACC,IAAK+a,EACL,UAAU,kDACV,MAAO,CACL,MAAOQ,EAAc,OAAS,GAAGb,EAAQ,KACzC,SAAU,OACV,WAAY,kBACZ,SAAU,QAAA,CACZ,CAAA,CACF,EAEJ,CAEJ,CACF,gHCvZM4D,GAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBb5D,GAAW,IAeJ7V,GAAe8V,EAAAA,WAC1B,CAAC,CAAE,IAAApY,EAAK,gBAAAqY,EAAiB,kBAAAC,CAAA,EAAqBC,IAAQ,CACpD,MAAMpgB,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACVwb,EAAU/a,EAAAA,OAAuB,IAAI,EACrCgb,EAAUhb,EAAAA,OAA2B,IAAI,EACzC0X,EAAqB1X,EAAAA,OAAOoX,CAAe,EAC3CO,EAAuB3X,EAAAA,OAAOqX,CAAiB,EACrDK,EAAmB,QAAUN,EAC7BO,EAAqB,QAAUN,EAG/B,MAAMO,EAAoB5X,EAAAA,OAAO,CAAC,EAE5B,CAACyQ,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAACmY,EAAKC,CAAM,EAAIpY,EAAAA,SAAoB,CAAA,CAAE,EACtC,CAACqY,EAASC,CAAU,EAAItY,EAAAA,SAAS,EAAK,EACtC,CAACuY,EAAeC,CAAgB,EAAIxY,EAAAA,SAAiB,EAAE,EACvD,CAACiY,EAAaC,CAAc,EAAIlY,EAAAA,SAAS,EAAK,EAC9CgY,EAAiB9X,EAAAA,OAAO,EAAK,EACnC8X,EAAe,QAAUC,EAEzB,MAAMkD,EAAiBhU,EAAAA,YAAY,CAACgC,EAAiBC,IAAkB,OACjEA,EAAQ,IAAG0O,EAAkB,QAAU1O,IAC3CnL,EAAA2Z,EAAmB,UAAnB,MAAA3Z,EAAA,KAAA2Z,EAA6B,KAAK,IAAI,EAAGzO,EAAU,CAAC,EAAG2O,EAAkB,QAC3E,EAAG,CAAA,CAAE,EAECY,EAAavR,EAAAA,YAAY,IAAM,CACnC,MAAMiU,EAAOF,EAAQ,QAChBE,GACLA,EAAK,OAAO,MAAM,IAAM,CAAC,CAAC,CAC5B,EAAG,CAAA,CAAE,EAECzC,EAAaxR,EAAAA,YAAY,IAAM,CACnC,MAAMiU,EAAOF,EAAQ,QAChBE,GACLA,EAAK,OAAO,MAAM,IAAM,CAAC,CAAC,CAC5B,EAAG,CAAA,CAAE,EAEC7B,EAAYpS,EAAAA,YAAY,IAAMmR,EAAY9P,GAAS,CAACA,CAAI,EAAG,EAAE,EAE7D2Q,EAAkBhS,EAAAA,YAAY,IAAM,OACxC,MAAMiS,EAAS,CAACpB,EAAe,QAC/BE,EAAekB,CAAM,GACrBnb,EAAA4Z,EAAqB,UAArB,MAAA5Z,EAAA,KAAA4Z,EAA+BuB,GAE/B,MAAMgC,EAAOF,EAAQ,QACrB,GAAI,CAACE,EAAM,OACX,MAAM1T,EAAY0T,EAA+C,SAC7D1T,GACFA,EAAS,aAAa,kBAAmB0R,EAAS,OAAS,KAAK,CAEpE,EAAG,CAAA,CAAE,EAECI,EAAiBrS,cAAasS,GAAiB,OACnDjB,EAAiBiB,CAAI,EACrBnB,EAAW,EAAK,GAChBra,EAAAid,EAAQ,UAAR,MAAAjd,EAAiB,KAAKwb,GAAM,MAAM,IAAM,CAAC,EAC3C,EAAG,CAAA,CAAE,EAELC,EAAAA,oBAAoBlC,EAAK,KAAO,CAC9B,SAAUkB,EACV,SAAUC,EACV,gBAAAQ,EACA,UAAAI,CAAA,GACE,CAACb,EAAYC,EAAYQ,EAAiBI,CAAS,CAAC,EAExDpZ,EAAAA,UAAU,IAAM,CACd,MAAMkb,EAAOJ,EAAQ,QACrB,GAAI,CAACI,EAAM,OAEXzK,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb4L,EAAO,CAAA,CAAE,EACTE,EAAW,EAAK,EAChBE,EAAiB,EAAE,EACnB6C,EAAK,gBAAA,EAEL,IAAIjb,EAAY,GACZgb,EAA2B,KA4E/B,OA1Ea,SAAY,iBACvB,GAAI,CACF,GAAIhb,EAAW,OAEfgb,EAAO,SAAS,cAAc,cAAc,EAC5CC,EAAK,YAAYD,CAAI,EACrBF,EAAQ,QAAUE,EAGlBA,EAAK,iBAAiB,WAAankB,IAAa,WAC9C,MAAMqkB,EAAUrkB,GAAkB,OAClC,GAAI,CAACqkB,EAAQ,OAEb,MAAMtB,GAAMsB,EAAO,SACnB,GAAItB,IAAO,OAAOA,GAAI,SAAY,UAAY,OAAOA,GAAI,OAAU,SACjEmB,EAAenB,GAAI,QAASA,GAAI,KAAK,MAChC,CAEL,MAAMuB,KAAW7R,IAAAzL,GAAAid,EAAQ,UAAR,YAAAjd,GAAiB,OAAjB,YAAAyL,GAAuB,WAAY,CAAA,EAC9C8R,GAAMF,EAAO,OAAS,EACtBG,GAAOH,EAAO,UAAY,EAC1BlS,GAAQ,KAAK,IAAImS,GAAS,OAAQ,CAAC,EACnCpS,GAAU,KAAK,OAAOqS,GAAMC,IAAQrS,GAAQA,EAAK,EACvD+R,EAAehS,GAASC,EAAK,CAC/B,CACA,MAAMsS,GAAUJ,EAAO,QACnBI,IAAA,MAAAA,GAAS,MACXlD,EAAiBkD,GAAQ,IAAI,CAEjC,CAAC,EAED,MAAMC,EAAM,MAAM/b,EAAQX,CAAG,EAC7B,GAAI,CAAC0c,EAAI,GAAI,MAAM,IAAI,MAAM,SAASA,EAAI,MAAM,EAAE,EAClD,MAAMC,GAAO,MAAMD,EAAI,KAAA,EACvB,IAAI9T,EAAO,YACX,GAAI,CAEF,MAAM4S,EADI,IAAI,IAAIxb,EAAK,OAAO,SAAS,IAAI,EAC5B,SAAS,MAAM,GAAG,EAAE,IAAA,EAC/Bwb,IAAM5S,EAAO,mBAAmB4S,CAAI,EAC1C,MAAQ,CAAkB,CAC1B,MAAM9a,GAAO,IAAI,KAAK,CAACic,EAAI,EAAG/T,CAAI,EAGlC,GADA,MAAMuT,EAAK,KAAKzb,EAAI,EAChBS,EAAW,EAAEsJ,GAAAzL,EAAAmd,EAAK,OAAL,YAAAnd,EAAW,UAAX,MAAAyL,EAAA,KAAAzL,GAAwB,MAAQ,CAGjD,MAAMyJ,EAAY0T,EAGb,SAED1T,IAEFA,EAAS,aAAa,WAAY,EAAE,EACpCA,EAAS,aAAa,kBAAmB,KAAK,EAC9CA,EAAS,aAAa,SAAU,IAAI,EACpCA,EAAS,aAAa,MAAO,IAAI,GACjCwS,EAAAxS,EAAS,YAAT,MAAAwS,EAAA,KAAAxS,EAAqBsT,IAErB,OAAMN,EAAAhT,EAAS,OAAT,YAAAgT,EAAA,KAAAhT,KAGR0Q,IAAOW,EAAAqC,EAAK,OAAL,YAAArC,EAAW,MAAO,CAAA,CAAE,EAC3BnI,EAAW,EAAK,EAChBuK,EAAe,IAAGU,EAAAT,EAAK,OAAL,YAAAS,EAAW,SAAS,SAAU,CAAC,CACnD,OAAStb,EAAK,CACZ,QAAQ,MAAM,kBAAmBA,CAAG,EAC/BH,IACHoM,EAASpV,EAAE,kBAAkB,CAAC,EAC9BwZ,EAAW,EAAK,EAEpB,CACF,GAEA,EAEO,IAAM,WACXxQ,EAAY,GACZ,GAAI,EAAE8Z,GAAAxQ,GAAAzL,EAAAid,EAAQ,UAAR,YAAAjd,EAAiB,OAAjB,YAAAyL,EAAuB,UAAvB,MAAAwQ,EAAA,KAAAxQ,EAAoC,MAAQ,CAAe,CACjEwR,EAAQ,QAAU,KAClBG,EAAK,gBAAA,CACP,CACF,EAAG,CAACpc,EAAKkc,CAAc,CAAC,EAExB,MAAMP,EAAWzT,EAAAA,YACdsS,GAA6B,CAAC,CAACA,GAAQA,IAASlB,EACjD,CAACA,CAAa,CAAA,EAGVsC,EAAiB,CAACL,EAAkBM,EAAQ,UAC/C,KAAA,CAAG,MAAO,CAAE,UAAW,OAAQ,QAAS,EAAG,OAAQA,EAAQ,EAAI,aAAe,CAAA,EAC5E,SAAAN,EAAM,IAAI,CAACtQ,EAAMnS,IAAA,SAChBgL,OAAAA,EAAAA,KAAC,KAAA,CACE,SAAA,CAAAmH,EAAK,KACJxN,EAAAA,IAAC,SAAA,CACC,QAAS,IAAM8c,EAAetP,EAAK,IAAK,EACxC,UAAW,sGACT0Q,EAAS1Q,EAAK,IAAI,EACd,uDACA,wEACN,GACA,MAAOA,EAAK,MAEX,UAAAjM,EAAAiM,EAAK,QAAL,YAAAjM,EAAY,MAAK,CAAA,QAGnB,MAAA,CAAI,UAAU,6EACZ,UAAAyL,EAAAQ,EAAK,QAAL,YAAAR,EAAY,OACf,EAEDQ,EAAK,UAAYA,EAAK,SAAS,OAAS,GAAK2Q,EAAe3Q,EAAK,SAAU4Q,EAAQ,CAAC,CAAA,CAAA,EAlB9E,GAAG5Q,EAAK,MAAQA,EAAK,KAAK,IAAInS,CAAC,EAmBxC,EACD,EACH,EAGF,OACEgL,EAAAA,KAAC,MAAA,CAAI,UAAU,sGACZ,SAAA,CAAAwJ,GACC7P,EAAAA,IAAC,OAAI,UAAU,sHACb,eAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,CAAA,CACpC,EAGDoE,GAAW,CAACpE,GACX7P,EAAAA,IAAC,MAAA,CAAI,UAAU,iFACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,mHAAA,CAAoH,CAAA,CACrI,EAIDyb,EAAI,OAAS,GACZpV,EAAAA,KAAC,MAAA,CACC,UAAU,qFACV,MAAO,CAAE,QAASsV,EAAU,EAAI,EAAG,cAAeA,EAAU,OAAS,MAAA,EAErE,SAAA,CAAAtV,EAAAA,KAAC,MAAA,CACC,UAAU,mMACV,MAAO,CAAE,UAAWsV,EAAU,gBAAkB,mBAAA,EAEhD,SAAA,CAAAtV,EAAAA,KAAC,MAAA,CAAI,UAAU,sHACb,SAAA,CAAArG,MAAC,OAAA,CAAK,UAAU,kDAAmD,SAAAtF,EAAE,aAAa,EAAE,EACpFsF,EAAAA,IAAC,SAAA,CACC,QAAS,IAAM4b,EAAW,EAAK,EAC/B,UAAU,uEAEV,SAAA5b,EAAAA,IAAC5B,EAAAA,EAAA,CAAE,UAAU,iBAAA,CAAkB,CAAA,CAAA,CACjC,EACF,QACC,MAAA,CAAI,UAAU,mDACZ,SAAA+f,EAAe1C,CAAG,CAAA,CACrB,CAAA,CAAA,CAAA,EAEFzb,EAAAA,IAAC,MAAA,CACC,UAAU,qDACV,MAAO,CAAE,WAAY2b,EAAU,kBAAoB,aAAA,EACnD,QAAS,IAAMC,EAAW,EAAK,CAAA,CAAA,CACjC,CAAA,CAAA,EAIH,CAAC/L,GACA7P,EAAAA,IAAC,MAAA,CACC,IAAKue,EACL,UAAU,kDACV,MAAO,CACL,MAAOhD,EAAc,OAAS,GAAGb,EAAQ,KACzC,SAAU,OACV,WAAY,iBAAA,CACd,CAAA,CACF,EAEJ,CAEJ,CACF,EAEA7V,GAAa,YAAc,mIC5SrBua,GAAgB7c,GAAwB,OAC5C,MAAMwK,IAAMxL,EAAAgB,EAAI,MAAM,GAAG,EAAE,IAAA,IAAf,YAAAhB,EAAsB,cAAc,MAAM,KAAK,KAAM,GAajE,MAZwC,CACtC,IAAK,YACL,KAAM,aACN,IAAK,YACL,IAAK,YACL,IAAK,kBACL,IAAK,kBACL,IAAK,mBACL,IAAK,YACL,MAAO,aACP,IAAK,aAAA,EAEQwL,CAAG,GAAK,WACzB,EAEahI,GAA8C,CAAC,CAAE,IAAAxC,KAAU,CACtE,MAAM,EAAIpC,EAAA,EACJ,CAAC0P,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAAC+b,EAAWC,CAAY,EAAIhc,EAAAA,SAAS,EAAI,EACzCic,EAAW/b,EAAAA,OAAuB,IAAI,EACtCgc,EAAYhc,EAAAA,OAA6B,IAAI,EAmFnD,OAjFAC,EAAAA,UAAU,IAAM,CAEd,GAAI,CAAC+b,EAAU,SAAWD,EAAS,QAAS,CAC1C,MAAME,EAAe,SAAS,cAAc,UAAU,EACtDA,EAAa,UAAU,IAAI,wBAAyB,iBAAiB,EACrEF,EAAS,QAAQ,YAAYE,CAAY,EAEzC,MAAMC,EAAYN,GAAa7c,CAAG,EAU5Bod,EAASC,GAAQH,EAAc,CACnC,SAAU,GACV,KAAM,GACN,QAAS,OACT,WAAY,CACV,SAAU,CACR,aACA,cACA,qBACA,cACA,kBACA,kBACA,uBACA,kBAAA,EAEF,YAAa,CACX,OAAQ,EAAA,CACV,EAEF,MAAO,CACL,IAAK,CACH,eAAgB,EAAA,EAElB,kBAAmB,GACnB,kBAAmB,GACnB,iBAAkB,EAAA,EAEpB,QAlCcC,IAAc,kBAC1B,CACA,CAAE,IAAKnd,EAAK,KAAM,iBAAA,EAClB,CAAE,IAAKA,EAAK,KAAM,WAAA,CAAY,EAE9B,CAAC,CAAE,IAAKA,EAAK,KAAMmd,EAAW,CA6BhC,CACD,EAGKG,EAAUF,EAAO,GAAA,EAAK,cAAc,OAAO,EAC7CE,IACDA,EAA6B,MAAM,UAAY,WAIlDF,EAAO,GAAG,aAAc,IAAM,CAC5BL,EAAa,EAAK,CACpB,CAAC,EAEDK,EAAO,GAAG,QAAS,IAAM,CACvB,MAAM9P,EAAQ8P,EAAO,MAAA,EACrB,QAAQ,MAAM,kBAAmB9P,CAAK,EACtCC,EAAS,EAAE,+BAAgC,CAAE,OAAOD,GAAAA,YAAAA,EAAO,UAAW,EAAE,sBAAsB,CAAA,CAAG,CAAC,EAClGyP,EAAa,EAAK,CACpB,CAAC,EAEDE,EAAU,QAAUG,CACtB,CACF,EAAG,CAACpd,CAAG,CAAC,EAGRkB,EAAAA,UAAU,IAAM,CACd,MAAMkc,EAASH,EAAU,QAEzB,MAAO,IAAM,CACPG,GAAU,CAACA,EAAO,eACpBA,EAAO,QAAA,EACPH,EAAU,QAAU,KAExB,CACF,EAAG,CAAA,CAAE,EAED3P,QAEC,MAAA,CAAI,UAAU,qEACb,SAAAxJ,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,yHACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,mCAAmC,KAAK,OAAO,QAAQ,YAAY,OAAO,eACvF,SAAAA,EAAAA,IAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,sIAAA,CAAuI,CAAA,CAC9M,CAAA,CACF,QACC,IAAA,CAAE,UAAU,2DAA4D,SAAA,EAAE,mBAAmB,EAAE,EAChGA,EAAAA,IAAC,IAAA,CAAE,UAAU,mCAAoC,SAAA6P,CAAA,CAAM,CAAA,CAAA,CACzD,CAAA,CACF,QAKD,MAAA,CAAI,UAAU,qEACb,SAAAxJ,EAAAA,KAAC,MAAA,CAAI,UAAU,qCAEZ,SAAA,CAAAgZ,SACE,MAAA,CAAI,UAAU,uHACb,SAAAhZ,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,wIAAA,CAAyI,QACvJ,IAAA,CAAE,UAAU,oDAAqD,SAAA,EAAE,eAAe,CAAA,CAAE,CAAA,CAAA,CACvF,CAAA,CACF,EAIFA,EAAAA,IAAC,MAAA,CACC,IAAKuf,EACL,UAAU,yEACV,MAAO,CACL,UAAW,qEAAA,CACb,CAAA,CACF,CAAA,CACF,CAAA,CACF,CAEJ,iHCnIO,SAASO,GAAe,CAC7B,IAAAvd,CACF,EAAgD,CAC9C,MAAMwd,EAAWvc,EAAAA,OAAyB,IAAI,EACxC,CAACwc,EAAWC,CAAY,EAAI3c,EAAAA,SAAS,EAAK,EAC1C,CAAC+b,EAAWC,CAAY,EAAIhc,EAAAA,SAAS,EAAI,EACzC,CAAC4c,EAAaC,CAAc,EAAI7c,EAAAA,SAAS,CAAC,EAC1C,CAAC8c,EAAUC,CAAW,EAAI/c,EAAAA,SAAS,CAAC,EACpC,CAACgd,EAAQC,CAAc,EAAIjd,EAAAA,SAAS,CAAC,EACrC,CAACkd,EAASC,CAAU,EAAInd,EAAAA,SAAS,EAAK,EACtC,CAACod,EAAQC,CAAS,EAAIrd,EAAAA,SAAS,EAAK,EACpC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAEtDG,EAAAA,UAAU,IAAM,CACd,MAAMmd,EAAQb,EAAS,QACvB,GAAI,CAACa,EAAO,OAGZtB,EAAa,EAAI,EACjBxP,EAAS,IAAI,EAEb,MAAM+Q,EAAe,IAAM,CACpB,MAAMD,EAAM,WAAW,GAC1BT,EAAeS,EAAM,WAAW,CAEpC,EAEME,EAAmB,IAAM,CACzB,CAAC,MAAMF,EAAM,QAAQ,GAAK,SAASA,EAAM,QAAQ,GACnDP,EAAYO,EAAM,QAAQ,CAE9B,EAEMG,EAAY,IAAM,CACtBzB,EAAa,EAAK,EAClBwB,EAAA,CACF,EAEME,EAAY,IAAM1B,EAAa,EAAI,EACnC2B,EAAY,IAAM,CACtB3B,EAAa,EAAK,EAClBW,EAAa,EAAI,CACnB,EAGMiB,EAAS,IAAMjB,EAAa,EAAI,EAChCkB,EAAU,IAAMlB,EAAa,EAAK,EAClCmB,EAAU,IAAMnB,EAAa,EAAK,EAElCoB,EAAU,IAAM,CACpBvR,EAAS,QAAQ,EACjBwP,EAAa,EAAK,CACpB,EAEA,OAAAsB,EAAM,iBAAiB,aAAcC,CAAY,EACjDD,EAAM,iBAAiB,iBAAkBE,CAAgB,EACzDF,EAAM,iBAAiB,iBAAkBE,CAAgB,EACzDF,EAAM,iBAAiB,UAAWG,CAAS,EAC3CH,EAAM,iBAAiB,UAAWI,CAAS,EAC3CJ,EAAM,iBAAiB,UAAWK,CAAS,EAC3CL,EAAM,iBAAiB,OAAQM,CAAM,EACrCN,EAAM,iBAAiB,QAASO,CAAO,EACvCP,EAAM,iBAAiB,QAASQ,CAAO,EACvCR,EAAM,iBAAiB,QAASS,CAAO,EAGnCT,EAAM,YAAc,GACtBtB,EAAa,EAAK,EAClBwB,EAAA,GACSF,EAAM,YAAc,GAC7BE,EAAA,EAGK,IAAM,CACXF,EAAM,oBAAoB,aAAcC,CAAY,EACpDD,EAAM,oBAAoB,iBAAkBE,CAAgB,EAC5DF,EAAM,oBAAoB,iBAAkBE,CAAgB,EAC5DF,EAAM,oBAAoB,UAAWG,CAAS,EAC9CH,EAAM,oBAAoB,UAAWI,CAAS,EAC9CJ,EAAM,oBAAoB,UAAWK,CAAS,EAC9CL,EAAM,oBAAoB,OAAQM,CAAM,EACxCN,EAAM,oBAAoB,QAASO,CAAO,EAC1CP,EAAM,oBAAoB,QAASQ,CAAO,EAC1CR,EAAM,oBAAoB,QAASS,CAAO,CAC5C,CACF,EAAG,CAAC9e,CAAG,CAAC,EAER,MAAM+e,EAAa7W,EAAAA,YAAY,IAAM,CACnC,MAAMmW,EAAQb,EAAS,QAClBa,IAEDA,EAAM,OACRA,EAAM,OAAO,MAAM,IAAM,CAEzB,CAAC,EAEDA,EAAM,MAAA,EAEV,EAAG,CAAA,CAAE,EAECW,EAAO9W,cAAa+W,GAAiB,CACzC,MAAMZ,EAAQb,EAAS,QAClBa,IACLA,EAAM,YAAcY,EACpBrB,EAAeqB,CAAI,EACrB,EAAG,CAAA,CAAE,EAECC,EAAOhX,EAAAA,YACViX,GAAoB,CACnB,MAAMd,EAAQb,EAAS,QAClBa,IACLA,EAAM,YAAc,KAAK,IACvB,EACA,KAAK,IAAIA,EAAM,YAAcc,EAASd,EAAM,UAAY,GAAQ,CAAA,EAEpE,EACA,CAAA,CAAC,EAGGe,EAAYlX,cAAamX,GAAgB,CAC7C,MAAMhB,EAAQb,EAAS,QACvB,GAAI,CAACa,EAAO,OACZ,MAAMiB,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGD,CAAG,CAAC,EAC5ChB,EAAM,OAASiB,EACftB,EAAesB,CAAO,EAClBA,EAAU,IACZjB,EAAM,MAAQ,GACdH,EAAW,EAAK,EAEpB,EAAG,CAAA,CAAE,EAECqB,EAAarX,EAAAA,YAAY,IAAM,CACnC,MAAMmW,EAAQb,EAAS,QAClBa,IACLA,EAAM,MAAQ,CAACA,EAAM,MACrBH,EAAWG,EAAM,KAAK,EACxB,EAAG,CAAA,CAAE,EAECmB,EAAatX,EAAAA,YAAY,IAAM,CACnC,MAAMmW,EAAQb,EAAS,QACvB,GAAI,CAACa,EAAO,OACZ,MAAMoB,EAAO,CAACpB,EAAM,KACpBA,EAAM,KAAOoB,EACbrB,EAAUqB,CAAI,CAChB,EAAG,CAAA,CAAE,EAECC,EAAaxX,cAAa+W,GAAiB,CAC/C,GAAI,CAAC,SAASA,CAAI,GAAK,MAAMA,CAAI,GAAKA,EAAO,EAAG,MAAO,OACvD,MAAMU,EAAU,KAAK,MAAMV,EAAO,EAAE,EAC9BE,EAAU,KAAK,MAAMF,EAAO,EAAE,EACpC,MAAO,GAAGU,CAAO,IAAIR,EAAQ,WAAW,SAAS,EAAG,GAAG,CAAC,EAC1D,EAAG,CAAA,CAAE,EAEL,MAAO,CACL,SAAA3B,EACA,UAAAC,EACA,UAAAX,EACA,OAAAqB,EACA,YAAAR,EACA,SAAAE,EACA,OAAAE,EACA,QAAAE,EACA,MAAA3Q,EACA,WAAAyR,EACA,KAAAC,EACA,KAAAE,EACA,UAAAE,EACA,WAAAG,EACA,WAAAC,EACA,WAAAE,CAAA,CAEJ,CC9LA,MAAME,GAID,CAAC,CAAE,KAAAC,EAAM,UAAAxhB,EAAY,GAAI,MAAAiO,KAAY,CACxC,MAAM6B,EAAelN,EAAAA,OAAuB,IAAI,EAC1C6e,EAAW7e,EAAAA,OAAuB,IAAI,EACtC,CAAC8e,EAAUC,CAAW,EAAIjf,EAAAA,SAAS,EAAK,EACxC,CAACkf,EAAYC,CAAa,EAAInf,EAAAA,SAAS,CAAC,EAE9CG,EAAAA,UAAU,IAAM,CACd,MAAMif,EAAQ,IAAM,CAClB,MAAM1R,EAAYN,EAAa,QACzBiS,EAAQN,EAAS,QACvB,GAAI,CAACrR,GAAa,CAAC2R,EAAO,OAC1B,MAAMC,EAAK5R,EAAU,YACf6R,EAAKF,EAAM,YACjBJ,EAAYM,EAAKD,CAAE,EACnBH,EAAcI,CAAE,CAClB,EACAH,EAAA,EACA,MAAMI,EAAW,IAAI,eAAeJ,CAAK,EACzC,OAAIhS,EAAa,SAASoS,EAAS,QAAQpS,EAAa,OAAO,EACxD,IAAMoS,EAAS,WAAA,CACxB,EAAG,CAACV,CAAI,CAAC,EAET,MAAMW,EAAM,GACNC,EAAcR,EAAaO,EAC3BE,EAAMD,EAAc,GAE1B,OACE3c,EAAAA,KAAC,MAAA,CACC,IAAKqK,EACL,UAAW,6CAA6C9P,CAAS,GACjE,MAAAiO,EAEC,SAAA,CAAAyT,EACCjc,EAAAA,KAACsH,GAAAA,OAAO,IAAP,CACC,UAAU,wCACV,QAAS,CAAE,EAAG,CAAC,EAAG,CAACqV,CAAW,CAAA,EAC9B,WAAY,CAAE,SAAUC,EAAK,OAAQ,IAAU,KAAM,SAAU,YAAa,GAAA,EAE5E,SAAA,CAAAjjB,EAAAA,IAAC,QAAM,SAAAoiB,CAAA,CAAK,EACZpiB,MAAC,QAAK,MAAO,CAAE,MAAO+iB,CAAA,EAAO,UAAU,mBAAmB,EAC1D/iB,EAAAA,IAAC,QAAM,SAAAoiB,CAAA,CAAK,CAAA,CAAA,CAAA,EAEZ,KAEJpiB,EAAAA,IAAC,MAAA,CACC,IAAKqiB,EACL,UAAU,wBACV,MAAOC,EAAW,CAAE,SAAU,WAAY,WAAY,SAAU,cAAe,MAAA,EAAW,OAEzF,SAAAF,CAAA,CAAA,CACH,CAAA,CAAA,CAGN,EAGMc,GAA4C,CAAC,CAAE,UAAAlD,CAAA,IACnDhgB,EAAAA,IAAC2N,GAAAA,OAAO,IAAP,CACC,UAAU,eACV,MAAO,CACL,IAAK,OACL,MAAO,MACP,MAAO,QACP,OAAQ,QACR,gBAAiB,YACjB,OAAQ,CAAA,EAEV,QAAS,CAAE,OAAQqS,EAAY,GAAK,CAAA,EACpC,WAAY,CAAE,SAAU,GAAK,KAAM,CAAC,GAAK,EAAG,GAAK,CAAC,CAAA,EAElD,SAAA3Z,EAAAA,KAAC,MAAA,CACC,MAAM,MACN,OAAO,MACP,QAAQ,cACR,KAAK,OACL,MAAM,6BAGN,SAAA,CAAArG,EAAAA,IAAC,SAAA,CAAO,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,KAAK,iBAAA,CAAkB,EAEtDA,EAAAA,IAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,KAAK,gBAAA,CAAiB,EAErDA,EAAAA,IAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,KAAK,qBAAA,CAAsB,EAEzDA,EAAAA,IAAC,SAAA,CAAO,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,KAAK,OAAO,OAAO,OAAO,YAAY,MAAM,EAG5EA,EAAAA,IAAC,OAAA,CACC,EAAE,gBACF,OAAO,gBACP,YAAY,MACZ,cAAc,OAAA,CAAA,EAGhBA,EAAAA,IAAC,OAAA,CACC,EAAE,oBACF,OAAO,yBACP,YAAY,IACZ,cAAc,OAAA,CAAA,EAIhBA,EAAAA,IAAC,OAAA,CAAK,EAAE,KAAK,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,MAAM,KAAK,iBAAiB,EAEzEA,EAAAA,IAAC,OAAA,CAAK,EAAE,OAAO,EAAE,KAAK,MAAM,IAAI,OAAO,IAAI,GAAG,IAAI,KAAK,sBAAsB,EAE7EA,EAAAA,IAAC,OAAA,CAAK,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,OAAO,OAAO,YAAY,MAAM,cAAc,QAAQ,EAC9FA,EAAAA,IAAC,UAAO,GAAG,KAAK,GAAG,QAAQ,EAAE,MAAM,KAAK,MAAA,CAAO,SAG9C,OAAA,CACC,SAAA,CAAAqG,OAAC,kBAAe,GAAG,WAAW,GAAG,MAAM,GAAG,MACxC,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,OAAO,KAAK,UAAU,OAAO,EACnCA,EAAAA,IAAC,OAAA,CAAK,OAAO,OAAO,UAAU,SAAA,CAAU,CAAA,EAC1C,SACC,iBAAA,CAAe,GAAG,gBAAgB,GAAG,MAAM,GAAG,MAC7C,SAAA,CAAAA,EAAAA,IAAC,OAAA,CAAK,OAAO,KAAK,UAAU,OAAO,EACnCA,EAAAA,IAAC,OAAA,CAAK,OAAO,OAAO,UAAU,MAAA,CAAO,CAAA,EACvC,EACAqG,EAAAA,KAAC,iBAAA,CAAe,GAAG,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IACnD,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,OAAO,KAAK,UAAU,OAAO,EACnCA,EAAAA,IAAC,OAAA,CAAK,OAAO,MAAM,UAAU,OAAO,EACpCA,EAAAA,IAAC,OAAA,CAAK,OAAO,OAAO,UAAU,MAAA,CAAO,CAAA,EACvC,EACAqG,EAAAA,KAAC,iBAAA,CAAe,GAAG,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IACpD,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,OAAO,KAAK,UAAU,OAAO,EACnCA,EAAAA,IAAC,OAAA,CAAK,OAAO,OAAO,UAAU,MAAA,CAAO,CAAA,EACvC,EACAqG,EAAAA,KAAC,iBAAA,CAAe,GAAG,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IACzD,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,OAAO,KAAK,UAAU,OAAO,EACnCA,EAAAA,IAAC,OAAA,CAAK,OAAO,OAAO,UAAU,MAAA,CAAO,CAAA,CAAA,CACvC,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CACF,CACF,EAQWiF,GAA8C,CAAC,CAAE,IAAA1C,EAAK,SAAA2D,KAAe,CAChF,MAAMxL,EAAIyF,EAAA,EACJ,CACJ,SAAA4f,EACA,UAAAC,EACA,UAAAX,EACA,OAAAqB,EACA,YAAAR,EACA,SAAAE,EACA,OAAAE,EACA,QAAAE,EACA,MAAA3Q,EACA,WAAAyR,EACA,KAAAC,EACA,KAAAE,EACA,UAAAE,EACA,WAAAG,EACA,WAAAC,EACA,WAAAE,CAAA,EACEnC,GAAe,CAAE,IAAAvd,EAAK,EAEpB,CAAC4gB,EAAYC,CAAa,EAAI9f,EAAAA,SAAS,EAAK,EAC5C+f,EAAY7f,EAAAA,OAAuB,IAAI,EACvC8f,EAAiB9f,EAAAA,OAAA,EAEjB+f,EAAWnD,EAAW,EAAIF,EAAcE,EAAW,EAEzD3c,EAAAA,UAAU,IAAM,CACd,MAAM+f,EAAsBjpB,GAAkB,CACxC8oB,EAAU,SAAW,CAACA,EAAU,QAAQ,SAAS9oB,EAAE,MAAc,GACnE6oB,EAAc,EAAK,CAEvB,EACA,OAAID,GACF,SAAS,iBAAiB,YAAaK,CAAkB,EAEpD,IAAM,SAAS,oBAAoB,YAAaA,CAAkB,CAC3E,EAAG,CAACL,CAAU,CAAC,EAEf,MAAMM,EAAoB,IAAM,CAC9B,aAAaH,EAAe,OAAO,EACnCF,EAAc,EAAI,CACpB,EAEMM,EAAoB,IAAM,CAC9BJ,EAAe,QAAU,WAAW,IAAMF,EAAc,EAAK,EAAG,GAAG,CACrE,EAEMO,EAAanD,GAAWF,IAAW,EAAIsD,EAAAA,QAAUtD,EAAS,GAAMuD,EAAAA,QAAUC,EAAAA,QAEhF,OAAIjU,EAEA7P,EAAAA,IAAC,MAAA,CAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,EACpC,EACF,EAKFxJ,EAAAA,KAAC,MAAA,CAAI,UAAU,4IAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,eAAe,MAAO,CAAE,MAAO,QAAS,OAAQ,OAAA,EAE7D,SAAA,CAAArG,EAAAA,IAAC2N,GAAAA,OAAO,IAAP,CACC,UAAU,gCACV,MAAO,CACL,MAAO,QACP,OAAQ,QACR,IAAK,OACL,KAAM,MACN,WAAY,qEAAA,EAEd,QAASqS,EAAY,CAAE,MAAO,CAAC,EAAG,KAAM,CAAC,EAAG,QAAS,CAAC,GAAK,EAAG,EAAG,CAAA,EAAM,CAAE,MAAO,EAAG,QAAS,EAAA,EAC5F,WAAYA,EAAY,CAAE,SAAU,EAAG,OAAQ,IAAU,KAAM,aAAgB,CAAE,SAAU,EAAA,CAAI,CAAA,EAIjG3Z,EAAAA,KAAC,MAAA,CACC,UAAU,oDACV,MAAO,CACL,MAAO,QACP,OAAQ,QACR,IAAK,OACL,KAAM,OACN,WAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYZ,UAAW2Z,EACP,6FACA,6DACJ,UAAW,oCACX,mBAAoBA,EAAY,UAAY,QAAA,EAI9C,SAAA,CAAA3Z,EAAAA,KAAC,MAAA,CACC,UAAU,gCACV,MAAO,CACL,MAAO,MACP,OAAQ,MACR,IAAK,MACL,KAAM,MACN,WAAY,yEACZ,UAAW,mGAAA,EAGb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CACC,UAAU,2DACV,MAAO,CACL,WAAY;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAA,CAMd,CAAA,EAEFA,EAAAA,IAAC,MAAA,CACC,UAAU,gCACV,MAAO,CACL,MAAO,MACP,OAAQ,MACR,IAAK,MACL,KAAM,MACN,WAAY,oDACZ,UAAW,0DAAA,CACb,CAAA,CACF,CAAA,CAAA,EAGDqf,GACCrf,EAAAA,IAAC2N,GAAAA,OAAO,IAAP,CACC,UAAU,4CACV,MAAO,CAAE,OAAQ,iCAAA,EACjB,QAAS,CAAE,MAAO,CAAC,EAAG,KAAM,CAAC,EAAG,QAAS,CAAC,GAAK,GAAK,EAAG,CAAA,EACvD,WAAY,CAAE,SAAU,IAAK,OAAQ,GAAA,CAAS,CAAA,CAChD,CAAA,CAAA,EAKJ3N,MAACkjB,IAAQ,UAAAlD,CAAA,CAAsB,CAAA,EACjC,EAGA3Z,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAArG,EAAAA,IAACmiB,GAAA,CACC,KAAMjc,EACN,UAAU,yEAAA,CAAA,EAEZlG,EAAAA,IAAC,IAAA,CAAE,UAAU,gEAAgE,SAAA,OAAA,CAE7E,CAAA,EACF,EAGAqG,EAAAA,KAAC,MAAA,CACC,UAAU,8HACV,MAAO,CAAE,eAAgB,YAAA,EAGzB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,WACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iDACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,uEAAA,CAAwE,EACvFA,EAAAA,IAAC,MAAA,CACC,UAAU,oEACV,MAAO,CACL,MAAO,GAAGujB,EAAW,GAAG,IACxB,WAAY,mEACZ,UAAWvD,EAAY,gCAAkC,OACzD,WAAY,mBAAA,CACd,CAAA,EAEFhgB,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,IAAI,IACJ,IAAKogB,EAAW,EAAIA,EAAWF,GAAe,IAC9C,KAAK,MACL,MAAOA,EACP,SAAW3lB,GAAMgnB,EAAK,WAAWhnB,EAAE,OAAO,KAAK,CAAC,EAChD,SAAU6lB,GAAY,EACtB,aAAY1lB,EAAE,qBAAqB,EACnC,UAAU,sCAAA,CAAA,CACZ,EACF,EACA2L,EAAAA,KAAC,MAAA,CAAI,UAAU,2EACb,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,mBAAoB,gBAAmB,SAAAiiB,EAAW/B,CAAW,EAAE,EAC9ElgB,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,mBAAoB,cAAA,EAAmB,SAAAogB,EAAW,EAAI6B,EAAW7B,CAAQ,EAAI,OAAA,CAAQ,CAAA,CAAA,CACtG,CAAA,EACF,EAGA/Z,EAAAA,KAAC,MAAA,CAAI,UAAU,yDAEb,SAAA,CAAArG,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAASoU,EACT,WAAY,CAAE,MAAO,GAAA,EACrB,SAAU,CAAE,MAAO,GAAA,EACnB,aAAqBrnB,EAATgmB,EAAW,sBAA2B,oBAAN,EAC5C,UAAW,uGACTA,EACI,qCACA,uCACN,GAEA,SAAA1gB,EAAAA,IAAC+jB,EAAAA,OAAA,CAAO,UAAU,iBAAA,CAAkB,CAAA,CAAA,EAItC/jB,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAAS,IAAM8T,EAAK,GAAG,EACvB,WAAY,CAAE,MAAO,GAAA,EACrB,SAAU,CAAE,MAAO,GAAA,EACnB,aAAY/mB,EAAE,wBAAwB,EACtC,UAAU,+IAEV,SAAAsF,EAAAA,IAACgkB,EAAAA,SAAA,CAAS,UAAU,2BAAA,CAA4B,CAAA,CAAA,EAIlDhkB,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAAS2T,EACT,WAAY,CAAE,MAAO,IAAA,EACrB,SAAU,CAAE,MAAO,GAAA,EACnB,aAAwB5mB,EAAZslB,EAAc,mBAAwB,iBAAN,EAC5C,UAAU,kFACV,MAAO,CACL,WAAY,oEACZ,MAAO,OACP,UAAW,kCAAA,EAGZ,SAAAA,QACEiE,EAAAA,MAAA,CAAM,UAAU,kBAAkB,EAEnCjkB,EAAAA,IAACkkB,EAAAA,KAAA,CAAK,UAAU,4BAAA,CAA6B,CAAA,CAAA,EAKjDlkB,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAAS,IAAM8T,EAAK,EAAE,EACtB,WAAY,CAAE,MAAO,GAAA,EACrB,SAAU,CAAE,MAAO,GAAA,EACnB,aAAY/mB,EAAE,uBAAuB,EACrC,UAAU,+IAEV,SAAAsF,EAAAA,IAACmkB,EAAAA,YAAA,CAAY,UAAU,2BAAA,CAA4B,CAAA,CAAA,EAIrD9d,EAAAA,KAAC,MAAA,CACC,IAAKgd,EACL,UAAU,eACV,aAAcI,EACd,aAAcC,EAEd,SAAA,CAAA1jB,EAAAA,IAAC2N,GAAAA,OAAO,OAAP,CACC,QAASmU,EACT,WAAY,CAAE,MAAO,GAAA,EACrB,SAAU,CAAE,MAAO,GAAA,EACnB,aAAsBpnB,EAAV8lB,EAAY,oBAAyB,iBAAN,EAC3C,UAAW,uGACT2C,EACI,qCACA,wCACN,GAEA,SAAAnjB,EAAAA,IAAC2jB,EAAA,CAAW,UAAU,iBAAA,CAAkB,CAAA,CAAA,EAG1C3jB,EAAAA,IAACwO,GAAAA,iBACE,SAAA2U,GACCnjB,EAAAA,IAAC2N,GAAAA,OAAO,IAAP,CACC,QAAS,CAAE,QAAS,EAAG,MAAO,GAAA,EAC9B,QAAS,CAAE,QAAS,EAAG,MAAO,CAAA,EAC9B,KAAM,CAAE,QAAS,EAAG,MAAO,GAAA,EAC3B,WAAY,CAAE,SAAU,GAAA,EACxB,UAAU,2GACV,MAAO,CACL,KAAM,MACN,WAAY,QACZ,eAAgB,YAAA,EAElB,aAAc8V,EACd,aAAcC,EAEd,SAAArd,EAAAA,KAAC,OAAI,UAAU,mDAAmD,MAAO,CAAE,OAAQ,SACjF,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,4DAA4D,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAA,EACzG,SAAA,CAAArG,EAAAA,IAAC,MAAA,CACC,UAAU,iDACV,MAAO,CAAE,MAAO,MAAO,OAAQ,MAAA,CAAO,CAAA,EAExCA,EAAAA,IAAC,MAAA,CACC,UAAU,qEACV,MAAO,CACL,MAAO,MACP,OAAQ,IAAIwgB,EAAU,EAAIF,GAAU,GAAG,IACvC,WAAY,yBACZ,WAAY,oBAAA,CACd,CAAA,EAEFtgB,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,IAAI,IACJ,IAAI,IACJ,KAAK,OACL,MAAOwgB,EAAU,EAAIF,EACrB,SAAW/lB,GAAMonB,EAAU,WAAWpnB,EAAE,OAAO,KAAK,CAAC,EACrD,aAAYG,EAAE,mBAAmB,EACjC,UAAU,sCACV,MAAO,CACL,MAAO,OACP,OAAQ,OACR,UAAW,iBACX,gBAAiB,eAAA,CACnB,CAAA,CACF,EACF,EACAsF,EAAAA,IAAC,OAAA,CAAK,UAAU,wDACb,SAAA,KAAK,OAAOwgB,EAAU,EAAIF,GAAU,GAAG,CAAA,CAC1C,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAEJ,CAAA,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CAAA,CAAA,QAGD,QAAA,CAAM,IAAKP,EAAU,IAAKxd,EAAK,UAAU,YAAA,CAAa,CAAA,EACzD,CAEJ,iHCheO,SAAS6hB,GAAkBC,EAAcC,EAAkD,CAChG,MAAMxc,EAAgBpH,GAAA,EAChB,CAACqT,EAAMC,CAAO,EAAI1Q,EAAAA,SAAS,EAAE,EAC7B,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EAE3CG,OAAAA,EAAAA,UAAU,IAAM,CACd,IAAIC,EAAY,GAChB,OAAAwQ,EAAW,EAAI,EACfqQ,GAAAA,WAAWF,EAAM,CACf,KAAAC,EACA,MAAOxc,IAAkB,QAAU,eAAiB,WAAA,CACrD,EACE,KAAM0c,GAAQ,CACR9gB,IACHsQ,EAAQwQ,CAAG,EACXtQ,EAAW,EAAK,EAEpB,CAAC,EACA,MAAM,IAAM,CACNxQ,IACHsQ,EAAQ,EAAE,EACVE,EAAW,EAAK,EAEpB,CAAC,EACI,IAAM,CACXxQ,EAAY,EACd,CACF,EAAG,CAAC2gB,EAAMC,EAAMxc,CAAa,CAAC,EAEvB,CAAE,KAAAiM,EAAM,QAAAE,CAAA,CACjB,CC7BA,MAAMwQ,GAAWrC,GAAiB,CAChC,KAAM,CAACsC,EAAQC,CAAS,EAAIrhB,EAAAA,SAAS,EAAK,EACpCshB,EAAana,EAAAA,YAAY,SAAY,CACzC,GAAI,CACF,MAAM,UAAU,UAAU,UAAU2X,CAAI,CAC1C,MAAQ,CACN,MAAMyC,EAAW,SAAS,cAAc,UAAU,EAClDA,EAAS,MAAQzC,EACjB,SAAS,KAAK,YAAYyC,CAAQ,EAClCA,EAAS,OAAA,EACT,SAAS,YAAY,MAAM,EAC3B,SAAS,KAAK,YAAYA,CAAQ,CACpC,CACAF,EAAU,EAAI,EACd,WAAW,IAAMA,EAAU,EAAK,EAAG,GAAI,CACzC,EAAG,CAACvC,CAAI,CAAC,EACT,MAAO,CAAE,OAAAsC,EAAQ,WAAAE,CAAA,CACnB,EAGME,GAAmB,CAAC,CAAE,KAAA1C,KAA6B,CACvD,MAAM,EAAIjiB,EAAA,EACJ,CAAE,OAAAukB,EAAQ,WAAAE,GAAeH,GAAQrC,CAAI,EAC3C,OACEpiB,EAAAA,IAAC,SAAA,CACC,QAAS4kB,EACT,UAAU,8HACV,MAAgB,EAATF,EAAW,kBAAuB,oBAAN,EAElC,SAAAA,QAAUK,EAAAA,MAAA,CAAM,KAAM,GAAI,EAAK/kB,EAAAA,IAACglB,EAAAA,KAAA,CAAK,KAAM,EAAA,CAAI,CAAA,CAAA,CAGtD,EAGMC,GAAqB,CAAC,CAAE,KAAA7C,KAA6B,CACzD,MAAM,EAAIjiB,EAAA,EACJ,CAAE,OAAAukB,EAAQ,WAAAE,GAAeH,GAAQrC,CAAI,EAC3C,OACEpiB,EAAAA,IAAC,SAAA,CACC,QAAS4kB,EACT,UAAU,kPACV,MAAgB,EAATF,EAAW,kBAAuB,oBAAN,EAElC,SAAAA,QAAUK,EAAAA,MAAA,CAAM,KAAM,GAAI,EAAK/kB,EAAAA,IAACglB,EAAAA,KAAA,CAAK,KAAM,EAAA,CAAI,CAAA,CAAA,CAGtD,EAGME,GAAiB,CAAC,CAAE,KAAAb,EAAM,KAAAC,KAA2C,CACzE,KAAM,CAAE,KAAAvQ,CAAA,EAASqQ,GAAkBC,EAAMC,CAAI,EAC7C,OACEje,EAAAA,KAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,qJACb,SAAA,CAAArG,EAAAA,IAAC,OAAA,CAAK,UAAU,kEAAmE,SAAAskB,EAAK,EACxFtkB,EAAAA,IAAC8kB,GAAA,CAAiB,KAAMT,CAAA,CAAM,CAAA,EAChC,EACCtQ,EACC/T,EAAAA,IAAC,MAAA,CACC,UAAU,wGACV,wBAAyB,CAAE,OAAQ+T,CAAA,CAAK,CAAA,EAG1C/T,EAAAA,IAAC,MAAA,CACC,UAAU,qHACV,MAAO,CAAE,SAAU,OAAQ,WAAY,KAAA,EAEvC,SAAAA,EAAAA,IAAC,OAAA,CAAK,UAAU,6CAA8C,SAAAqkB,CAAA,CAAK,CAAA,CAAA,CACrE,EAEJ,CAEJ,EAEalf,GAAoD,CAAC,CAAE,IAAA5C,EAAK,SAAA4iB,EAAW,aAAgB,CAClG,MAAMzqB,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACqiB,EAASC,CAAU,EAAI/hB,EAAAA,SAAiB,EAAE,EAC3C,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAAE,KAAMgiB,CAAA,EAAelB,GAC3Be,IAAa,SAAWC,EAAU,GAClC,UAAA,EAqBF,OAlBA3hB,EAAAA,UAAU,IAAM,EACO,SAAY,CAC/B,GAAI,CACFyQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb,MAAMsS,EAAO,MAAMmD,GAAchjB,EAAK,CAAE,QAAAW,EAAS,EACjDmiB,EAAWjD,CAAI,CACjB,OAASve,EAAK,CACZiM,EAASpV,EAAE,sBAAsB,CAAC,EAClC,QAAQ,MAAMmJ,CAAG,CACnB,QAAA,CACEqQ,EAAW,EAAK,CAClB,CACF,GAEA,CACF,EAAG,CAAC3R,EAAKW,EAASxI,CAAC,CAAC,EAEhBuZ,EAEAjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIA6P,EAEA7P,EAAAA,IAAC,MAAA,CAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,EACpC,EACF,EAKAsV,IAAa,SAEbnlB,EAAAA,IAAC,MAAA,CAAI,UAAU,yDACZ,SAAAslB,EACCtlB,EAAAA,IAAC,MAAA,CACC,UAAU,sCACV,wBAAyB,CAAE,OAAQslB,CAAA,CAAW,CAAA,EAGhDtlB,EAAAA,IAAC,MAAA,CAAI,UAAU,gGACZ,WACH,EAEJ,QAMD,MAAA,CAAI,UAAU,8DACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,8CACb,SAAAA,EAAAA,IAACwlB,GAAA,CACG,cAAe,CAACC,GAAWC,EAAU,EACrC,cAAe,CAACC,GAAWC,EAAW,EACtC,WAAY,CACV,KAAK,CAAE,KAAAC,EAAM,OAAAC,EAAQ,UAAAllB,EAAW,SAAAhB,EAAU,GAAG+G,GAAc,CACzD,MAAMof,EAAQ,iBAAiB,KAAKnlB,GAAa,EAAE,EAC7ColB,EAAa,OAAOpmB,CAAQ,EAAE,QAAQ,MAAO,EAAE,EACrD,MAAI,CAACkmB,GAAUC,QAELb,GAAA,CAAe,KAAMc,EAAY,KAAMD,EAAM,CAAC,EAAG,EAEtDD,EAgBH9lB,EAAAA,IAAC,OAAA,CACC,UAAU,mIACT,GAAG2G,EAEH,SAAA/G,CAAA,CAAA,EAjBDyG,EAAAA,KAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAArG,EAAAA,IAACilB,GAAA,CAAmB,KAAMe,CAAA,CAAY,EACtChmB,EAAAA,IAAC,MAAA,CACC,UAAU,oGACV,MAAO,CAAE,SAAU,OAAQ,WAAY,KAAA,EAEvC,SAAAA,EAAAA,IAAC,OAAA,CAAK,UAAU,6CAA8C,SAAAJ,CAAA,CAAS,CAAA,CAAA,CACzE,EACF,CAYN,EACA,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,sFACX,SAAAJ,EACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,uEACX,SAAAJ,EACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,sEAAuE,SAAAJ,EAAS,EAEhG,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,sEAAuE,SAAAJ,EAAS,EAEhG,EAAG,CAAC,CAAE,SAAAA,CAAA,IACJI,EAAAA,IAAC,IAAA,CAAE,UAAU,6DAA8D,SAAAJ,EAAS,EAEtF,EAAG,CAAC,CAAE,KAAAmd,EAAM,SAAAnd,KACVI,EAAAA,IAAC,IAAA,CACC,KAAA+c,EACA,UAAU,wHACV,OAAO,SACP,IAAI,sBAEH,SAAAnd,CAAA,CAAA,EAGL,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,sEAAuE,SAAAJ,EAAS,EAEhG,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,yEAA0E,SAAAJ,EAAS,EAEnG,GAAI,CAAC,CAAE,SAAAA,CAAA,IAAeI,EAAAA,IAAC,KAAA,CAAG,UAAU,gBAAiB,SAAAJ,EAAS,EAC9D,WAAY,CAAC,CAAE,SAAAA,CAAA,IACbI,EAAAA,IAAC,aAAA,CAAW,UAAU,0FACnB,SAAAJ,EACH,EAEF,MAAO,CAAC,CAAE,SAAAA,CAAA,IACRI,EAAAA,IAAC,MAAA,CAAI,UAAU,yEACb,SAAAA,EAAAA,IAAC,QAAA,CAAM,UAAU,gDAAiD,SAAAJ,EAAS,EAC7E,EAEF,MAAO,CAAC,CAAE,SAAAA,CAAA,IAAeI,EAAAA,IAAC,QAAA,CAAM,UAAU,mBAAoB,SAAAJ,EAAS,EACvE,MAAO,CAAC,CAAE,SAAAA,CAAA,IACRI,EAAAA,IAAC,QAAA,CAAM,UAAU,oDAAqD,SAAAJ,EAAS,EAEjF,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,+CAAgD,SAAAJ,EAAS,EAEzE,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,sHACX,SAAAJ,EACH,EAEF,GAAI,CAAC,CAAE,SAAAA,CAAA,IACLI,EAAAA,IAAC,KAAA,CAAG,UAAU,sDAAuD,SAAAJ,EAAS,EAEhF,GAAI,IAAMI,EAAAA,IAAC,KAAA,CAAG,UAAU,0BAAA,CAA2B,EACnD,IAAK,CAAC,CAAE,IAAAimB,EAAK,IAAAC,KACXlmB,EAAAA,IAAC,MAAA,CACC,IAAAimB,EACA,IAAAC,EACA,UAAU,uFAAA,CAAA,EAGd,MAAO,CAAC,CAAE,KAAAxO,EAAM,QAAAyO,EAAS,GAAGxf,KACtB+Q,IAAS,WAET1X,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAAAmmB,EACA,SAAQ,GACR,UAAU,uCACT,GAAGxf,CAAA,CAAA,EAIH3G,EAAAA,IAAC,QAAA,CAAM,KAAA0X,EAAa,GAAG/Q,CAAA,CAAO,EAEvC,OAAQ,CAAC,CAAE,SAAA/G,CAAA,IACTI,EAAAA,IAAC,SAAA,CAAO,UAAU,wCAAyC,SAAAJ,EAAS,EAEtE,GAAI,CAAC,CAAE,SAAAA,CAAA,IAAeI,EAAAA,IAAC,KAAA,CAAG,UAAU,aAAc,SAAAJ,EAAS,EAC3D,IAAK,CAAC,CAAE,SAAAA,KACNI,EAAAA,IAAC,MAAA,CAAI,UAAU,qCAAsC,SAAAJ,CAAA,CAAS,CAAA,EAIjE,SAAAwlB,CAAA,CAAA,EAEP,CAAA,CACF,CAEJ,oHC9QMgB,GAA0B,CAC9B,IAAK,UACL,OAAQ,UACR,OAAQ,UACR,QAAS,UACT,QAAS,UACT,MAAO,yBACP,UAAW,yBACX,MAAO,wBACT,EAEMC,GAA2B,CAC/B,IAAK,UACL,OAAQ,UACR,OAAQ,UACR,QAAS,UACT,QAAS,UACT,MAAO,sBACP,UAAW,uBACX,MAAO,sBACT,EAYMC,GAAoC,CAAC,CAAE,QAAAC,EAAS,MAAA1mB,EAAO,MAAAue,EAAO,gBAAAoI,EAAiB,OAAAC,KAAa,CAChG,MAAM/rB,EAAIyF,EAAA,EACJ,CAACumB,EAAUC,CAAW,EAAIrjB,EAAAA,SAASkjB,CAAe,EAClDI,EAASxI,EAAQ,GAEjByI,EAASpc,EAAAA,YAAY,IAAMkc,KAAoB,CAAC7a,CAAI,EAAG,EAAE,EAG/D,GAAIjM,GAAU,MAA+B,OAAOA,GAAU,SAC5D,OACEwG,EAAAA,KAAC,MAAA,CAAI,UAAU,+DAA+D,MAAO,CAAE,YAAa,GAAGugB,CAAM,IAAA,EAC3G,SAAA,CAAA5mB,EAAAA,IAAC,OAAA,CAAK,UAAU,mCAAA,CAAoC,EACnDumB,IAAY,QACXlgB,EAAAA,KAAC,OAAA,CAAK,UAAU,oBAAoB,MAAO,CAAE,MAAOogB,EAAO,GAAA,EAAO,SAAA,CAAA,IAC9DF,EAAQ,IAACvmB,MAAC,QAAK,MAAO,CAAE,MAAOymB,EAAO,KAAA,EAAS,SAAA,IAAA,CAAE,CAAA,EACrD,EAEDK,GAAgBjnB,EAAO4mB,CAAM,CAAA,EAChC,EAIJ,MAAMM,EAAU,MAAM,QAAQlnB,CAAK,EAE7ByX,GADUyP,EAAWlnB,EAAsB,OAAO,QAAQA,CAAgC,GAC1E,OAChBmnB,EAAcD,EAAU,IAAM,IAC9BE,EAAeF,EAAU,IAAM,IAGrC,OAAIzP,IAAU,EAEVjR,EAAAA,KAAC,MAAA,CAAI,UAAU,+DAA+D,MAAO,CAAE,YAAa,GAAGugB,CAAM,IAAA,EAC3G,SAAA,CAAA5mB,EAAAA,IAAC,OAAA,CAAK,UAAU,mCAAA,CAAoC,EACnDumB,IAAY,QACXlgB,EAAAA,KAAC,OAAA,CAAK,UAAU,oBAAoB,MAAO,CAAE,MAAOogB,EAAO,GAAA,EAAO,SAAA,CAAA,IAC9DF,EAAQ,IAACvmB,MAAC,QAAK,MAAO,CAAE,MAAOymB,EAAO,KAAA,EAAS,SAAA,IAAA,CAAE,CAAA,EACrD,SAED,OAAA,CAAK,MAAO,CAAE,MAAOA,EAAO,SAAY,SAAA,CAAAO,EAAaC,CAAA,CAAA,CAAa,CAAA,EACrE,SAKD,MAAA,CAEC,SAAA,CAAA5gB,EAAAA,KAAC,MAAA,CACC,UAAU,yHACV,MAAO,CAAE,YAAa,GAAGugB,CAAM,IAAA,EAC/B,QAASC,EAET,SAAA,CAAA7mB,EAAAA,IAAC,QAAK,UAAU,iFAAiF,MAAO,CAAE,MAAOymB,EAAO,KAAA,EACrH,WACGzmB,EAAAA,IAACknB,cAAA,CAAY,UAAU,sBAAsB,QAC5CzlB,EAAAA,aAAA,CAAa,UAAU,sBAAsB,CAAA,CAEpD,EACC8kB,IAAY,QACXlgB,EAAAA,KAAC,OAAA,CAAK,UAAU,oBAAoB,MAAO,CAAE,MAAOogB,EAAO,GAAA,EAAO,SAAA,CAAA,IAC9DF,EAAQ,IAACvmB,MAAC,QAAK,MAAO,CAAE,MAAOymB,EAAO,KAAA,EAAS,SAAA,IAAA,CAAE,CAAA,EACrD,EAEFzmB,MAAC,QAAK,MAAO,CAAE,MAAOymB,EAAO,OAAA,EAAY,SAAAO,EAAY,EACpD,CAACN,GACArgB,EAAAA,KAAC,OAAA,CAAK,UAAU,WAAW,MAAO,CAAE,MAAOogB,EAAO,SAAA,EAC/C,SAAA,CAAAM,EAAU,GAAGzP,CAAK,IAAI5c,EAAE,YAAY,CAAC,GAAK,GAAG4c,CAAK,IAAI5c,EAAE,WAAW,CAAC,UACpE,OAAA,CAAK,MAAO,CAAE,MAAO+rB,EAAO,SAAW,SAAA,CAAA,IAAEQ,CAAA,CAAA,CAAa,CAAA,CAAA,CACzD,CAAA,CAAA,CAAA,EAKHP,GACCrgB,EAAAA,KAAAwH,WAAA,CACG,SAAA,CAAAkZ,EACIlnB,EAAoB,IAAI,CAAC2N,EAAMnS,IAC9B2E,MAACsmB,IAAiB,MAAO9Y,EAAM,MAAO4Q,EAAQ,EAAG,gBAAiBA,EAAQ,EAAG,OAAAqI,GAA9DprB,CAA8E,CAC9F,EACD,OAAO,QAAQwE,CAAgC,EAAE,IAAI,CAAC,CAACpF,EAAGyC,CAAC,IACzD8C,MAACsmB,IAAiB,QAAS7rB,EAAG,MAAOyC,EAAG,MAAOkhB,EAAQ,EAAG,gBAAiBA,EAAQ,EAAG,OAAAqI,GAAvEhsB,CAAuF,CACvG,EAELuF,EAAAA,IAAC,MAAA,CAAI,UAAU,sCAAsC,MAAO,CAAE,YAAa,GAAG4mB,EAAS,EAAE,KAAM,MAAOH,EAAO,OAAA,EAC1G,SAAAQ,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,CAEJ,EAEA,SAASH,GAAgBjnB,EAAgB4mB,EAAoB,CAC3D,OAAI5mB,IAAU,KAAaG,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAOymB,EAAO,QAAS,UAAW,QAAA,EAAY,SAAA,OAAI,EACxF5mB,IAAU,OAAkBG,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAOymB,EAAO,QAAS,UAAW,QAAA,EAAY,SAAA,YAAS,EAClG,OAAO5mB,GAAU,gBAAmB,OAAA,CAAK,MAAO,CAAE,MAAO4mB,EAAO,OAAA,EAAY,SAAA,OAAO5mB,CAAK,EAAE,EAC1F,OAAOA,GAAU,eAAkB,OAAA,CAAK,MAAO,CAAE,MAAO4mB,EAAO,MAAA,EAAW,SAAA,OAAO5mB,CAAK,EAAE,EACxF,OAAOA,GAAU,SAAiBwG,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,MAAOogB,EAAO,MAAA,EAAU,SAAA,CAAA,IAAE5mB,EAAM,GAAA,EAAC,EAC/EG,MAAC,OAAA,CAAK,MAAO,CAAE,MAAOymB,EAAO,OAAA,EAAY,SAAA,OAAO5mB,CAAK,CAAA,CAAE,CAChE,CAEA,SAASsnB,GAAW1mB,EAAkC,CACpD,OAAOA,IAAU,QAAU4lB,GAAeD,EAC5C,CAIO,MAAM/gB,GAA4C,CAAC,CAAE,IAAA9C,KAAU,CACpE,MAAM,EAAIpC,EAAA,EACJ+C,EAAUH,GAAA,EACV+E,EAAgBpH,GAAA,EAChB+lB,EAAS3mB,EAAAA,QAAQ,IAAMqnB,GAAWrf,CAAa,EAAG,CAACA,CAAa,CAAC,EACjE,CAACsf,EAAMC,CAAO,EAAI/jB,EAAAA,SAAkB,IAAI,EACxC,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAmBtD,OAjBAG,EAAAA,UAAU,IAAM,EACG,SAAY,CAC3B,GAAI,CACFyQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb,MAAMsS,EAAO,MAAMmD,GAAchjB,EAAK,CAAE,QAAAW,EAAS,EACjDmkB,EAAQ,KAAK,MAAMjF,CAAI,CAAC,CAC1B,OAASve,EAAK,CACZiM,EAAS,EAAE,kBAAkB,CAAC,EAC9B,QAAQ,MAAMjM,CAAG,CACnB,QAAA,CACEqQ,EAAW,EAAK,CAClB,CACF,GACA,CACF,EAAG,CAAC3R,CAAG,CAAC,EAEJ0R,EAEAjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIA6P,EAEA7P,EAAAA,IAAC,MAAA,CAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,EACpC,EACF,EAKF7P,EAAAA,IAAC,MAAA,CAAI,UAAU,2EACb,SAAAA,EAAAA,IAACsmB,GAAA,CAAS,MAAOc,EAAM,MAAO,EAAG,gBAAe,GAAC,OAAAX,EAAgB,EACnE,CAEJ,gHCjMalhB,GAA0C,CAAC,CAAE,IAAAhD,EAAK,SAAA2D,KAAe,CAC5E,MAAMxL,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACkR,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChDoN,EAAelN,EAAAA,OAAuB,IAAI,EAC1CuR,EAAiBvR,EAAAA,OAA2B,IAAI,EAChDwR,EAAexR,EAAAA,OAAyC,IAAI,EAC5DyR,EAAoBzR,EAAAA,OAA8B,IAAI,EACtD0R,EAAmB1R,EAAAA,OAAsB,IAAI,EAC7C2R,EAAoB3R,EAAAA,OAAO,CAAE,MAAO,EAAG,OAAQ,EAAG,EAElD4R,EAAsB3K,EAAAA,YAAY,IAAM,CAC5C,GAAI,CAACiG,EAAa,QAAS,MAAO,CAAE,MAAO,IAAK,OAAQ,GAAA,EACxD,MAAM2E,EAAW3E,EAAa,QAAQ,YAChC4E,EAAY5E,EAAa,QAAQ,aACjC/B,EAAQ0G,EAAW,IAAMA,EAAW,IACpCzG,EAAS0G,EAAY,IAAMA,EAAY,IAC7C,MAAO,CAAE,MAAA3G,EAAO,OAAAC,CAAA,CAClB,EAAG,CAAA,CAAE,EAEC2G,EAAmB9K,EAAAA,YAAY,IAAM,CACzC,GAAI,CAACiG,EAAa,SAAW,CAACsE,EAAa,QAAS,OAEpDtE,EAAa,QAAQ,UAAY,GACjCqE,EAAe,QAAU,KAEzB,KAAM,CAAE,MAAApG,EAAO,OAAAC,CAAA,EAAWwG,EAAA,EACpBI,EAAW7G,EAAQ,IAEnBrT,EAAI,IAAIma,GAAY/E,EAAa,QAAS,CAC9C,KAAM,OACN,YAAa,GACb,gBAAiB,GACjB,SAAU,GACV,IAAK,CACH,IAAK,IACL,OAAQ,EAAA,EAEV,IAAK,CACH,IAAK,GACL,MAAO8E,EAAW,GAAK,IACvB,WAAYA,EAAW,GAAK,GAC5B,SAAUA,EAAW,GAAK,EAAA,EAE5B,KAAM,CACJ,OAAQ,IAAM5G,EACd,MAAO,IAAMD,CAAA,CACf,CACD,EAEDrT,EAAE,SAAS0Z,EAAa,OAA6C,EACrED,EAAe,QAAUzZ,CAC3B,EAAG,CAAC8Z,CAAmB,CAAC,EAExB3R,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAACiN,EAAa,QAAS,OAE3B,IAAIgF,EAAkB,GAEtB,MAAMC,EAAmB,IAAM,CAC7B,GAAID,EAAiB,CACnBA,EAAkB,GAClBP,EAAkB,QAAUC,EAAA,EAC5B,MACF,CAEA,MAAMQ,EAAgBR,EAAA,EAChBS,EAAiBV,EAAkB,QACnCW,EAAY,KAAK,IAAID,EAAe,MAAQD,EAAc,KAAK,EAC/DG,EAAa,KAAK,IAAIF,EAAe,OAASD,EAAc,MAAM,EAEpEE,EAAY,IAAMC,EAAa,KAEnCZ,EAAkB,QAAUS,EAExBV,EAAiB,SACnB,aAAaA,EAAiB,OAAO,EAGvCA,EAAiB,QAAU,OAAO,WAAW,IAAM,CAC7CF,EAAa,SACfO,EAAA,CAEJ,EAAG,GAAG,EACR,EAEA,OAAAN,EAAkB,QAAU,IAAI,eAAe,IAAM,CACnDU,EAAA,CACF,CAAC,EAEDV,EAAkB,QAAQ,QAAQvE,EAAa,OAAO,EAE/C,IAAM,CACPuE,EAAkB,SACpBA,EAAkB,QAAQ,WAAA,EAExBC,EAAiB,SACnB,aAAaA,EAAiB,OAAO,CAEzC,CACF,EAAG,CAACE,EAAqBG,CAAgB,CAAC,EAE1C9R,EAAAA,UAAU,IAAM,CACd,IAAIuS,EAAY,GAEhB,MAAMsR,EAAU,SAAY,CAC1B,GAAK5W,EAAa,QAElB,CAAAwD,EAAW,EAAI,EACfpE,EAAS,IAAI,EAEb,GAAI,CACF,MAAMsS,EAAO,MAAMmD,GAAchjB,EAAK,CAAE,QAAAW,EAAS,EAC3CqkB,EAASC,GAASpF,EAAM,CAAE,UAAWqF,GAAkBvhB,CAAQ,EAAG,EAClEkQ,EAAYsR,GAA4BH,EAAO,OAAQA,EAAO,KAAMrhB,CAAQ,EAElF,GAAI,CAAC8P,EAAW,OAEhBhB,EAAa,QAAUoB,EACvBb,EAAA,EACArB,EAAW,EAAK,CAClB,OAASrQ,EAAK,CACRmS,IACF,QAAQ,MAAM,YAAanS,CAAG,EAC9BiM,EAASpV,EAAE,iBAAiB,CAAC,EAC7BwZ,EAAW,EAAK,EAEpB,EACF,EAEMqC,EAAQ,WAAW,IAAM,CAC7B,sBAAsB,IAAM,CAC1B+Q,EAAA,CACF,CAAC,CACH,EAAG,GAAG,EAEN,MAAO,IAAM,CACXtR,EAAY,GACZ,aAAaO,CAAK,EAClBvB,EAAa,QAAU,KACnBtE,EAAa,UACfA,EAAa,QAAQ,UAAY,IAEnCqE,EAAe,QAAU,IAC3B,CACF,EAAG,CAACxS,EAAK2D,EAAUqP,CAAgB,CAAC,EAGlClP,EAAAA,KAAC,MAAA,CAAI,UAAU,4EACZ,SAAA,CAAA4N,SACE,MAAA,CAAI,UAAU,6HACb,SAAA5N,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,gKAAA,CAAiK,QAC/K,IAAA,CAAE,UAAU,mEAAoE,SAAAtF,EAAE,aAAa,CAAA,CAAE,CAAA,CAAA,CACpG,CAAA,CACF,EAGDmV,GAAS,CAACoE,GACTjU,EAAAA,IAAC,MAAA,CAAI,UAAU,6HACb,SAAAqG,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAArG,EAAAA,IAAC,OAAI,UAAU,yPACb,eAACwW,EAAAA,gBAAA,CAAgB,UAAU,gEAAgE,CAAA,CAC7F,QACC,IAAA,CAAE,UAAU,sFAAuF,SAAA9b,EAAE,iBAAiB,EAAE,EACzHsF,EAAAA,IAAC,IAAA,CAAE,UAAU,uEAAwE,SAAA6P,CAAA,CAAM,CAAA,CAAA,CAC7F,CAAA,CACF,EAGD,CAACA,GACA7P,EAAAA,IAAC,MAAA,CACC,IAAK0Q,EACL,UAAU,mDACV,MAAO,CAAE,QAASuD,EAAU,EAAI,CAAA,CAAE,CAAA,CACpC,EAEJ,CAEJ,+GCxLM0T,GAAkBC,GAAwB,CAC9C,GAAI,CAEF,MAAMC,EADS,IAAI,UAAA,EACA,gBAAgBD,EAAK,iBAAiB,EAGzD,GADgBC,EAAI,cAAc,aAAa,EAClC,OAAOD,EAGpB,MAAME,EADa,IAAI,cAAA,EACO,kBAAkBD,CAAG,EACnD,OAAOE,GAAUD,CAAU,CAC7B,MAAQ,CACN,OAAOF,CACT,CACF,EAEMG,GAAaH,GAAwB,CACzC,MAAMI,EAAU,KACVC,EAAM,eACZ,IAAIC,EAAYN,EAAI,QAAQK,EAAK;AAAA,KAAU,EAEvCE,EAAM,EACV,OAAOD,EACJ,MAAM;AAAA,CAAI,EACV,IAAKE,GAAS,CACb,IAAIxB,EAAS,EACT,SAAS,KAAKwB,CAAI,EACpBD,EAAM,KAAK,IAAIA,EAAM,EAAG,CAAC,EAChB,oBAAoB,KAAKC,CAAI,GAAK,CAAC,aAAa,KAAKA,CAAI,IAClExB,EAAS,GAEX,MAAMyB,EAASL,EAAQ,OAAOG,CAAG,EAAIC,EACrC,OAAAD,GAAOvB,EACAyB,CACT,CAAC,EACA,KAAK;AAAA,CAAI,CACd,EAEa5iB,GAA0C,CAAC,CAAE,IAAAlD,KAAU,CAClE,MAAM,EAAIpC,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACqiB,EAASC,CAAU,EAAI/hB,EAAAA,SAAiB,EAAE,EAC3C,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAAE,KAAMglB,CAAA,EAAgBlE,GAAkBgB,EAAS,KAAK,EAmB9D,OAjBA3hB,EAAAA,UAAU,IAAM,EACD,SAAY,CACvB,GAAI,CACFyQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb,MAAMyY,EAAM,MAAMhD,GAAchjB,EAAK,CAAE,QAAAW,EAAS,EAChDmiB,EAAWsC,GAAeY,CAAG,CAAC,CAChC,OAAS1kB,EAAK,CACZ,QAAQ,MAAMA,CAAG,EACjBiM,EAAS,EAAE,iBAAiB,CAAC,CAC/B,QAAA,CACEoE,EAAW,EAAK,CAClB,CACF,GACA,CACF,EAAG,CAAC3R,CAAG,CAAC,EAEJ0R,EAEAjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIA6P,EAEA7P,EAAAA,IAAC,MAAA,CAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,EACpC,EACF,EAKF7P,EAAAA,IAAC,MAAA,CAAI,UAAU,yDACZ,SAAAsoB,EACCtoB,EAAAA,IAAC,MAAA,CACC,UAAU,sCACV,wBAAyB,CAAE,OAAQsoB,CAAA,CAAY,CAAA,EAGjDtoB,EAAAA,IAAC,MAAA,CAAI,UAAU,gGACZ,WACH,EAEJ,CAEJ,+GC7FMwoB,GAAgD,CACpD,IAAK,MACL,IAAK,MACL,IAAK,MACL,KAAM,OACN,IAAK,MACL,IAAK,MACL,KAAM,OACN,KAAM,MACR,EAEMC,GAAaviB,GAAiD,OAClE,MAAM6G,IAAMxL,EAAA2E,EAAS,MAAM,GAAG,EAAE,IAAA,IAApB,YAAA3E,EAA2B,gBAAiB,GACxD,OAAOinB,GAAczb,CAAG,CAC1B,EAEapH,GAAoD,CAAC,CAAE,IAAApD,EAAK,SAAA2D,KAAe,CACtF,MAAMxL,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACqf,EAAMsG,CAAO,EAAIplB,EAAAA,SAAiB,EAAE,EACrC,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAEtDG,EAAAA,UAAU,IAAM,EACD,SAAY,CACvB,GAAI,CACFyQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb4Y,EAAQ,MAAMnD,GAAchjB,EAAK,CAAE,QAAAW,CAAA,CAAS,CAAC,CAC/C,OAASW,EAAK,CACZ,QAAQ,MAAMA,CAAG,EACjBiM,EAASpV,EAAE,sBAAsB,CAAC,CACpC,QAAA,CACEwZ,EAAW,EAAK,CAClB,CACF,GACA,CACF,EAAG,CAAC3R,CAAG,CAAC,EAER,MAAMglB,EAAqCznB,EAAAA,QAAQ,IAAM,CACvD,GAAI,CAACsiB,EAAM,OAAO,KAClB,GAAI,CACF,OAAOuG,GAAcvG,EAAMqG,GAAUviB,CAAQ,CAAC,CAChD,OAASrC,EAAK,CACZ,eAAQ,MAAMA,CAAG,EACV,IACT,CACF,EAAG,CAACue,EAAMlc,CAAQ,CAAC,EAEnB,GAAI+N,EACF,OACEjU,MAAC,OAAI,UAAU,sFACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIJ,GAAI6P,GAAS,CAAC0X,EACZ,aACG,MAAA,CAAI,UAAU,sFACb,SAAAvnB,EAAAA,IAAC,OAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,GAASnV,EAAE,uBAAuB,EAAE,EAClE,CAAA,CACF,EAIJ,MAAMkuB,EAAUrB,EAAO,SAAW,OAASA,EAAO,SAAW,OACvDsB,EAAOtB,EAAO,UAAY,CAAA,EAC1BuB,EAAWF,EAAU,gCAAkC,6BAE7D,OACEviB,EAAAA,KAAC,MAAA,CAAI,UAAU,sDAEb,SAAA,CAAArG,EAAAA,IAAC,OAAI,UAAU,gGACb,SAAAqG,EAAAA,KAAC,MAAA,CAAI,UAAU,yCAEb,SAAA,CAAArG,EAAAA,IAAC,MAAA,CAAI,UAAU,gGAAA,CAAiG,EAEhHA,EAAAA,IAAC,KAAA,CAAG,UAAU,iCACX,SAAAunB,EAAO,KAAK,IAAI,CAACwB,EAAK1tB,IACrBgL,OAAC,KAAA,CAAoB,UAAU,8CAE7B,SAAA,CAAArG,EAAAA,IAAC,MAAA,CACC,UAAW,+IAA+I8oB,CAAQ,EAAA,CAAA,EAGpKziB,EAAAA,KAAC,MAAA,CAAI,UAAU,+EACb,SAAA,CAAArG,MAAC,QAAK,UAAU,mEACb,SAAAgpB,GAAmBD,EAAI,KAAK,EAC/B,EACA/oB,EAAAA,IAAC,OAAA,CAAK,UAAU,uCAAuC,SAAA,IAAC,QACvD,OAAA,CAAK,UAAU,mEACb,SAAAgpB,GAAmBD,EAAI,GAAG,EAC7B,EACA1iB,EAAAA,KAAC,OAAA,CAAK,UAAU,sEAAsE,SAAA,CAAA,IAClF0iB,EAAI,IAAM1tB,EAAI,CAAA,EAClB,EACC0tB,EAAI,OACH/oB,EAAAA,IAAC,QAAK,UAAU,2JACb,WAAI,KAAA,CACP,CAAA,EAEJ,EAEC+oB,EAAI,OAASA,EAAI,MAAM,OAAS,EAC/B/oB,EAAAA,IAAC,MAAA,CAAI,UAAU,8KACZ,SAAA+oB,EAAI,MAAM,IAAI,CAACE,EAAMC,IACpB7iB,EAAAA,KAAC,OAAA,CAEC,UAAU,+CACV,MAAO2iB,GAAmBC,EAAK,KAAK,EAEpC,SAAA,CAAAjpB,EAAAA,IAAC,OAAA,CAAK,UAAU,sFACb,SAAAgpB,GAAmBC,EAAK,KAAK,EAAE,MAAM,EAAG,CAAC,CAAA,CAC5C,EACAjpB,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,WAAK,IAAA,CAAK,CAAA,CAAA,EAPzC,KAAKkpB,CAAE,EAAA,CASf,EACH,EAEAlpB,EAAAA,IAAC,IAAA,CACC,UAAW,yIACT4oB,EAAU,+CAAiD,8BAC7D,GAEC,SAAAG,EAAI,IAAA,CAAA,CACP,CAAA,EA9CK,OAAO1tB,CAAC,EAgDjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,EAGAgL,EAAAA,KAAC,MAAA,CAAI,UAAU,iTACb,SAAA,CAAAA,OAAC,OAAA,CAAM,SAAA,CAAAkhB,EAAO,KAAK,OAAO,IAAY7sB,EAAVkuB,EAAY,iBAAsB,eAAN,CAAqB,EAAE,EAC9EC,EAAK,QACJxiB,EAAAA,KAAAwH,EAAAA,SAAA,CACE,SAAA,CAAA7N,EAAAA,IAAC,OAAA,CAAK,UAAU,uBAAuB,SAAA,IAAC,EACxCA,EAAAA,IAAC,OAAA,CAAM,SAAA6oB,EAAK,MAAA,CAAO,CAAA,CAAA,CACrB,CAAA,CAAA,CAEJ,CAAA,EACF,CAEJ,oHCtIaM,GAAgD,CAAC,CAC5D,KAAAC,EACA,MAAAC,EACA,iBAAAC,EAAmB,IACnB,aAAAC,EAAe,IACf,aAAAC,EAAe,IACf,cAAAC,EAAgB,IAChB,WAAAC,EACA,aAAAC,EAAe,qBACf,UAAA/oB,EAAY,EACd,IAAM,CACJ,MAAM8P,EAAelN,EAAAA,OAAuB,IAAI,EAC1C,CAAComB,EAAWC,CAAY,EAAIvmB,EAAAA,SAAiB,IAAM,CACvD,GAAIomB,GAAc,OAAO,OAAW,IAAa,CAC/C,MAAMI,EAAQ,OAAO,OAAO,aAAa,QAAQJ,CAAU,CAAC,EAC5D,GAAI,CAAC,MAAMI,CAAK,GAAKA,EAAQ,EAAG,OAAOA,CACzC,CACA,OAAOR,CACT,CAAC,EACK,CAACS,EAAUC,CAAW,EAAI1mB,EAAAA,SAAS,EAAK,EACxC,CAAC2mB,EAAWC,CAAY,EAAI5mB,EAAAA,SAAS,EAAK,EAGhDG,EAAAA,UAAU,IAAM,CACd,GAAI,OAAO,OAAW,IAAa,OACnC,MAAM0mB,EAAK,OAAO,WAAWR,CAAY,EACnC9hB,EAAU,IAAMqiB,EAAaC,EAAG,OAAO,EAC7C,OAAAtiB,EAAA,EACAsiB,EAAG,iBAAiB,SAAUtiB,CAAO,EAC9B,IAAMsiB,EAAG,oBAAoB,SAAUtiB,CAAO,CACvD,EAAG,CAAC8hB,CAAY,CAAC,EAGjBlmB,EAAAA,UAAU,IAAM,CACd,GAAI,CAACsmB,EAAU,OACf,MAAMK,EAAc7vB,GAAkB,CACpC,GAAI,CAACmW,EAAa,QAAS,OAC3B,MAAMiB,EAAOjB,EAAa,QAAQ,sBAAA,EAC5BzT,EAAI1C,EAAE,QAAUoX,EAAK,KACrB0Y,EAAM1Y,EAAK,MAAQ8X,EAAgB,EACnCa,EAAe,KAAK,IAAId,EAAca,CAAG,EACzCE,EAAO,KAAK,IAAIhB,EAAc,KAAK,IAAIe,EAAcrtB,CAAC,CAAC,EAC7D4sB,EAAaU,CAAI,CACnB,EACMC,EAAW,IAAMR,EAAY,EAAK,EACxC,OAAO,iBAAiB,YAAaI,CAAU,EAC/C,OAAO,iBAAiB,UAAWI,CAAQ,EAC3C,MAAMC,EAAa,SAAS,KAAK,MAAM,OACjCC,EAAa,SAAS,KAAK,MAAM,WACvC,gBAAS,KAAK,MAAM,OAAS,aAC7B,SAAS,KAAK,MAAM,WAAa,OAC1B,IAAM,CACX,OAAO,oBAAoB,YAAaN,CAAU,EAClD,OAAO,oBAAoB,UAAWI,CAAQ,EAC9C,SAAS,KAAK,MAAM,OAASC,EAC7B,SAAS,KAAK,MAAM,WAAaC,CACnC,CACF,EAAG,CAACX,EAAUR,EAAcC,EAAcC,CAAa,CAAC,EAGxDhmB,EAAAA,UAAU,IAAM,CACd,GAAI,GAACimB,GAAcK,GACnB,GAAI,CACF,OAAO,aAAa,QAAQL,EAAY,OAAOE,CAAS,CAAC,CAC3D,MAAQ,CAER,CACF,EAAG,CAACA,EAAWF,EAAYK,CAAQ,CAAC,EAEpC,MAAMY,EAAoBlgB,cAAalQ,GAAwB,CAC7DA,EAAE,eAAA,EACFyvB,EAAY,EAAI,CAClB,EAAG,CAAA,CAAE,EAEL,OACE3jB,EAAAA,KAAC,MAAA,CACC,IAAKqK,EACL,UAAW,uFAAuF9P,CAAS,GAE3G,SAAA,CAAAZ,EAAAA,IAAC,MAAA,CACC,UAAU,oGACV,MAAOiqB,EAAY,CAAE,MAAO,GAAGL,CAAS,MAAS,OAEhD,SAAAR,CAAA,CAAA,EAGHppB,EAAAA,IAAC,MAAA,CACC,KAAK,YACL,mBAAiB,WACjB,YAAa2qB,EACb,UAAW,gHACTZ,EAAW,yBAA2B,yCACxC,GAGA,SAAA/pB,EAAAA,IAAC,OAAA,CAAK,UAAU,qDAAA,CAAsD,CAAA,CAAA,EAExEA,EAAAA,IAAC,MAAA,CAAI,UAAU,yDAA0D,SAAAqpB,CAAA,CAAM,CAAA,CAAA,CAAA,CAGrF,ECpGMuB,GAAyB7mB,EAAAA,KAAK,IAClC,QAAA,QAAA,EAAA,KAAA,IAAA8mB,EAAA,EAAmC,SAAW,CAAE,QAASvtB,EAAE,oBAAqB,CAClF,EAkBMwtB,GAAe3f,GAAiB,CACpC,MAAMnQ,EAAKiQ,GAAY,CAAU,KAAAE,EAAe,KAAM,EAAA,CAAI,EAC1D,OAAInQ,IAAO,QAAgB+vB,EAAAA,UACvB/vB,IAAO,QAAUA,IAAO,YAAcA,IAAO,QAAUA,IAAO,OAASA,IAAO,OAASA,IAAO,WACzFmQ,EAAK,SAAS,KAAK,GAAKA,EAAK,SAAS,WAAW,EAAI6f,EAAAA,SAAWC,EAAAA,SAElEC,EAAAA,IACT,EAuBMC,GAAoC,CAAC,CACzC,KAAAtF,EACA,MAAAzH,EACA,aAAAgN,EACA,SAAA1E,EACA,SAAA2E,EACA,SAAAC,EACA,QAAAC,EACA,QAAAC,CACF,IAAM,OACJ,MAAMrd,EAASuY,EAAS,IAAIb,EAAK,IAAI,EAC/B4F,EAAaL,IAAiBvF,EAAK,KACnCsC,EAAM,CAAE,YAAa,GAAG/J,EAAQ,GAAK,EAAE,IAAA,EACvCsN,EAAenxB,GAAqC,CACxD,MAAMoX,EAAQpX,EAAE,cAA8B,sBAAA,EAC9CgxB,EAAQ1F,EAAK,MAAQ,IAAKlU,CAAI,CAChC,EAEA,GAAIkU,EAAK,MACP,OACExf,EAAAA,KAAAwH,WAAA,CACE,SAAA,CAAAxH,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMglB,EAASxF,EAAK,IAAI,EACjC,aAAc6F,EACd,aAAcF,EACd,UAAU,8IACV,MAAOrD,EAEP,SAAA,CAAAnoB,EAAAA,IAACyB,EAAAA,aAAA,CACC,UAAW,kEACT0M,EAAS,gBAAkB,EAC7B,EAAA,CAAA,EAEDA,QACEwd,aAAA,CAAW,UAAU,0DAA0D,EAEhF3rB,EAAAA,IAAC4rB,EAAAA,OAAA,CAAO,UAAU,yDAAA,CAA0D,QAE7E,OAAA,CAAK,UAAU,sCAAuC,SAAA/F,EAAK,MAAQ,GAAA,CAAI,CAAA,CAAA,CAAA,EAEzE1X,KACC5M,EAAAskB,EAAK,WAAL,YAAAtkB,EAAe,IAAKqT,GAClB5U,EAAAA,IAACmrB,GAAA,CAEC,KAAMvW,EACN,MAAOwJ,EAAQ,EACf,aAAAgN,EACA,SAAA1E,EACA,SAAA2E,EACA,SAAAC,EACA,QAAAC,EACA,QAAAC,CAAA,EARK5W,EAAM,IAAA,GAUd,EACL,EAIJ,MAAMiX,EAAOf,GAAYjF,EAAK,IAAI,EAElC,OACExf,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMilB,EAASzF,CAAI,EAC5B,aAAc6F,EACd,aAAcF,EACd,UAAW,kGACTC,EAAa,uCAAyC,8CACxD,GACA,MAAOtD,EAEP,SAAA,CAAAnoB,EAAAA,IAAC,OAAA,CAAK,UAAU,uCAAA,CAAwC,EACxDA,EAAAA,IAAC6rB,EAAA,CAAK,UAAU,wDAAA,CAAyD,EACzE7rB,EAAAA,IAAC,OAAA,CAAK,UAAU,sCAAuC,WAAK,KAAK,QAChE,OAAA,CAAK,UAAU,8DACb,SAAA+B,GAAe8jB,EAAK,IAAI,CAAA,CAC3B,CAAA,CAAA,CAAA,CAGN,EAIahgB,GAA0C,CAAC,CAAE,IAAAtD,EAAK,aAAAupB,EAAe,EAAG,cAAAC,KAAoB,OACnG,MAAMrxB,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACipB,EAAKC,CAAM,EAAI3oB,EAAAA,SAAuB,IAAI,EAC3C,CAAC4oB,EAAMC,CAAO,EAAI7oB,EAAAA,SAA6B,IAAI,EACnD,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD,CAACojB,EAAUC,CAAW,EAAIrjB,EAAAA,aAA0B,IAAI,CAAC,EAAE,CAAC,CAAC,EAC7D,CAAC8oB,EAAUC,CAAW,EAAI/oB,EAAAA,SAAiC,IAAI,EAC/D,CAACgpB,EAAgBC,CAAiB,EAAIjpB,EAAAA,SAAS,EAAK,EACpD,CAACkpB,EAAcC,CAAe,EAAInpB,EAAAA,SAAwB,IAAI,EAC9D,CAACopB,EAAUC,CAAW,EAAIrpB,EAAAA,SAA+B,IAAI,EAC7DspB,EAAmBppB,EAAAA,OAAOuoB,CAAa,EAE7CtoB,EAAAA,UAAU,IAAM,CACdmpB,EAAiB,QAAUb,CAC7B,EAAG,CAACA,CAAa,CAAC,EAElBtoB,EAAAA,UAAU,IAAM,CACd,IAAIC,EAAY,GA0BhB,OAzBa,SAAY,CACvB,GAAI,CACFwQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb,MAAMmP,EAAM,MAAM/b,EAAQX,CAAG,EAC7B,GAAI,CAAC0c,EAAI,GAAI,MAAM,IAAI,MAAM,MAAM,EACnC,MAAM4N,EAAM,MAAM5N,EAAI,YAAA,EAChB/iB,EAAI,MAAM4wB,GAAQD,CAAG,EAC3B,GAAInpB,EAAW,OACf,MAAMqpB,EAAUC,GAAe9wB,CAAC,EAC1B+wB,EAAOC,GAAaH,CAAO,EACjCd,EAAO/vB,CAAC,EACRiwB,EAAQc,CAAI,EACZ,MAAMzqB,EAAO,IAAI,IAAY,CAAC,EAAE,CAAC,EACjC,GAAIyqB,EAAK,SACP,UAAW1xB,KAAK0xB,EAAK,SAAc1xB,EAAE,OAAOiH,EAAK,IAAIjH,EAAE,IAAI,EAE7DorB,EAAYnkB,CAAI,CAClB,OAASqB,EAAK,CACZ,QAAQ,MAAMA,CAAG,EACZH,GAAWoM,EAASpV,EAAE,iBAAiB,CAAC,CAC/C,QAAA,CACOgJ,GAAWwQ,EAAW,EAAK,CAClC,CACF,GACA,EACO,IAAM,CACXxQ,EAAY,EACd,CACF,EAAG,CAACnB,CAAG,CAAC,EAGRkB,EAAAA,UAAU,IACD,IAAM,CACP2oB,GAAA,MAAAA,EAAU,SAAS,IAAI,gBAAgBA,EAAS,OAAO,CAC7D,EACC,CAACA,CAAQ,CAAC,EAEb,MAAMe,EAAartB,EAAAA,QAAgC,IAAM,CACvD,GAAI,CAACosB,EAAM,OAAO,KAClB,IAAIrlB,EAAQ,EACRumB,EAAO,EACP9S,EAAO,EACX,MAAM+S,EAAQ7yB,GAAmB,OAC3BA,EAAE,OACAA,EAAE,MAAM4yB,KACZ7rB,EAAA/G,EAAE,WAAF,MAAA+G,EAAY,QAAQ8rB,KAEpBxmB,IACAyT,GAAQ9f,EAAE,KAEd,EACA,OAAA6yB,EAAKnB,CAAI,EACF,CAAE,MAAArlB,EAAO,KAAAumB,EAAM,KAAA9S,CAAA,CACxB,EAAG,CAAC4R,CAAI,CAAC,EAGTzoB,EAAAA,UAAU,IAAM,OACd,OAAAlC,EAAAqrB,EAAiB,UAAjB,MAAArrB,EAAA,KAAAqrB,EAA2BO,GACpB,IAAM,QACX5rB,EAAAqrB,EAAiB,UAAjB,MAAArrB,EAAA,KAAAqrB,EAA2B,KAC7B,CACF,EAAG,CAACO,CAAU,CAAC,EAEf,MAAMG,EAAe7iB,cAAa8iB,GAAiB,CACjD5G,EAAa7a,GAAS,CACpB,MAAMkW,EAAO,IAAI,IAAIlW,CAAI,EACzB,OAAIkW,EAAK,IAAIuL,CAAI,EAAGvL,EAAK,OAAOuL,CAAI,EAC/BvL,EAAK,IAAIuL,CAAI,EACXvL,CACT,CAAC,CACH,EAAG,CAAA,CAAE,EAECwL,EAAc/iB,EAAAA,YAAY,CAAC2X,EAAczQ,IAAkB,CAC/Dgb,EAAY,CACV,KAAAvK,EACA,EAAGzQ,EAAK,MAAQ,EAChB,EAAGA,EAAK,IAAMA,EAAK,OAAS,CAAA,CAC7B,CACH,EAAG,CAAA,CAAE,EAEC8b,EAAchjB,EAAAA,YAAY,IAAM,CACpCkiB,EAAY,IAAI,CAClB,EAAG,CAAA,CAAE,EAECe,EAAejjB,EAAAA,YACnB,MAAOob,GAAsB,CAC3B,GAAI,GAACmG,GAAOnG,EAAK,OACjB,CAAIuG,GAAA,MAAAA,EAAU,SAAS,IAAI,gBAAgBA,EAAS,OAAO,EAC3DG,EAAkB,EAAI,EACtBE,EAAgB,IAAI,EAEpB,GAAI,CACF,MAAMkB,EAAOC,GAAc/H,EAAK,IAAI,EAC9B3G,EAAO,MAAM2O,GAAiB7B,EAAKnG,EAAK,KAAM8H,IAAS,2BAA6BA,EAAO,MAAS,EACpG/pB,EAAU,IAAI,gBAAgBsb,CAAI,EACxCmN,EAAY,CAAE,KAAMxG,EAAK,KAAM,KAAMA,EAAK,KAAM,KAAMA,EAAK,KAAM,QAAAjiB,CAAA,CAAS,CAC5E,OAASC,EAAK,CACZ,QAAQ,MAAMA,CAAG,EACjB4oB,EAAgB,QAAQ,CAC1B,QAAA,CACEF,EAAkB,EAAK,CACzB,EACF,EACA,CAACP,EAAKI,CAAQ,CAAA,EAGhB,GAAInY,EACF,OACEjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIJ,GAAI6P,GAAS,CAACqc,EACZ,aACG,MAAA,CAAI,UAAU,qEACb,SAAAlsB,EAAAA,IAAC,OAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,GAASnV,EAAE,kBAAkB,EAAE,EAC7D,CAAA,CACF,EAKJ,MAAMozB,QACH,MAAA,CAAI,UAAU,0CACZ,UAAAvsB,EAAA2qB,EAAK,WAAL,YAAA3qB,EAAe,IAAKqT,GACnB5U,EAAAA,IAACmrB,GAAA,CAEC,KAAMvW,EACN,MAAO,EACP,cAAcwX,GAAA,YAAAA,EAAU,OAAQ,KAChC,SAAA1F,EACA,SAAU4G,EACV,SAAUI,EACV,QAASF,EACT,QAASC,CAAA,EARJ7Y,EAAM,IAAA,GAWjB,EAIImZ,EACJ1nB,EAAAA,KAAC,MAAA,CAAI,UAAU,8CACZ,SAAA,CAAA,CAAC+lB,GACApsB,EAAAA,IAAC,MAAA,CAAI,UAAU,gGAAgG,SAAA,eAE/G,EAEDosB,GAAYE,GACXtsB,EAAAA,IAAC,MAAA,CAAI,UAAU,0DACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,iHAAA,CAAkH,CAAA,CACnI,EAEDosB,GAAY,CAACE,GAAkBE,SAC7B,MAAA,CAAI,UAAU,gFACZ,SAAAA,EACH,EAEDJ,GAAY,CAACE,GAAkB,CAACE,GAC/BxsB,EAAAA,IAAA6N,EAAAA,SAAA,CACE,SAAA7N,EAAAA,IAAC,MAAA,CAAI,UAAU,2EACb,SAAAA,EAAAA,IAAC4N,EAAAA,SAAA,CACC,eACG,MAAA,CAAI,UAAU,0DACb,SAAA5N,EAAAA,IAAC,MAAA,CAAI,UAAU,iHAAA,CAAkH,CAAA,CACnI,EAGF,SAAAA,EAAAA,IAAC4qB,GAAA,CACC,KAAK,QACL,MAAO,CAAC,CAAE,KAAMwB,EAAS,KAAM,IAAKA,EAAS,QAAS,KAAMwB,GAAcxB,EAAS,IAAI,EAAG,EAC1F,aAAc,EACd,gBAAiBN,EAAe,CAAA,CAAA,CAClC,CAAA,EAEJ,CAAA,CACF,CAAA,EAEJ,EAGF,OACEzlB,EAAAA,KAAAwH,WAAA,CACE,SAAA,CAAA7N,EAAAA,IAACmpB,GAAA,CACC,KAAM2E,EACN,MAAOC,EACP,iBAAkB,IAClB,aAAc,IACd,aAAc,IACd,WAAW,oBAAA,CAAA,EAGZrB,GACC,OAAO,SAAa,KACpBje,GAAAA,aACEzO,EAAAA,IAAC,MAAA,CACC,UAAU,6KACV,MAAO,CACL,KAAM,GAAG0sB,EAAS,CAAC,KACnB,IAAK,GAAGA,EAAS,CAAC,KAClB,UAAW,kBAAA,EAGZ,SAAAA,EAAS,IAAA,CAAA,EAEZ,SAAS,IAAA,CACX,EACJ,CAEJ,+GC/Xa3mB,GAA4C,CAAC,CACxD,IAAAxD,EACA,SAAA2D,EACA,SAAA8nB,EAAW,GACX,YAAAC,EAAc,EAChB,IAAM,CACJ,MAAMvzB,EAAIyF,EAAA,EACJ+C,EAAUH,GAAA,EACV,CAACqiB,EAASC,CAAU,EAAI/hB,EAAAA,SAAiB,EAAE,EAC3C,CAAC2Q,EAASC,CAAU,EAAI5Q,EAAAA,SAAS,EAAI,EACrC,CAACuM,EAAOC,CAAQ,EAAIxM,EAAAA,SAAwB,IAAI,EAChD4qB,EAAWC,GAAwBjoB,CAAQ,EAC3C,CAAE,KAAMoiB,CAAA,EAAgBlE,GAC5B8J,IAAa,OAAS9I,EAAU,GAChC8I,CAAA,EAqBF,OAlBAzqB,EAAAA,UAAU,IAAM,EACG,SAAY,CAC3B,GAAI,CACFyQ,EAAW,EAAI,EACfpE,EAAS,IAAI,EACb,MAAMsS,EAAO,MAAMmD,GAAchjB,EAAK,CAAE,QAAAW,EAAS,EACjDmiB,EAAWjD,CAAI,CACjB,OAASve,EAAK,CACZiM,EAASpV,EAAE,kBAAkB,CAAC,EAC9B,QAAQ,MAAMmJ,CAAG,CACnB,QAAA,CACEqQ,EAAW,EAAK,CAClB,CACF,GAEA,CACF,EAAG,CAAC3R,CAAG,CAAC,EAEJ0R,EAEAjU,MAAC,OAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,oHAAoH,CAAA,CACrI,EAIA6P,EAEA7P,EAAAA,IAAC,MAAA,CAAI,UAAU,qEACb,eAAC,MAAA,CAAI,UAAU,wCACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,UAAU,cAAe,SAAA6P,CAAA,CAAM,EACpC,EACF,EAKAoe,GAAgBC,IAAa,OAE7BluB,EAAAA,IAAC,MAAA,CAAI,UAAU,+CACb,SAAAA,EAAAA,IAAC,SAAA,CACC,OAAQolB,EACR,QAAQ,oBACR,UAAU,qCACV,MAAOlf,CAAA,CAAA,EAEX,QAMD,MAAA,CAAI,UAAU,yDACZ,SAAAgoB,IAAa,QAAU,CAAC5F,EACvBtoB,EAAAA,IAAC,MAAA,CACC,UAAW,yDACTguB,EAAW,0CAA4C,oBACzD,GAEC,SAAA5I,CAAA,CAAA,EAGHplB,EAAAA,IAAC,MAAA,CACC,UAAW,uCAAuCguB,EAAW,GAAK,SAAS,GAC3E,wBAAyB,CAAE,OAAQ1F,CAAA,CAAY,CAAA,EAGrD,CAEJ"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../file-preview-core/lib/index.mjs","../src/i18n/LocaleContext.tsx","../src/ThemeContext.tsx","../src/renderers/Image/toolbar.tsx","../src/renderers/Pdf/toolbar.tsx","../src/renderers/Epub/toolbar.tsx","../src/renderers/Mobi/toolbar.tsx","../src/renderers/Zip/toolbar.tsx","../src/renderers/Text/toolbar.tsx","../src/renderers/Markdown/toolbar.tsx","../src/RequestContext.tsx","../src/renderers/lazy.tsx","../src/renderers/Unsupported/index.tsx","../src/renderers/RendererLoading.tsx","../src/FilePreviewContent.tsx","../src/FilePreviewModal.tsx","../src/FilePreviewEmbed.tsx","../src/utils/pdfConfig.ts","../src/index.ts","../src/renderers/Image/index.tsx","../src/renderers/Pdf/index.tsx","../src/renderers/Docx/index.tsx","../src/renderers/Xlsx/index.tsx","../src/renderers/Pptx/index.tsx","../src/renderers/Msg/index.tsx","../src/renderers/Epub/index.tsx","../src/renderers/Mobi/index.tsx","../src/renderers/Video/index.tsx","../src/hooks/useAudioPlayer.ts","../src/renderers/Audio/index.tsx","../src/hooks/useShikiHighlight.ts","../src/renderers/Markdown/index.tsx","../src/renderers/Json/index.tsx","../src/renderers/Csv/index.tsx","../src/renderers/Xml/index.tsx","../src/renderers/Subtitle/index.tsx","../src/components/ResizableSplit.tsx","../src/renderers/Zip/index.tsx","../src/renderers/Text/index.tsx","../src/renderers/Font/index.tsx"],"sourcesContent":["import j from \"jszip\";\nconst dt = [\n \"image\",\n \"pdf\",\n \"docx\",\n \"xlsx\",\n \"pptx\",\n \"msg\",\n \"epub\",\n \"mobi\",\n \"video\",\n \"audio\",\n \"markdown\",\n \"json\",\n \"csv\",\n \"xml\",\n \"subtitle\",\n \"zip\",\n \"text\",\n \"font\"\n];\nfunction U(e) {\n try {\n const n = new URL(e).pathname.split(\"/\").pop() || \"file\";\n return decodeURIComponent(n);\n } catch {\n const t = e.split(\"/\").pop() || \"file\";\n return decodeURIComponent(t);\n }\n}\nfunction k(e) {\n var n;\n const t = ((n = e.split(\".\").pop()) == null ? void 0 : n.toLowerCase()) || \"\";\n return {\n // 图片\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n // 视频\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n ogg: \"video/ogg\",\n ogv: \"video/ogg\",\n mov: \"video/quicktime\",\n avi: \"video/x-msvideo\",\n mkv: \"video/x-matroska\",\n m4v: \"video/x-m4v\",\n \"3gp\": \"video/3gpp\",\n flv: \"video/x-flv\",\n // 音频\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n m4a: \"audio/mp4\",\n aac: \"audio/aac\",\n flac: \"audio/flac\",\n // 文档\n pdf: \"application/pdf\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n ppt: \"application/vnd.ms-powerpoint\",\n msg: \"application/vnd.ms-outlook\",\n mobi: \"application/x-mobipocket-ebook\",\n azw: \"application/vnd.amazon.ebook\",\n azw3: \"application/vnd.amazon.ebook\",\n kf8: \"application/vnd.amazon.ebook\",\n // 文本\n txt: \"text/plain\",\n md: \"text/markdown\",\n markdown: \"text/markdown\",\n json: \"application/json\",\n xml: \"application/xml\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"text/javascript\",\n ts: \"text/typescript\",\n jsx: \"text/javascript\",\n tsx: \"text/typescript\",\n py: \"text/x-python\",\n java: \"text/x-java\",\n cpp: \"text/x-c++src\",\n c: \"text/x-csrc\",\n cs: \"text/x-csharp\",\n php: \"text/x-php\",\n rb: \"text/x-ruby\",\n go: \"text/x-go\",\n rs: \"text/x-rust\",\n yaml: \"text/yaml\",\n yml: \"text/yaml\",\n toml: \"text/toml\",\n ini: \"text/plain\",\n env: \"text/plain\",\n diff: \"text/x-diff\",\n patch: \"text/x-diff\",\n log: \"text/plain\",\n csv: \"text/csv\",\n tsv: \"text/tab-separated-values\",\n srt: \"application/x-subrip\",\n vtt: \"text/vtt\",\n zip: \"application/zip\"\n }[t] || \"application/octet-stream\";\n}\nfunction A(e, t = 0) {\n if (e instanceof File)\n return {\n id: `file-${Date.now()}-${t}`,\n name: e.name,\n url: URL.createObjectURL(e),\n type: e.type || k(e.name),\n size: e.size\n };\n if (typeof e == \"string\") {\n const o = U(e);\n return {\n id: `url-${Date.now()}-${t}`,\n name: o,\n url: e,\n type: k(o)\n };\n }\n return {\n id: e.id || `link-${Date.now()}-${t}`,\n name: e.name,\n url: e.url,\n type: e.type || k(e.name),\n size: e.size\n };\n}\nfunction ft(e) {\n return e.map((t, o) => A(t, o));\n}\nfunction ut(e) {\n var r;\n const t = ((r = e.name.split(\".\").pop()) == null ? void 0 : r.toLowerCase()) || \"\", o = e.type.toLowerCase();\n if (o.startsWith(\"image/\") || [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"svg\"].includes(t))\n return \"image\";\n if (o.includes(\"pdf\") || t === \"pdf\")\n return \"pdf\";\n if (o.includes(\"wordprocessingml\") || t === \"docx\")\n return \"docx\";\n if (o.includes(\"spreadsheetml\") || t === \"xlsx\")\n return \"xlsx\";\n if (o.includes(\"presentationml\") || t === \"pptx\" || t === \"ppt\")\n return \"pptx\";\n if (o.includes(\"ms-outlook\") || t === \"msg\")\n return \"msg\";\n if (o.includes(\"epub\") || t === \"epub\")\n return \"epub\";\n if ([\"mobi\", \"azw\", \"azw3\", \"kf8\"].includes(t) || o === \"application/x-mobipocket-ebook\" || o === \"application/vnd.amazon.ebook\")\n return \"mobi\";\n if ([\"csv\", \"tsv\"].includes(t) || o === \"text/csv\" || o === \"text/tab-separated-values\")\n return \"csv\";\n if (t === \"xml\" || o === \"application/xml\" || o === \"text/xml\")\n return \"xml\";\n if ([\"srt\", \"vtt\", \"lrc\", \"elrc\", \"ass\", \"ssa\", \"ttml\", \"dfxp\"].includes(t) || o === \"text/vtt\" || o === \"application/x-subrip\" || o === \"application/ttml+xml\")\n return \"subtitle\";\n if (t === \"zip\" || o === \"application/zip\" || o === \"application/x-zip-compressed\")\n return \"zip\";\n if ([\"ttf\", \"otf\", \"woff\", \"woff2\"].includes(t) || o.startsWith(\"font/\") || o === \"application/font-woff\" || o === \"application/font-woff2\" || o === \"application/x-font-ttf\" || o === \"application/x-font-otf\" || o === \"application/font-sfnt\")\n return \"font\";\n if (o.startsWith(\"video/\") || [\"mp4\", \"webm\", \"ogg\", \"ogv\", \"mov\", \"avi\", \"mkv\", \"m4v\", \"3gp\", \"flv\"].includes(t))\n return \"video\";\n if (o.startsWith(\"audio/\") || [\"mp3\", \"wav\", \"ogg\", \"m4a\", \"flac\", \"aac\"].includes(t))\n return \"audio\";\n if (t === \"md\" || t === \"markdown\")\n return \"markdown\";\n if (o === \"application/json\" || t === \"json\")\n return \"json\";\n const n = [\n \"txt\",\n \"log\",\n \"lock\",\n \"js\",\n \"jsx\",\n \"ts\",\n \"tsx\",\n \"py\",\n \"java\",\n \"cpp\",\n \"c\",\n \"h\",\n \"cs\",\n \"php\",\n \"rb\",\n \"go\",\n \"mod\",\n \"rs\",\n \"swift\",\n \"kt\",\n \"lua\",\n \"vim\",\n \"html\",\n \"css\",\n \"scss\",\n \"sass\",\n \"less\",\n \"yaml\",\n \"yml\",\n \"toml\",\n \"ini\",\n \"conf\",\n \"env\",\n \"diff\",\n \"patch\",\n \"sh\",\n \"bash\",\n \"zsh\",\n \"sql\"\n ];\n return o.startsWith(\"text/\") || n.includes(t) ? \"text\" : \"unsupported\";\n}\nfunction pt(e) {\n var n;\n const t = ((n = e.split(\".\").pop()) == null ? void 0 : n.toLowerCase()) || \"\";\n return {\n js: \"javascript\",\n jsx: \"jsx\",\n ts: \"typescript\",\n tsx: \"tsx\",\n py: \"python\",\n java: \"java\",\n cpp: \"cpp\",\n c: \"c\",\n cs: \"csharp\",\n php: \"php\",\n rb: \"ruby\",\n go: \"go\",\n mod: \"go\",\n rs: \"rust\",\n swift: \"swift\",\n kt: \"kotlin\",\n lua: \"lua\",\n vim: \"vim\",\n scala: \"scala\",\n sh: \"bash\",\n bash: \"bash\",\n zsh: \"bash\",\n json: \"json\",\n xml: \"xml\",\n html: \"html\",\n css: \"css\",\n scss: \"scss\",\n sass: \"sass\",\n less: \"less\",\n sql: \"sql\",\n yaml: \"yaml\",\n yml: \"yaml\",\n toml: \"toml\",\n ini: \"ini\",\n env: \"bash\",\n conf: \"nginx\",\n diff: \"diff\",\n patch: \"diff\",\n log: \"log\",\n md: \"markdown\",\n txt: \"text\"\n }[t] || \"text\";\n}\nfunction mt(e) {\n var n;\n const t = ((n = e.split(\".\").pop()) == null ? void 0 : n.toLowerCase().split(\"?\")[0]) || \"\";\n return {\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n ogg: \"video/ogg\",\n ogv: \"video/ogg\",\n mov: \"video/quicktime\",\n avi: \"video/x-msvideo\",\n mkv: \"video/x-matroska\",\n m4v: \"video/mp4\",\n \"3gp\": \"video/3gpp\",\n flv: \"video/x-flv\"\n }[t] || \"video/mp4\";\n}\nfunction ht(e) {\n return e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} KB` : `${(e / (1024 * 1024)).toFixed(1)} MB`;\n}\nfunction gt(e) {\n if (!isFinite(e) || isNaN(e) || e < 0) return \"0:00\";\n const t = Math.floor(e / 60), o = Math.floor(e % 60);\n return `${t}:${o.toString().padStart(2, \"0\")}`;\n}\nfunction xt(e) {\n var o;\n return (((o = e.split(\".\").pop()) == null ? void 0 : o.toLowerCase()) || \"\") === \"tsv\" ? \"\t\" : \",\";\n}\nfunction bt(e, t = {}) {\n const o = t.delimiter ?? \",\", n = t.firstRowAsHeader ?? !0, r = [];\n let a = [], i = \"\", l = !1, s = 0;\n const c = e.length;\n for (; s < c; ) {\n const u = e[s];\n if (l) {\n if (u === '\"') {\n if (e[s + 1] === '\"') {\n i += '\"', s += 2;\n continue;\n }\n l = !1, s += 1;\n continue;\n }\n i += u, s += 1;\n continue;\n }\n if (u === '\"') {\n l = !0, s += 1;\n continue;\n }\n if (u === o) {\n a.push(i), i = \"\", s += 1;\n continue;\n }\n if (u === \"\\r\") {\n e[s + 1] === `\n` && (s += 1), a.push(i), r.push(a), a = [], i = \"\", s += 1;\n continue;\n }\n if (u === `\n`) {\n a.push(i), r.push(a), a = [], i = \"\", s += 1;\n continue;\n }\n i += u, s += 1;\n }\n for ((i.length > 0 || a.length > 0) && (a.push(i), r.push(a)); r.length > 0; ) {\n const u = r[r.length - 1];\n if (u.length === 1 && u[0] === \"\")\n r.pop();\n else\n break;\n }\n let d = [], p = r;\n n && r.length > 0 && (d = r[0], p = r.slice(1));\n const f = Math.max(\n d.length,\n ...p.map((u) => u.length),\n 0\n );\n for (const u of p)\n for (; u.length < f; ) u.push(\"\");\n return {\n header: d,\n rows: p,\n columnCount: f,\n delimiter: o\n };\n}\nfunction $(e) {\n const t = e instanceof Uint8Array ? e : new Uint8Array(e);\n if (t.length >= 3 && t[0] === 239 && t[1] === 187 && t[2] === 191)\n return new TextDecoder(\"utf-8\").decode(t);\n if (t.length >= 2 && t[0] === 255 && t[1] === 254)\n return new TextDecoder(\"utf-16le\").decode(t);\n if (t.length >= 2 && t[0] === 254 && t[1] === 255)\n return new TextDecoder(\"utf-16be\").decode(t);\n try {\n return new TextDecoder(\"utf-8\", { fatal: !0 }).decode(t);\n } catch {\n }\n try {\n return new TextDecoder(\"gbk\").decode(t);\n } catch {\n }\n return new TextDecoder(\"utf-8\", { fatal: !1 }).decode(t);\n}\nconst I = $;\nasync function Ft(e, t) {\n const o = !!t && (\"fetcher\" in t || \"init\" in t), n = o ? t.fetcher ?? fetch : fetch, r = o ? t.init : t, a = await n(e, r);\n if (!a.ok) throw new Error(`请求失败: ${a.status}`);\n const i = await a.arrayBuffer();\n return $(i);\n}\nasync function B(e, t) {\n if (e)\n return typeof e == \"function\" ? await e(t) : e;\n}\nfunction W(e, t) {\n if (!e && !t) return;\n if (!e) return t;\n if (!t) return e;\n const o = new Headers(e.headers || {});\n return t.headers && new Headers(t.headers).forEach((n, r) => {\n o.set(r, n);\n }), {\n ...e,\n ...t,\n headers: o\n };\n}\nfunction wt(e) {\n const t = (e == null ? void 0 : e.requestHandler) ?? ((n, r) => fetch(n, r)), o = e == null ? void 0 : e.requestInit;\n return async (n, r) => {\n const a = await B(o, n), i = W(a, r);\n return t(n, i);\n };\n}\nasync function vt(e, t = fetch, o) {\n const n = await t(e, o);\n if (!n.ok) throw new Error(`请求失败: ${n.status}`);\n const r = await n.blob();\n return URL.createObjectURL(r);\n}\nasync function yt(e, t, o = fetch, n) {\n const r = await o(e, n);\n if (!r.ok) throw new Error(`请求失败: ${r.status}`);\n const a = await r.blob(), i = URL.createObjectURL(a);\n try {\n const l = document.createElement(\"a\");\n l.href = i, l.download = t, l.style.display = \"none\", document.body.appendChild(l), l.click(), document.body.removeChild(l);\n } finally {\n setTimeout(() => URL.revokeObjectURL(i), 1e3);\n }\n}\nfunction E(e) {\n const t = e.trim().replace(\",\", \".\"), o = t.split(\":\").map((n) => n.trim());\n if (o.length === 3) {\n const [n, r, a] = o;\n return Number(n) * 3600 + Number(r) * 60 + Number(a);\n }\n if (o.length === 2) {\n const [n, r] = o;\n return Number(n) * 60 + Number(r);\n }\n return Number(t) || 0;\n}\nfunction _t(e) {\n if (!isFinite(e) || e < 0) return \"00:00:00.000\";\n const t = Math.floor(e * 1e3), o = t % 1e3, n = Math.floor(t / 1e3) % 60, r = Math.floor(t / 6e4) % 60, a = Math.floor(t / 36e5), i = (l, s = 2) => l.toString().padStart(s, \"0\");\n return `${i(a)}:${i(r)}:${i(n)}.${i(o, 3)}`;\n}\nconst z = /(\\d{1,2}:)?\\d{1,2}:\\d{1,2}[.,]\\d{1,3}\\s*-->\\s*(\\d{1,2}:)?\\d{1,2}:\\d{1,2}[.,]\\d{1,3}/, Z = /^\\s*\\[\\d{1,2}:\\d{1,2}(?:[.:]\\d{1,3})?\\]/;\nfunction V(e) {\n const t = e.replace(/^\\uFEFF/, \"\").trimStart();\n return /^WEBVTT/.test(t) ? \"vtt\" : /^<\\?xml/i.test(t) || /<tt\\b[^>]*>/i.test(t) ? \"ttml\" : /^\\[Script Info\\]/im.test(t) || /^Dialogue:/m.test(t) ? /ScriptType:\\s*v4\\.00\\s*$/im.test(t) ? \"ssa\" : \"ass\" : Z.test(t) || /^\\[(ti|ar|al|au|by|length|offset|re|ve):/im.test(t) ? /<\\d{1,2}:\\d{1,2}(?:[.:]\\d{1,3})?>/.test(t) ? \"elrc\" : \"lrc\" : \"srt\";\n}\nfunction L(e, t) {\n const n = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`), r = [];\n let a, i = 0;\n if (t === \"vtt\") {\n const l = [];\n for (; i < n.length && n[i].trim() !== \"\"; )\n l.push(n[i]), i++;\n for (a = l.join(`\n`); i < n.length && n[i].trim() === \"\"; ) i++;\n }\n for (; i < n.length; ) {\n for (; i < n.length && n[i].trim() === \"\"; ) i++;\n if (i >= n.length) break;\n let l, s = null;\n if (z.test(n[i]))\n s = n[i], i++;\n else if (l = n[i].trim() || void 0, i++, i < n.length && z.test(n[i]))\n s = n[i], i++;\n else\n continue;\n if (!s) continue;\n const c = s.match(/([\\d:.,]+)\\s*-->\\s*([\\d:.,]+)/);\n if (!c) continue;\n const d = E(c[1]), p = E(c[2]), f = [];\n for (; i < n.length && n[i].trim() !== \"\"; )\n f.push(n[i]), i++;\n r.push({ id: l, start: d, end: p, text: f.join(`\n`) });\n }\n return { format: t, cues: r, header: a };\n}\nfunction T(e, t, o) {\n const n = Number(e), r = Number(t);\n let a = 0;\n if (o) {\n const i = (o + \"000\").slice(0, 3);\n a = Number(i);\n }\n return n * 60 + r + a / 1e3;\n}\nfunction R(e, t) {\n const o = /^\\[(ti|ar|al|au|by|length|offset|re|ve):(.*)\\]$/i.exec(e.trim());\n if (!o) return !1;\n const n = o[1].toLowerCase(), r = o[2].trim();\n if (t.metadata[n] = r, n === \"offset\") {\n const a = Number(r);\n isNaN(a) || (t.offsetMs = a);\n }\n return !0;\n}\nfunction O(e) {\n const o = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`), n = { metadata: {}, offsetMs: 0 }, r = /\\[(\\d{1,2}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g, a = [];\n for (const s of o) {\n const c = s.trim();\n if (!c || R(c, n)) continue;\n const d = [];\n let p = 0;\n r.lastIndex = 0;\n let f;\n for (; (f = r.exec(c)) !== null && f.index === p; )\n d.push(T(f[1], f[2], f[3])), p = f.index + f[0].length;\n if (d.length === 0) continue;\n const u = c.slice(p).trim();\n for (const m of d)\n a.push({ start: m, text: u });\n }\n a.sort((s, c) => s.start - c.start);\n const i = n.offsetMs / 1e3;\n return { format: \"lrc\", cues: a.map((s, c) => {\n const d = Math.max(0, s.start - i), p = a[c + 1], f = p ? Math.max(d, p.start - i) : d + 5;\n return { start: d, end: f, text: s.text };\n }), metadata: n.metadata };\n}\nfunction q(e) {\n const o = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`), n = { metadata: {}, offsetMs: 0 }, r = /\\[(\\d{1,2}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g, a = /<(\\d{1,2}):(\\d{1,2})(?:[.:](\\d{1,3}))?>/g, i = [];\n for (const c of o) {\n const d = c.trim();\n if (!d || R(d, n)) continue;\n const p = [];\n let f = 0;\n r.lastIndex = 0;\n let u;\n for (; (u = r.exec(d)) !== null && u.index === f; )\n p.push(T(u[1], u[2], u[3])), f = u.index + u[0].length;\n if (p.length === 0) continue;\n const m = d.slice(f);\n for (const h of p)\n i.push({ start: h, raw: m });\n }\n i.sort((c, d) => c.start - d.start);\n const l = n.offsetMs / 1e3;\n return { format: \"elrc\", cues: i.map((c, d) => {\n const p = [];\n let f = \"\", u = 0, m = null;\n a.lastIndex = 0;\n let h;\n for (; (h = a.exec(c.raw)) !== null; ) {\n const F = c.raw.slice(u, h.index);\n m !== null && F && p.push({ start: Math.max(0, m - l), text: F }), f += F, m = T(h[1], h[2], h[3]), u = h.index + h[0].length;\n }\n const b = c.raw.slice(u);\n m !== null && b && p.push({ start: Math.max(0, m - l), text: b }), f += b;\n const g = Math.max(0, c.start - l), x = i[d + 1], v = x ? Math.max(g, x.start - l) : g + 5;\n return {\n start: g,\n end: v,\n text: f.trim(),\n words: p.length ? p : void 0\n };\n }), metadata: n.metadata };\n}\nfunction D(e) {\n const t = e.trim().split(\":\");\n return t.length !== 3 ? 0 : Number(t[0]) * 3600 + Number(t[1]) * 60 + Number(t[2].replace(\",\", \".\"));\n}\nfunction N(e, t) {\n const n = e.replace(/\\r\\n?/g, `\n`).replace(/^\\uFEFF/, \"\").split(`\n`);\n let r = \"\", a = [];\n const i = [], l = [];\n for (const s of n) {\n const c = s.replace(/\\s+$/, \"\"), d = c.trim(), p = /^\\[([^\\]]+)\\]\\s*$/.exec(d);\n if (p) {\n r = p[1].toLowerCase(), l.push(c);\n continue;\n }\n if (r !== \"events\") {\n l.push(c);\n continue;\n }\n const f = /^Format:\\s*(.+)$/i.exec(d);\n if (f) {\n a = f[1].split(\",\").map((w) => w.trim());\n continue;\n }\n const u = /^(Dialogue|Comment):\\s*(.+)$/i.exec(d);\n if (!u || u[1].toLowerCase() === \"comment\" || a.length === 0) continue;\n const m = a.length, h = u[2].split(\",\"), b = h.slice(0, m - 1), g = h.slice(m - 1).join(\",\"), x = {};\n a.forEach((w, y) => {\n x[w] = y === m - 1 ? g : b[y] ?? \"\";\n });\n const v = D(x.Start || \"\"), F = D(x.End || \"\"), _ = (x.Text || \"\").replace(/\\\\N/g, `\n`).replace(/\\\\n/g, `\n`).replace(/\\\\h/g, \" \").replace(/\\{[^}]*\\}/g, \"\");\n i.push({ start: v, end: F, text: _, style: x.Style });\n }\n return i.sort((s, c) => s.start - c.start), {\n format: t,\n cues: i,\n header: l.join(`\n`).trim() || void 0\n };\n}\nfunction S(e) {\n const t = e.trim();\n if (!t) return 0;\n const o = /^(\\d+(?:\\.\\d+)?)(h|m|s|ms|f|t)$/i.exec(t);\n if (o) {\n const r = Number(o[1]), a = o[2].toLowerCase();\n return a === \"h\" ? r * 3600 : a === \"m\" ? r * 60 : a === \"ms\" ? r / 1e3 : r;\n }\n const n = t.split(\":\");\n return n.length === 3 ? Number(n[0]) * 3600 + Number(n[1]) * 60 + Number(n[2]) : n.length === 2 ? Number(n[0]) * 60 + Number(n[1]) : Number(t) || 0;\n}\nfunction H(e) {\n if (typeof DOMParser > \"u\")\n throw new Error(\"TTML parsing requires a DOMParser environment\");\n const t = new DOMParser().parseFromString(e, \"application/xml\");\n if (t.getElementsByTagName(\"parsererror\").length > 0)\n throw new Error(\"TTML XML parse error\");\n const n = t.getElementsByTagName(\"p\"), r = [];\n for (let a = 0; a < n.length; a++) {\n const i = n[a], l = i.getAttribute(\"begin\") || \"\", s = i.getAttribute(\"end\") || \"\", c = i.getAttribute(\"dur\") || \"\", d = S(l);\n let p;\n s ? p = S(s) : c ? p = d + S(c) : p = d + 5;\n let f = \"\";\n i.childNodes.forEach((m) => {\n if (m.nodeType === 3)\n f += m.nodeValue || \"\";\n else if (m.nodeType === 1) {\n const h = m;\n h.tagName.toLowerCase() === \"br\" ? f += `\n` : f += h.textContent || \"\";\n }\n });\n const u = f.replace(/[ \\t]+/g, \" \").replace(/\\n /g, `\n`).trim();\n (u || d || p) && r.push({ start: d, end: p, text: u });\n }\n return r.sort((a, i) => a.start - i.start), { format: \"ttml\", cues: r };\n}\nfunction Ct(e, t) {\n switch (t ?? V(e)) {\n case \"lrc\":\n return O(e);\n case \"elrc\":\n return q(e);\n case \"ass\":\n return N(e, \"ass\");\n case \"ssa\":\n return N(e, \"ssa\");\n case \"ttml\":\n return H(e);\n case \"vtt\":\n return L(e, \"vtt\");\n case \"srt\":\n default:\n return L(e, \"srt\");\n }\n}\nasync function kt(e) {\n return j.loadAsync(e);\n}\nfunction St(e) {\n const t = [];\n return e.forEach((o, n) => {\n var p;\n const r = n.dir, a = r && !o.endsWith(\"/\") ? o + \"/\" : o, i = r ? a.replace(/\\/$/, \"\") : a, l = i.lastIndexOf(\"/\"), s = l >= 0 ? i.slice(l + 1) : i, c = l >= 0 ? i.slice(0, l) : \"\", d = r ? 0 : ((p = n._data) == null ? void 0 : p.uncompressedSize) ?? 0;\n t.push({\n path: a,\n name: s,\n dir: c,\n isDir: r,\n size: d,\n date: n.date\n });\n }), t;\n}\nfunction Tt(e) {\n const t = { name: \"\", path: \"\", isDir: !0, children: [], size: 0 }, o = /* @__PURE__ */ new Map();\n o.set(\"\", t);\n const n = (a) => {\n if (o.has(a)) return o.get(a);\n const i = a.split(\"/\").filter(Boolean);\n let l = t, s = \"\";\n for (const c of i) {\n s = s ? `${s}/${c}` : c;\n let d = o.get(s);\n d || (d = { name: c, path: s + \"/\", isDir: !0, children: [], size: 0 }, l.children.push(d), o.set(s, d)), l = d;\n }\n return l;\n };\n for (const a of e) {\n if (a.isDir) {\n n(a.path.replace(/\\/$/, \"\"));\n continue;\n }\n n(a.dir).children.push({\n name: a.name,\n path: a.path,\n isDir: !1,\n size: a.size\n });\n }\n const r = (a) => {\n if (a.children) {\n a.children.sort((i, l) => i.isDir !== l.isDir ? i.isDir ? -1 : 1 : i.name.localeCompare(l.name));\n for (const i of a.children) r(i);\n }\n };\n return r(t), t;\n}\nasync function Mt(e, t) {\n const o = e.file(t);\n if (!o) throw new Error(`ZIP entry not found: ${t}`);\n const n = await o.async(\"arraybuffer\");\n return I(n);\n}\nasync function Et(e, t, o) {\n const n = e.file(t);\n if (!n) throw new Error(`ZIP entry not found: ${t}`);\n const r = await n.async(\"arraybuffer\");\n return new Blob([r], o ? { type: o } : void 0);\n}\nfunction G(e) {\n return e ? e.startsWith(\"#\") ? e : e.length === 8 ? \"#\" + e.substring(2) : e.length === 6 ? \"#\" + e : \"#000000\" : \"#000000\";\n}\nconst J = [\n \"FFFFFF\",\n \"000000\",\n \"E7E6E6\",\n \"44546A\",\n \"4472C4\",\n \"ED7D31\",\n \"A5A5A5\",\n \"FFC000\",\n \"5B9BD5\",\n \"70AD47\"\n], X = [\n \"000000\",\n \"FFFFFF\",\n \"FF0000\",\n \"00FF00\",\n \"0000FF\",\n \"FFFF00\",\n \"FF00FF\",\n \"00FFFF\",\n \"000000\",\n \"FFFFFF\",\n \"FF0000\",\n \"00FF00\",\n \"0000FF\",\n \"FFFF00\",\n \"FF00FF\",\n \"00FFFF\",\n \"800000\",\n \"008000\",\n \"000080\",\n \"808000\",\n \"800080\",\n \"008080\",\n \"C0C0C0\",\n \"808080\",\n \"9999FF\",\n \"993366\",\n \"FFFFCC\",\n \"CCFFFF\",\n \"660066\",\n \"FF8080\",\n \"0066CC\",\n \"CCCCFF\",\n \"000080\",\n \"FF00FF\",\n \"FFFF00\",\n \"00FFFF\",\n \"800080\",\n \"800000\",\n \"008080\",\n \"0000FF\",\n \"00CCFF\",\n \"CCFFFF\",\n \"CCFFCC\",\n \"FFFF99\",\n \"99CCFF\",\n \"FF99CC\",\n \"CC99FF\",\n \"FFCC99\",\n \"3366FF\",\n \"33CCCC\",\n \"99CC00\",\n \"FFCC00\",\n \"FF9900\",\n \"FF6600\",\n \"666699\",\n \"969696\",\n \"003366\",\n \"339966\",\n \"003300\",\n \"333300\",\n \"993300\",\n \"993366\",\n \"333399\",\n \"333333\"\n];\nfunction K(e, t) {\n const o = parseInt(e.substring(0, 2), 16), n = parseInt(e.substring(2, 4), 16), r = parseInt(e.substring(4, 6), 16), a = (c) => t < 0 ? Math.round(c * (1 + t)) : Math.round(c + (255 - c) * t), i = Math.min(255, Math.max(0, a(o))), l = Math.min(255, Math.max(0, a(n))), s = Math.min(255, Math.max(0, a(r)));\n return i.toString(16).padStart(2, \"0\") + l.toString(16).padStart(2, \"0\") + s.toString(16).padStart(2, \"0\");\n}\nfunction Q(e) {\n if (e && e.type === \"pattern\" && e.pattern === \"solid\") {\n const t = e.fgColor;\n if (t)\n return M(t);\n }\n}\nfunction M(e) {\n if (e) {\n if (\"argb\" in e && typeof e.argb == \"string\" && e.argb)\n return G(e.argb);\n if (\"theme\" in e && typeof e.theme == \"number\") {\n const t = J[e.theme] || \"000000\", o = \"tint\" in e && typeof e.tint == \"number\" ? e.tint : 0;\n return \"#\" + (o !== 0 ? K(t, o) : t);\n }\n if (\"indexed\" in e && typeof e.indexed == \"number\") {\n const t = X[e.indexed];\n if (t) return \"#\" + t;\n }\n }\n}\nfunction Y(e) {\n if (!e || !e.style) return;\n const t = M(e.color) || \"#000000\";\n return [e.style, t];\n}\nfunction tt(e) {\n const t = {};\n let o = !1;\n if (e.font) {\n const r = e.font;\n if ((r.name || r.size || r.bold || r.italic) && (o = !0, t.font = {}, r.name && (t.font.name = r.name), r.size && (t.font.size = r.size), r.bold && (t.font.bold = !0), r.italic && (t.font.italic = !0)), r.color) {\n const a = M(r.color);\n a && (o = !0, t.color = a);\n }\n r.underline && (o = !0, t.underline = !0), r.strike && (o = !0, t.strike = !0);\n }\n const n = Q(e.fill);\n if (n && (o = !0, t.bgcolor = n), e.alignment) {\n const r = e.alignment;\n r.horizontal && (o = !0, t.align = r.horizontal), r.vertical && (o = !0, t.valign = r.vertical), r.wrapText && (o = !0, t.textwrap = !0);\n }\n if (e.border) {\n const r = {};\n let a = !1;\n const i = [\"top\", \"bottom\", \"left\", \"right\"];\n for (const l of i) {\n const s = Y(e.border[l]);\n s && (r[l] = s, a = !0);\n }\n a && (o = !0, t.border = r);\n }\n return o ? t : null;\n}\nfunction et(e) {\n return JSON.stringify(e);\n}\nfunction ot(e, t, o) {\n const n = tt(e);\n if (!n) return -1;\n const r = et(n), a = o.get(r);\n if (a !== void 0) return a;\n const i = t.length;\n return t.push(n), o.set(r, i), i;\n}\nfunction nt(e) {\n const t = e.value;\n if (t == null) return \"\";\n if (typeof t == \"string\") return t;\n if (typeof t == \"number\") return String(t);\n if (typeof t == \"boolean\") return t ? \"TRUE\" : \"FALSE\";\n if (t instanceof Date)\n return t.toLocaleDateString();\n if (typeof t == \"object\" && \"formula\" in t) {\n const o = t.result;\n return o != null ? String(o) : \"\";\n }\n return typeof t == \"object\" && \"richText\" in t ? t.richText.map((n) => n.text).join(\"\") : typeof t == \"object\" && \"hyperlink\" in t ? t.text || \"\" : typeof t == \"object\" && \"error\" in t ? String(t.error) : String(t);\n}\nfunction rt(e) {\n const t = e.split(\":\"), o = P(t[0]), n = t[1] ? P(t[1]) : o;\n return {\n top: o.row,\n left: o.col,\n bottom: n.row,\n right: n.col\n };\n}\nfunction P(e) {\n const t = e.match(/^([A-Z]+)(\\d+)$/);\n if (!t) return { row: 1, col: 1 };\n const o = t[1], n = parseInt(t[2], 10);\n let r = 0;\n for (let a = 0; a < o.length; a++)\n r = r * 26 + (o.charCodeAt(a) - 64);\n return { row: n, col: r };\n}\nfunction zt(e) {\n const t = [];\n return e.eachSheet((o) => {\n const n = [], r = /* @__PURE__ */ new Map(), a = [], i = {}, l = {}, s = o.columnCount;\n for (let f = 1; f <= s; f++) {\n const u = o.getColumn(f);\n u.width && (l[String(f - 1)] = { width: Math.round(u.width * 7.5) });\n }\n l.len = Math.max(s, 26);\n const c = /* @__PURE__ */ new Map(), d = o.model, p = (d == null ? void 0 : d.merges) || [];\n for (const f of p) {\n a.push(f);\n const { top: u, left: m, bottom: h, right: b } = rt(f), g = h - u, x = b - m;\n c.set(`${u - 1},${m - 1}`, [g, x]);\n }\n o.eachRow({ includeEmpty: !0 }, (f, u) => {\n const m = u - 1, h = {};\n f.eachCell({ includeEmpty: !1 }, (g, x) => {\n const v = x - 1;\n if (g.isMerged && g.master !== g) return;\n const F = nt(g), _ = ot(g, n, r), w = { text: F };\n _ !== -1 && (w.style = _);\n const y = `${m},${v}`;\n c.has(y) && (w.merge = c.get(y)), h[String(v)] = w;\n });\n const b = { cells: h };\n f.height && (b.height = Math.round(f.height * 1.333)), i[String(m)] = b;\n }), t.push({\n name: o.name,\n styles: n,\n merges: a,\n rows: i,\n cols: l\n });\n }), t;\n}\nfunction Lt(e, t, o = \"Sheet1\") {\n const n = e.length > 0, a = n ? [{ font: { bold: !0 } }] : [], i = {};\n if (n) {\n const s = {};\n e.forEach((c, d) => {\n s[String(d)] = { text: c, style: 0 };\n }), i[0] = { cells: s };\n }\n const l = n ? 1 : 0;\n return t.forEach((s, c) => {\n const d = {};\n s.forEach((p, f) => {\n p !== void 0 && p !== \"\" && (d[String(f)] = { text: p });\n }), i[String(c + l)] = { cells: d };\n }), [{ name: o, styles: a, rows: i }];\n}\nfunction Dt(e, t) {\n var i;\n if (typeof window > \"u\") return;\n const o = (e == null ? void 0 : e.version) || ((i = e == null ? void 0 : e.GlobalWorkerOptions) == null ? void 0 : i.version) || \"\", {\n workerSrc: n = `https://unpkg.com/pdfjs-dist@${o}/build/pdf.worker.min.mjs`,\n cMapUrl: r = `https://unpkg.com/pdfjs-dist@${o}/cmaps/`,\n cMapPacked: a = !0\n } = t || {};\n e.GlobalWorkerOptions && (e.GlobalWorkerOptions.workerSrc = n, e.GlobalWorkerOptions.cMapUrl = r, e.GlobalWorkerOptions.cMapPacked = a);\n}\nconst it = {\n // ─────── common ───────\n \"common.download\": \"下载\",\n \"common.close\": \"关闭\",\n \"common.loading\": \"加载中\",\n \"common.unknown_error\": \"未知错误\",\n \"common.unsupported_preview\": \"不支持预览此文件类型 ({type})\",\n // ─────── toolbar ───────\n \"toolbar.zoom_in\": \"放大\",\n \"toolbar.zoom_out\": \"缩小\",\n \"toolbar.rotate_left\": \"向左旋转\",\n \"toolbar.rotate_right\": \"向右旋转\",\n \"toolbar.reset\": \"复原\",\n \"toolbar.fit_to_window\": \"适应窗口\",\n \"toolbar.original_size\": \"原始尺寸\",\n \"toolbar.toc\": \"目录\",\n \"toolbar.prev_page\": \"上一页\",\n \"toolbar.next_page\": \"下一页\",\n \"toolbar.full_width\": \"全屏宽度\",\n \"toolbar.normal_width\": \"正常宽度\",\n \"toolbar.wrap_on\": \"自动换行\",\n \"toolbar.wrap_off\": \"不换行\",\n \"toolbar.source\": \"源码\",\n \"toolbar.preview\": \"预览\",\n // ─────── image ───────\n \"image.load_failed\": \"图片加载失败\",\n // ─────── pdf ───────\n \"pdf.load_failed\": \"PDF 文件加载失败\",\n // ─────── docx ───────\n \"docx.parse_failed\": \"Word 文档解析失败\",\n // ─────── xlsx ───────\n \"xlsx.loading\": \"加载 Excel 中...\",\n \"xlsx.load_failed\": \"Excel 加载失败\",\n \"xlsx.parse_failed\": \"Excel 文件解析失败\",\n \"xlsx.not_found\": \"Excel 文件不存在\",\n // ─────── pptx ───────\n \"pptx.loading\": \"加载 PPT 中...\",\n \"pptx.load_failed\": \"PPT 加载失败\",\n \"pptx.parse_failed\": \"PPT 文件解析失败\",\n \"pptx.not_found\": \"PPT 文件不存在\",\n \"pptx.invalid_format\": \"PPT 文件格式错误或已损坏\",\n \"pptx.no_pages\": \"PPT 文件无有效页面\",\n \"pptx.timeout\": \"加载超时,请检查网络或稍后重试\",\n // ─────── msg ───────\n \"msg.parse_failed\": \"Outlook 邮件解析失败\",\n \"msg.parse_failed_short\": \"邮件解析失败\",\n \"msg.empty_body\": \"(无邮件正文)\",\n // ─────── epub ───────\n \"epub.load_failed\": \"EPUB 文件加载失败\",\n // ─────── mobi ───────\n \"mobi.load_failed\": \"电子书加载失败,文件可能已损坏或带有 DRM 保护\",\n // ─────── video ───────\n \"video.loading\": \"加载视频中...\",\n \"video.load_failed\": \"视频加载失败\",\n \"video.load_failed_with_error\": \"视频加载失败: {error}\",\n // ─────── audio (aria-label) ───────\n \"audio.aria.play\": \"播放\",\n \"audio.aria.pause\": \"暂停\",\n \"audio.aria.forward_10\": \"前进 10 秒\",\n \"audio.aria.backward_10\": \"后退 10 秒\",\n \"audio.aria.mute\": \"静音\",\n \"audio.aria.unmute\": \"取消静音\",\n \"audio.aria.loop_on\": \"开启循环\",\n \"audio.aria.loop_off\": \"关闭循环\",\n \"audio.aria.progress\": \"播放进度\",\n \"audio.aria.volume\": \"音量\",\n // ─────── markdown ───────\n \"markdown.load_failed\": \"Markdown 文件加载失败\",\n \"markdown.copy_code\": \"复制代码\",\n \"markdown.copied\": \"已复制\",\n // ─────── json ───────\n \"json.load_failed\": \"JSON 文件加载失败\",\n \"json.items\": \"items\",\n \"json.keys\": \"keys\",\n // ─────── csv ───────\n \"csv.loading\": \"加载 CSV 中...\",\n \"csv.load_failed\": \"CSV 文件加载失败\",\n \"csv.parse_failed\": \"CSV 解析失败\",\n // ─────── xml ───────\n \"xml.load_failed\": \"XML 文件加载失败\",\n // ─────── subtitle / lyric ───────\n \"subtitle.load_failed\": \"字幕文件加载失败\",\n \"subtitle.parse_failed\": \"字幕解析失败\",\n \"subtitle.lines\": \"lines\",\n \"subtitle.cues\": \"cues\",\n \"subtitle.meta.title\": \"标题\",\n \"subtitle.meta.artist\": \"艺术家\",\n \"subtitle.meta.album\": \"专辑\",\n \"subtitle.meta.author\": \"作者\",\n \"subtitle.meta.by\": \"制作\",\n \"subtitle.meta.length\": \"时长\",\n \"subtitle.meta.offset\": \"偏移\",\n \"subtitle.meta.editor\": \"编辑器\",\n \"subtitle.meta.version\": \"版本\",\n // ─────── zip ───────\n \"zip.load_failed\": \"ZIP 文件加载失败\",\n \"zip.parse_failed\": \"ZIP 解析失败\",\n // ─────── text ───────\n \"text.load_failed\": \"文本文件加载失败\",\n // ─────── font ───────\n \"font.loading\": \"加载字体中...\",\n \"font.load_failed\": \"字体文件加载失败\",\n \"font.parse_failed\": \"字体解析失败\",\n \"font.meta.family\": \"字体家族\",\n \"font.meta.subfamily\": \"子系列\",\n \"font.meta.version\": \"版本\",\n \"font.meta.designer\": \"设计师\",\n \"font.meta.glyphs\": \"字形数量\",\n \"font.meta.format\": \"格式\",\n \"font.sample_text_placeholder\": \"输入自定义文本...\"\n}, at = {\n // ─────── common ───────\n \"common.download\": \"Download\",\n \"common.close\": \"Close\",\n \"common.loading\": \"Loading\",\n \"common.unknown_error\": \"Unknown error\",\n \"common.unsupported_preview\": \"Preview not supported for this file type ({type})\",\n // ─────── toolbar ───────\n \"toolbar.zoom_in\": \"Zoom in\",\n \"toolbar.zoom_out\": \"Zoom out\",\n \"toolbar.rotate_left\": \"Rotate left\",\n \"toolbar.rotate_right\": \"Rotate right\",\n \"toolbar.reset\": \"Reset\",\n \"toolbar.fit_to_window\": \"Fit to window\",\n \"toolbar.original_size\": \"Original size\",\n \"toolbar.toc\": \"Table of contents\",\n \"toolbar.prev_page\": \"Previous page\",\n \"toolbar.next_page\": \"Next page\",\n \"toolbar.full_width\": \"Full width\",\n \"toolbar.normal_width\": \"Normal width\",\n \"toolbar.wrap_on\": \"Word wrap\",\n \"toolbar.wrap_off\": \"No wrap\",\n \"toolbar.source\": \"Source\",\n \"toolbar.preview\": \"Preview\",\n // ─────── image ───────\n \"image.load_failed\": \"Failed to load image\",\n // ─────── pdf ───────\n \"pdf.load_failed\": \"Failed to load PDF\",\n // ─────── docx ───────\n \"docx.parse_failed\": \"Failed to parse Word document\",\n // ─────── xlsx ───────\n \"xlsx.loading\": \"Loading Excel...\",\n \"xlsx.load_failed\": \"Failed to load Excel\",\n \"xlsx.parse_failed\": \"Failed to parse Excel file\",\n \"xlsx.not_found\": \"Excel file not found\",\n // ─────── pptx ───────\n \"pptx.loading\": \"Loading PPT...\",\n \"pptx.load_failed\": \"Failed to load PPT\",\n \"pptx.parse_failed\": \"Failed to parse PPT file\",\n \"pptx.not_found\": \"PPT file not found\",\n \"pptx.invalid_format\": \"PPT file format is invalid or corrupted\",\n \"pptx.no_pages\": \"PPT file has no valid pages\",\n \"pptx.timeout\": \"Loading timed out, please check your network and retry\",\n // ─────── msg ───────\n \"msg.parse_failed\": \"Failed to parse Outlook message\",\n \"msg.parse_failed_short\": \"Failed to parse message\",\n \"msg.empty_body\": \"(No message body)\",\n // ─────── epub ───────\n \"epub.load_failed\": \"Failed to load EPUB\",\n // ─────── mobi ───────\n \"mobi.load_failed\": \"Failed to load ebook — file may be corrupted or DRM-protected\",\n // ─────── video ───────\n \"video.loading\": \"Loading video...\",\n \"video.load_failed\": \"Failed to load video\",\n \"video.load_failed_with_error\": \"Failed to load video: {error}\",\n // ─────── audio (aria-label) ───────\n \"audio.aria.play\": \"Play\",\n \"audio.aria.pause\": \"Pause\",\n \"audio.aria.forward_10\": \"Forward 10 seconds\",\n \"audio.aria.backward_10\": \"Back 10 seconds\",\n \"audio.aria.mute\": \"Mute\",\n \"audio.aria.unmute\": \"Unmute\",\n \"audio.aria.loop_on\": \"Enable loop\",\n \"audio.aria.loop_off\": \"Disable loop\",\n \"audio.aria.progress\": \"Playback progress\",\n \"audio.aria.volume\": \"Volume\",\n // ─────── markdown ───────\n \"markdown.load_failed\": \"Failed to load Markdown\",\n \"markdown.copy_code\": \"Copy code\",\n \"markdown.copied\": \"Copied\",\n // ─────── json ───────\n \"json.load_failed\": \"Failed to load JSON\",\n \"json.items\": \"items\",\n \"json.keys\": \"keys\",\n // ─────── csv ───────\n \"csv.loading\": \"Loading CSV...\",\n \"csv.load_failed\": \"Failed to load CSV\",\n \"csv.parse_failed\": \"Failed to parse CSV\",\n // ─────── xml ───────\n \"xml.load_failed\": \"Failed to load XML\",\n // ─────── subtitle / lyric ───────\n \"subtitle.load_failed\": \"Failed to load subtitle\",\n \"subtitle.parse_failed\": \"Failed to parse subtitle\",\n \"subtitle.lines\": \"lines\",\n \"subtitle.cues\": \"cues\",\n \"subtitle.meta.title\": \"Title\",\n \"subtitle.meta.artist\": \"Artist\",\n \"subtitle.meta.album\": \"Album\",\n \"subtitle.meta.author\": \"Author\",\n \"subtitle.meta.by\": \"By\",\n \"subtitle.meta.length\": \"Length\",\n \"subtitle.meta.offset\": \"Offset\",\n \"subtitle.meta.editor\": \"Editor\",\n \"subtitle.meta.version\": \"Version\",\n // ─────── zip ───────\n \"zip.load_failed\": \"Failed to load ZIP\",\n \"zip.parse_failed\": \"Failed to parse ZIP\",\n // ─────── text ───────\n \"text.load_failed\": \"Failed to load text file\",\n // ─────── font ───────\n \"font.loading\": \"Loading font...\",\n \"font.load_failed\": \"Failed to load font\",\n \"font.parse_failed\": \"Failed to parse font\",\n \"font.meta.family\": \"Family\",\n \"font.meta.subfamily\": \"Subfamily\",\n \"font.meta.version\": \"Version\",\n \"font.meta.designer\": \"Designer\",\n \"font.meta.glyphs\": \"Glyphs\",\n \"font.meta.format\": \"Format\",\n \"font.sample_text_placeholder\": \"Type custom text...\"\n}, C = {\n \"zh-CN\": it,\n \"en-US\": at\n}, st = /\\{(\\w+)\\}/g;\nfunction lt(e, t) {\n return t ? e.replace(st, (o, n) => {\n const r = t[n];\n return r === void 0 ? `{${n}}` : String(r);\n }) : e;\n}\nfunction Nt(e) {\n var i;\n const t = e.fallbackLocale ?? \"zh-CN\", o = C[e.locale] ?? C[t] ?? C[\"zh-CN\"], n = (i = e.messages) == null ? void 0 : i[e.locale], r = n ? { ...o, ...n } : o, a = C[\"zh-CN\"];\n return (l, s) => {\n const c = r[l] ?? a[l] ?? l;\n return lt(c, s);\n };\n}\nexport {\n dt as SUPPORTED_FILE_TYPES,\n Tt as buildZipTree,\n C as builtInMessages,\n Dt as configurePdfWorker,\n Lt as convertCsvToSpreadsheetData,\n zt as convertWorkbookToSpreadsheetData,\n wt as createFetcher,\n Nt as createTranslator,\n $ as decodeText,\n I as decodeUtf8,\n yt as downloadFileWithFetcher,\n vt as fetchAsBlobUrl,\n Ft as fetchTextUtf8,\n ht as formatFileSize,\n _t as formatSubtitleTime,\n gt as formatTime,\n U as getFileNameFromUrl,\n ut as getFileType,\n pt as getLanguageFromFileName,\n mt as getVideoMimeType,\n xt as guessCsvDelimiter,\n k as inferMimeType,\n St as listZipEntries,\n kt as loadZip,\n A as normalizeFile,\n ft as normalizeFiles,\n bt as parseCsv,\n Ct as parseSubtitle,\n Et as readZipEntryBlob,\n Mt as readZipEntryText\n};\n//# sourceMappingURL=index.mjs.map\n","import React, { createContext, useContext, useMemo } from 'react';\nimport {\n createTranslator,\n type Locale,\n type Messages,\n type Translator,\n} from '@eternalheart/file-preview-core';\n\nexport interface LocaleContextValue {\n locale: Locale;\n t: Translator;\n}\n\nconst LocaleContext = createContext<LocaleContextValue | null>(null);\n\nexport interface LocaleProviderProps {\n /** 当前语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义字典,浅合并到内置字典之上 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n children: React.ReactNode;\n}\n\nexport const LocaleProvider: React.FC<LocaleProviderProps> = ({\n locale = 'zh-CN',\n messages,\n children,\n}) => {\n const value = useMemo<LocaleContextValue>(() => {\n const t = createTranslator({ locale, messages });\n return { locale, t };\n }, [locale, messages]);\n\n return <LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>;\n};\n\n/**\n * 兜底 translator(当组件被脱离 LocaleProvider 直接使用时)\n * 保持模块级单例,避免每次调用重建\n */\nlet fallbackTranslator: Translator | null = null;\nfunction getFallbackTranslator(): Translator {\n if (!fallbackTranslator) {\n fallbackTranslator = createTranslator({ locale: 'zh-CN' });\n }\n return fallbackTranslator;\n}\n\n/**\n * 获取翻译函数。任意位置调用都安全:\n * - 在 LocaleProvider 下 → 用 provider 提供的 translator\n * - 否则 → 回落到 zh-CN 兜底 translator\n */\nexport function useTranslator(): Translator {\n const ctx = useContext(LocaleContext);\n return ctx?.t ?? getFallbackTranslator();\n}\n\n/**\n * 获取当前 locale。在 Provider 之外返回 'zh-CN'。\n */\nexport function useLocale(): Locale {\n const ctx = useContext(LocaleContext);\n return ctx?.locale ?? 'zh-CN';\n}\n","import React, { createContext, useContext } from 'react';\n\n/** 已解析的主题(auto 在 FilePreviewContent 里被解析过) */\nexport type ResolvedTheme = 'dark' | 'light';\n\nconst ThemeContext = createContext<ResolvedTheme | null>(null);\n\nexport interface ThemeProviderProps {\n theme: ResolvedTheme;\n children: React.ReactNode;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({ theme, children }) => {\n return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;\n};\n\n/**\n * 获取已解析的主题('dark' | 'light')。\n * Provider 之外默认 'dark'(保持组件历史默认行为)。\n *\n * renderer 需要切第三方库的 theme prop(如 react-syntax-highlighter 的 style、\n * shiki 的 theme 选项)时使用;不要用它做 className 分支 —— class 由 CSS 变量\n * 通过根容器 [data-theme] 自动切换。\n */\nexport function useResolvedTheme(): ResolvedTheme {\n return useContext(ThemeContext) ?? 'dark';\n}\n","import React from 'react';\nimport { ZoomIn, ZoomOut, RotateCw, RotateCcw, Scan, RefreshCw } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nconst OriginalSizeIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <text x=\"12\" y=\"17.5\" textAnchor=\"middle\" fontSize=\"20\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">\n 1:1\n </text>\n </svg>\n);\n\nexport interface ImageToolbarContext {\n zoom: number;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onFitToWidth: () => void;\n onOriginalSize: () => void;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n onReset: () => void;\n t: Translator;\n}\n\nexport function getImageToolbarGroups(ctx: ImageToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n { type: 'button', icon: <ZoomOut className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_out'), action: ctx.onZoomOut, disabled: ctx.zoom <= 0.01 },\n { type: 'text', content: `${Math.round(ctx.zoom * 100)}%`, minWidth: '3rem' },\n { type: 'button', icon: <ZoomIn className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_in'), action: ctx.onZoomIn, disabled: ctx.zoom >= 10 },\n ],\n },\n {\n items: [\n { type: 'button', icon: <Scan className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.fit_to_window'), action: ctx.onFitToWidth },\n { type: 'button', icon: <OriginalSizeIcon className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.original_size'), action: ctx.onOriginalSize },\n ],\n },\n {\n items: [\n { type: 'button', icon: <RotateCcw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.rotate_left'), action: ctx.onRotateLeft },\n { type: 'button', icon: <RotateCw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.rotate_right'), action: ctx.onRotateRight },\n ],\n },\n {\n items: [\n { type: 'button', icon: <RefreshCw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.reset'), action: ctx.onReset },\n ],\n },\n ];\n}\n","import { ZoomIn, ZoomOut, RefreshCw } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface PdfToolbarContext {\n zoom: number;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onReset: () => void;\n t: Translator;\n}\n\nexport function getPdfToolbarGroups(ctx: PdfToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n { type: 'button', icon: <ZoomOut className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_out'), action: ctx.onZoomOut, disabled: ctx.zoom <= 0.01 },\n { type: 'text', content: `${Math.round(ctx.zoom * 100)}%`, minWidth: '3rem' },\n { type: 'button', icon: <ZoomIn className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.zoom_in'), action: ctx.onZoomIn, disabled: ctx.zoom >= 10 },\n ],\n },\n {\n items: [\n { type: 'button', icon: <RefreshCw className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.reset'), action: ctx.onReset },\n ],\n },\n ];\n}\n","import React from 'react';\nimport { ChevronLeft, ChevronRight, List, Maximize2, Minimize2 } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { EpubRendererHandle } from './index';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface EpubToolbarContext {\n epubRef: React.RefObject<EpubRendererHandle | null>;\n current: number;\n total: number;\n fullWidth: boolean;\n t: Translator;\n}\n\nexport function getEpubToolbarGroups(ctx: EpubToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n { type: 'button', icon: <List className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.toc'), action: () => ctx.epubRef.current?.toggleToc() },\n ],\n },\n {\n items: [\n { type: 'button', icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.prev_page'), action: () => ctx.epubRef.current?.prevPage() },\n { type: 'text', content: `${ctx.current} / ${ctx.total}`, minWidth: '4rem' },\n { type: 'button', icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />, tooltip: ctx.t('toolbar.next_page'), action: () => ctx.epubRef.current?.nextPage() },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: ctx.fullWidth ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" /> : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.fullWidth ? ctx.t('toolbar.normal_width') : ctx.t('toolbar.full_width'),\n action: () => ctx.epubRef.current?.toggleFullWidth(),\n },\n ],\n },\n ];\n}\n","import React from 'react';\nimport { ChevronLeft, ChevronRight, List, Maximize2, Minimize2 } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { MobiRendererHandle } from './index';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface MobiToolbarContext {\n mobiRef: React.RefObject<MobiRendererHandle | null>;\n current: number;\n total: number;\n fullWidth: boolean;\n t: Translator;\n}\n\nexport function getMobiToolbarGroups(ctx: MobiToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n {\n type: 'button',\n icon: <List className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.t('toolbar.toc'),\n action: () => ctx.mobiRef.current?.toggleToc(),\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.t('toolbar.prev_page'),\n action: () => ctx.mobiRef.current?.prevPage(),\n },\n {\n type: 'text',\n content: `${ctx.current} / ${ctx.total}`,\n minWidth: '4rem',\n },\n {\n type: 'button',\n icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.t('toolbar.next_page'),\n action: () => ctx.mobiRef.current?.nextPage(),\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: ctx.fullWidth\n ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" />\n : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.fullWidth ? ctx.t('toolbar.normal_width') : ctx.t('toolbar.full_width'),\n action: () => ctx.mobiRef.current?.toggleFullWidth(),\n },\n ],\n },\n ];\n}\n","import type { ToolbarGroup } from '../toolbar.types';\nimport { formatFileSize } from '@eternalheart/file-preview-core';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface ZipToolbarStats {\n files: number;\n dirs: number;\n size: number;\n}\n\nexport interface ZipToolbarContext {\n stats: ZipToolbarStats | null;\n t: Translator;\n}\n\nexport function getZipToolbarGroups({ stats }: ZipToolbarContext): ToolbarGroup[] {\n if (!stats) return [];\n return [\n {\n items: [\n {\n type: 'text',\n content: `${stats.files} files · ${stats.dirs} dirs · ${formatFileSize(stats.size)}`,\n minWidth: '10rem',\n },\n ],\n },\n ];\n}\n","import { WrapText, Eye, Code } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface TextToolbarContext {\n wordWrap: boolean;\n onToggleWrap: () => void;\n isHtml: boolean;\n htmlPreview: boolean;\n onToggleHtmlPreview: () => void;\n t: Translator;\n}\n\nexport function getTextToolbarGroups(ctx: TextToolbarContext): ToolbarGroup[] {\n const groups: ToolbarGroup[] = [\n {\n items: [\n {\n type: 'button',\n icon: <WrapText className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.wordWrap ? ctx.t('toolbar.wrap_off') : ctx.t('toolbar.wrap_on'),\n action: ctx.onToggleWrap,\n },\n ],\n },\n ];\n\n if (ctx.isHtml) {\n groups.push({\n items: [\n {\n type: 'button',\n icon: ctx.htmlPreview\n ? <Code className=\"rfp-w-4 rfp-h-4\" />\n : <Eye className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.htmlPreview ? ctx.t('toolbar.source') : ctx.t('toolbar.preview'),\n action: ctx.onToggleHtmlPreview,\n },\n ],\n });\n }\n\n return groups;\n}\n","import { Eye, Code } from 'lucide-react';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport type { Translator } from '@eternalheart/file-preview-core';\n\nexport interface MarkdownToolbarContext {\n viewMode: 'preview' | 'source';\n onToggleViewMode: () => void;\n t: Translator;\n}\n\nexport function getMarkdownToolbarGroups(ctx: MarkdownToolbarContext): ToolbarGroup[] {\n return [\n {\n items: [\n {\n type: 'button',\n icon: ctx.viewMode === 'preview'\n ? <Code className=\"rfp-w-4 rfp-h-4\" />\n : <Eye className=\"rfp-w-4 rfp-h-4\" />,\n tooltip: ctx.viewMode === 'preview' ? ctx.t('toolbar.source') : ctx.t('toolbar.preview'),\n action: ctx.onToggleViewMode,\n },\n ],\n },\n ];\n}\n","import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n Fetcher,\n PreviewFile,\n RequestHandler,\n RequestInitFactory,\n ShouldFetchAsBlob,\n} from '@eternalheart/file-preview-core';\nimport { createFetcher, fetchAsBlobUrl } from '@eternalheart/file-preview-core';\n\nexport interface RequestContextValue {\n fetcher: Fetcher;\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n}\n\nconst defaultValue: RequestContextValue = {\n fetcher: (url, init) => fetch(url, init),\n};\n\nconst RequestContext = createContext<RequestContextValue>(defaultValue);\n\nexport interface RequestProviderProps {\n requestInit?: RequestInitFactory;\n requestHandler?: RequestHandler;\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n children: React.ReactNode;\n}\n\nexport const RequestProvider: React.FC<RequestProviderProps> = ({\n requestInit,\n requestHandler,\n shouldFetchAsBlob,\n children,\n}) => {\n const value = useMemo<RequestContextValue>(\n () => ({\n fetcher: createFetcher({ requestInit, requestHandler }),\n shouldFetchAsBlob,\n }),\n [requestInit, requestHandler, shouldFetchAsBlob],\n );\n return (\n <RequestContext.Provider value={value}>{children}</RequestContext.Provider>\n );\n};\n\nexport function useRequest(): RequestContextValue {\n return useContext(RequestContext);\n}\n\nexport function useFetcher(): Fetcher {\n return useContext(RequestContext).fetcher;\n}\n\n/**\n * 解析 file 的可消费 URL:\n * - 未配置 shouldFetchAsBlob 或返回 false:直接返回 file.url\n * - 返回 true:用 fetcher 拉成 blob: URL,组件卸载或 file 变化时 revoke\n *\n * 期间返回空字符串(表示 \"还没准备好\"),调用方应避免空 URL 时挂载到 <img src> 等。\n */\nexport function useResolvedUrl(file: PreviewFile | undefined): string {\n const { fetcher, shouldFetchAsBlob } = useContext(RequestContext);\n const needBlob = !!(file && shouldFetchAsBlob?.(file));\n const [resolved, setResolved] = useState<string>(() =>\n !file ? '' : needBlob ? '' : file.url,\n );\n const createdRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!file) {\n setResolved('');\n return;\n }\n if (!needBlob) {\n setResolved(file.url);\n return;\n }\n let cancelled = false;\n setResolved('');\n fetchAsBlobUrl(file.url, fetcher)\n .then((blobUrl) => {\n if (cancelled) {\n URL.revokeObjectURL(blobUrl);\n return;\n }\n if (createdRef.current) {\n URL.revokeObjectURL(createdRef.current);\n }\n createdRef.current = blobUrl;\n setResolved(blobUrl);\n })\n .catch((err) => {\n if (!cancelled) {\n console.error('[file-preview] resolve blob url failed:', err);\n setResolved(file.url);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [file?.id, file?.url, needBlob, fetcher]);\n\n // 卸载时 revoke 最后一次创建的 blob URL\n useEffect(() => {\n return () => {\n if (createdRef.current) {\n URL.revokeObjectURL(createdRef.current);\n createdRef.current = null;\n }\n };\n }, []);\n\n return resolved;\n}\n","// 集中的 lazy 装饰:把每个 renderer 转为 React.lazy(import).then(default),\n// 让 rollup 自动按 chunk 分割。\n// 显式声明 LazyExoticComponent 以避免 TS4023(要求把内部 Props 类型导入到当前文件作用域)。\nimport { lazy, type LazyExoticComponent, type ComponentType } from 'react';\nimport type { ImageRenderer as ImageRendererImpl } from './Image';\nimport type { PdfRenderer as PdfRendererImpl } from './Pdf';\nimport type { DocxRenderer as DocxRendererImpl } from './Docx';\nimport type { XlsxRenderer as XlsxRendererImpl } from './Xlsx';\nimport type { PptxRenderer as PptxRendererImpl } from './Pptx';\nimport type { MsgRenderer as MsgRendererImpl } from './Msg';\nimport type { EpubRenderer as EpubRendererImpl } from './Epub';\nimport type { MobiRenderer as MobiRendererImpl } from './Mobi';\nimport type { VideoRenderer as VideoRendererImpl } from './Video';\nimport type { AudioRenderer as AudioRendererImpl } from './Audio';\nimport type { MarkdownRenderer as MarkdownRendererImpl } from './Markdown';\nimport type { JsonRenderer as JsonRendererImpl } from './Json';\nimport type { CsvRenderer as CsvRendererImpl } from './Csv';\nimport type { XmlRenderer as XmlRendererImpl } from './Xml';\nimport type { SubtitleRenderer as SubtitleRendererImpl } from './Subtitle';\nimport type { ZipRenderer as ZipRendererImpl } from './Zip';\nimport type { TextRenderer as TextRendererImpl } from './Text';\nimport type { FontRenderer as FontRendererImpl } from './Font';\n\ntype Lazy<T> = LazyExoticComponent<T extends ComponentType<infer P> ? ComponentType<P> : never>;\n\nexport const ImageRenderer: Lazy<typeof ImageRendererImpl> = lazy(() =>\n import('./Image').then((m) => ({ default: m.ImageRenderer })),\n);\n\nexport const PdfRenderer: Lazy<typeof PdfRendererImpl> = lazy(() =>\n import('./Pdf').then((m) => ({ default: m.PdfRenderer })),\n);\n\nexport const DocxRenderer: Lazy<typeof DocxRendererImpl> = lazy(() =>\n import('./Docx').then((m) => ({ default: m.DocxRenderer })),\n);\n\nexport const XlsxRenderer: Lazy<typeof XlsxRendererImpl> = lazy(() =>\n import('./Xlsx').then((m) => ({ default: m.XlsxRenderer })),\n);\n\nexport const PptxRenderer: Lazy<typeof PptxRendererImpl> = lazy(() =>\n import('./Pptx').then((m) => ({ default: m.PptxRenderer })),\n);\n\nexport const MsgRenderer: Lazy<typeof MsgRendererImpl> = lazy(() =>\n import('./Msg').then((m) => ({ default: m.MsgRenderer })),\n);\n\nexport const EpubRenderer: Lazy<typeof EpubRendererImpl> = lazy(() =>\n import('./Epub').then((m) => ({ default: m.EpubRenderer })),\n);\n\nexport const MobiRenderer: Lazy<typeof MobiRendererImpl> = lazy(() =>\n import('./Mobi').then((m) => ({ default: m.MobiRenderer })),\n);\n\nexport const VideoRenderer: Lazy<typeof VideoRendererImpl> = lazy(() =>\n import('./Video').then((m) => ({ default: m.VideoRenderer })),\n);\n\nexport const AudioRenderer: Lazy<typeof AudioRendererImpl> = lazy(() =>\n import('./Audio').then((m) => ({ default: m.AudioRenderer })),\n);\n\nexport const MarkdownRenderer: Lazy<typeof MarkdownRendererImpl> = lazy(() =>\n import('./Markdown').then((m) => ({ default: m.MarkdownRenderer })),\n);\n\nexport const JsonRenderer: Lazy<typeof JsonRendererImpl> = lazy(() =>\n import('./Json').then((m) => ({ default: m.JsonRenderer })),\n);\n\nexport const CsvRenderer: Lazy<typeof CsvRendererImpl> = lazy(() =>\n import('./Csv').then((m) => ({ default: m.CsvRenderer })),\n);\n\nexport const XmlRenderer: Lazy<typeof XmlRendererImpl> = lazy(() =>\n import('./Xml').then((m) => ({ default: m.XmlRenderer })),\n);\n\nexport const SubtitleRenderer: Lazy<typeof SubtitleRendererImpl> = lazy(() =>\n import('./Subtitle').then((m) => ({ default: m.SubtitleRenderer })),\n);\n\nexport const ZipRenderer: Lazy<typeof ZipRendererImpl> = lazy(() =>\n import('./Zip').then((m) => ({ default: m.ZipRenderer })),\n);\n\nexport const TextRenderer: Lazy<typeof TextRendererImpl> = lazy(() =>\n import('./Text').then((m) => ({ default: m.TextRenderer })),\n);\n\nexport const FontRenderer: Lazy<typeof FontRendererImpl> = lazy(() =>\n import('./Font').then((m) => ({ default: m.FontRenderer })),\n);\n","import { FileQuestion, Download } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ninterface UnsupportedRendererProps {\n fileName: string;\n fileType: string;\n onDownload: () => void;\n}\n\nexport const UnsupportedRenderer: React.FC<UnsupportedRendererProps> = ({\n fileName,\n fileType,\n onDownload,\n}) => {\n const t = useTranslator();\n return (\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-p-8 rfp-gap-6\">\n <div className=\"rfp-w-32 rfp-h-32 rfp-rounded-full rfp-bg-surface-2 rfp-flex rfp-items-center rfp-justify-center\">\n <FileQuestion className=\"rfp-w-16 rfp-h-16 rfp-text-fg-secondary\" />\n </div>\n\n <div className=\"rfp-text-fg-primary rfp-text-center\">\n <p className=\"rfp-text-xl rfp-font-medium rfp-mb-2\">{fileName}</p>\n <p className=\"rfp-text-fg-secondary\">{t('common.unsupported_preview', { type: fileType })}</p>\n </div>\n\n <button\n onClick={onDownload}\n className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-px-6 rfp-py-3 rfp-bg-surface-2 hover:rfp-bg-surface-3 rfp-backdrop-blur-sm rfp-rounded-lg rfp-text-fg-primary rfp-font-medium rfp-transition-all\"\n >\n <Download className=\"rfp-w-5 rfp-h-5\" />\n {t('common.download')}\n </button>\n </div>\n );\n};\n","import React from 'react';\nimport { useTranslator } from '../i18n/LocaleContext';\n\nexport const RendererLoading: React.FC = () => {\n const t = useTranslator();\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-text-fg-muted\">\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-gap-3\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-rounded-full rfp-border-2 rfp-border-fg-muted rfp-border-t-transparent rfp-animate-spin\" />\n <span className=\"rfp-text-sm\">{t('common.loading') ?? 'Loading...'}</span>\n </div>\n </div>\n );\n};\n","import React, { useState, useEffect, useCallback, useMemo, useRef, Suspense } from 'react';\nimport { motion } from 'framer-motion';\nimport { X, Download, ChevronLeft, ChevronRight } from 'lucide-react';\nimport { getFileType, createTranslator, type Locale, type Messages, type Translator, type Theme } from '@eternalheart/file-preview-core';\nimport { LocaleProvider } from './i18n/LocaleContext';\nimport { ThemeProvider } from './ThemeContext';\nimport type { ToolbarGroup } from './renderers/toolbar.types';\nimport { getImageToolbarGroups } from './renderers/Image/toolbar';\nimport { getPdfToolbarGroups } from './renderers/Pdf/toolbar';\nimport { getEpubToolbarGroups } from './renderers/Epub/toolbar';\nimport { getMobiToolbarGroups } from './renderers/Mobi/toolbar';\nimport { getZipToolbarGroups, type ZipToolbarStats } from './renderers/Zip/toolbar';\nimport { getTextToolbarGroups } from './renderers/Text/toolbar';\nimport { getMarkdownToolbarGroups } from './renderers/Markdown/toolbar';\n\nimport { PreviewFileInput, CustomRenderer, CustomRendererContext } from './types';\nimport type { CustomRendererEventPayload, PreviewFile, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';\nimport { downloadFileWithFetcher } from '@eternalheart/file-preview-core';\nimport { normalizeFiles } from './utils/fileNormalizer';\nimport { RequestProvider, useResolvedUrl, useFetcher } from './RequestContext';\n// Renderer 通过 React.lazy 动态加载,运行时按需下载对应 chunk\nimport {\n ImageRenderer,\n PdfRenderer,\n DocxRenderer,\n XlsxRenderer,\n PptxRenderer,\n MsgRenderer,\n EpubRenderer,\n MobiRenderer,\n VideoRenderer,\n AudioRenderer,\n MarkdownRenderer,\n JsonRenderer,\n CsvRenderer,\n XmlRenderer,\n SubtitleRenderer,\n ZipRenderer,\n TextRenderer,\n FontRenderer,\n} from './renderers/lazy';\nimport type { EpubRendererHandle } from './renderers/Epub';\nimport type { MobiRendererHandle } from './renderers/Mobi';\n// 不支持类型回退;体积极小,仍静态打包到主入口\nimport { UnsupportedRenderer } from './renderers/Unsupported';\nimport { RendererLoading } from './renderers/RendererLoading';\n\nconst MAX_ZIP_NESTING_DEPTH = 3;\n\nexport interface FilePreviewContentProps {\n files: PreviewFileInput[];\n currentIndex: number;\n onNavigate?: (index: number) => void;\n customRenderers?: CustomRenderer[];\n /** 运行模式:modal(弹窗) 或 embed(嵌入) */\n mode?: 'modal' | 'embed';\n /** 关闭回调,仅 modal 模式使用 */\n onClose?: () => void;\n /** ZIP 嵌套深度(内部使用),超过上限时不再递归渲染 ZIP */\n zipNestingDepth?: number;\n /** 国际化语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义翻译字典,浅合并到内置字典之上 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n /** 无头模式:隐藏工具栏和导航箭头,仅渲染文件内容 */\n headless?: boolean;\n /** 主题模式,默认 'dark' */\n theme?: Theme;\n /** 自定义渲染器派发的事件出口,载荷为 `{ name, payload, file }` */\n onCustomEvent?: (event: CustomRendererEventPayload) => void;\n /** 自定义 RequestInit(或工厂函数):用于注入 Authorization 等鉴权头 */\n requestInit?: RequestInitFactory;\n /** 自定义请求处理器:完全接管库内 fetch;与 requestInit 同时存在时 handler 接收已合并的 init */\n requestHandler?: RequestHandler;\n /** 返回 true 时,对应文件会先经 fetcher 拉成 blob: URL 再喂给 image/video/audio/pdf 等 renderer */\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n /**\n * 自定义下载回调。提供后完全接管下载行为;\n * 不提供时,库内默认通过 fetcher 拉成 Blob 触发下载(鉴权 URL 场景自动可用)。\n */\n onDownload?: (file: PreviewFile) => void | Promise<void>;\n}\n\nexport const FilePreviewContent: React.FC<FilePreviewContentProps> = (props) => {\n const { requestInit, requestHandler, shouldFetchAsBlob } = props;\n return (\n <RequestProvider\n requestInit={requestInit}\n requestHandler={requestHandler}\n shouldFetchAsBlob={shouldFetchAsBlob}\n >\n <FilePreviewContentInner {...props} />\n </RequestProvider>\n );\n};\n\nconst FilePreviewContentInner: React.FC<FilePreviewContentProps> = ({\n files,\n currentIndex,\n onNavigate,\n customRenderers = [],\n mode = 'modal',\n onClose,\n zipNestingDepth = 0,\n locale = 'zh-CN',\n messages: userMessages,\n headless = false,\n theme = 'dark',\n onCustomEvent,\n onDownload,\n // 以下三项已由外层 RequestProvider 消费,Inner 内不再直接使用\n requestInit: _requestInit,\n requestHandler: _requestHandler,\n shouldFetchAsBlob: _shouldFetchAsBlob,\n}) => {\n const t: Translator = useMemo(\n () => createTranslator({ locale, messages: userMessages }),\n [locale, userMessages],\n );\n\n const [systemDark, setSystemDark] = useState(() =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : true,\n );\n\n useEffect(() => {\n if (theme !== 'auto') return;\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [theme]);\n\n const resolvedTheme = theme === 'auto' ? (systemDark ? 'dark' : 'light') : theme;\n\n const [zoom, setZoom] = useState(1);\n const [rotation, setRotation] = useState(0);\n const [currentPage, setCurrentPage] = useState(1);\n const [, setTotalPages] = useState(1);\n const [contentNaturalWidth, setContentNaturalWidth] = useState(0);\n const [contentNaturalHeight, setContentNaturalHeight] = useState(0);\n const [imageResetKey, setImageResetKey] = useState(0);\n const contentRef = useRef<HTMLDivElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const epubRef = useRef<EpubRendererHandle>(null);\n const [epubCurrent, setEpubCurrent] = useState(0);\n const [epubTotal, setEpubTotal] = useState(0);\n const [epubFullWidth, setEpubFullWidth] = useState(false);\n const mobiRef = useRef<MobiRendererHandle>(null);\n const [mobiCurrent, setMobiCurrent] = useState(0);\n const [mobiTotal, setMobiTotal] = useState(0);\n const [mobiFullWidth, setMobiFullWidth] = useState(false);\n const [zipStats, setZipStats] = useState<ZipToolbarStats | null>(null);\n const [textWordWrap, setTextWordWrap] = useState(true);\n const [textHtmlPreview, setTextHtmlPreview] = useState(false);\n const [markdownViewMode, setMarkdownViewMode] = useState<'preview' | 'source'>('preview');\n\n // 导航箭头自动隐藏\n const [navVisible, setNavVisible] = useState(true);\n const navHideTimerRef = useRef<number | null>(null);\n const NAV_HIDE_DELAY = 2000;\n\n const resetNavTimer = useCallback(() => {\n setNavVisible(true);\n if (navHideTimerRef.current) {\n clearTimeout(navHideTimerRef.current);\n }\n navHideTimerRef.current = window.setTimeout(() => {\n setNavVisible(false);\n }, NAV_HIDE_DELAY);\n }, []);\n\n const handleMouseMove = useCallback(() => {\n resetNavTimer();\n }, [resetNavTimer]);\n\n // 标准化文件输入\n const normalizedFiles = useMemo(() => normalizeFiles(files), [files]);\n\n const currentFile = normalizedFiles[currentIndex];\n\n // 命中 shouldFetchAsBlob 时,把 file.url 转成 blob: URL 喂给 src 类 renderer\n const resolvedUrl = useResolvedUrl(currentFile);\n\n // 检查是否有自定义渲染器匹配当前文件\n const customRenderer = useMemo(() => {\n if (!currentFile) return null;\n return customRenderers.find(renderer => renderer.test(currentFile));\n }, [currentFile, customRenderers]);\n\n const fileType = currentFile ? getFileType(currentFile) : 'unsupported';\n\n // 自定义渲染器事件派发器:未绑定 onCustomEvent 时静默忽略\n const emitCustom = useCallback(\n (name: string, payload?: unknown) => {\n if (!currentFile) return;\n onCustomEvent?.({ name, payload, file: currentFile });\n },\n [currentFile, onCustomEvent],\n );\n\n // 自定义渲染器上下文:注入给 render / getToolbarGroups\n const customCtx = useMemo<CustomRendererContext>(\n () => ({\n emit: emitCustom,\n t,\n theme: resolvedTheme,\n locale,\n }),\n [emitCustom, t, resolvedTheme, locale],\n );\n\n // 重置状态当文件改变时\n useEffect(() => {\n setZoom(1);\n setRotation(0);\n setCurrentPage(1);\n setTotalPages(1);\n setContentNaturalWidth(0);\n setContentNaturalHeight(0);\n setNavVisible(true);\n if (navHideTimerRef.current) {\n clearTimeout(navHideTimerRef.current);\n }\n }, [currentIndex]);\n\n // 图片加载后默认适应窗口\n useEffect(() => {\n if (fileType === 'image' && contentNaturalWidth > 0 && contentNaturalHeight > 0 && contentRef.current) {\n const containerWidth = contentRef.current.clientWidth;\n const containerHeight = contentRef.current.clientHeight;\n const scaleX = containerWidth / contentNaturalWidth;\n const scaleY = containerHeight / contentNaturalHeight;\n const newZoom = Math.min(scaleX, scaleY);\n setZoom(Math.max(0.01, Math.min(10, newZoom)));\n }\n }, [fileType, contentNaturalWidth, contentNaturalHeight]);\n\n // 导航箭头自动隐藏计时器启动 & 清理\n useEffect(() => {\n if (normalizedFiles.length > 1) {\n resetNavTimer();\n }\n return () => {\n if (navHideTimerRef.current) {\n clearTimeout(navHideTimerRef.current);\n }\n };\n }, [normalizedFiles.length, resetNavTimer]);\n\n // 键盘导航\n // - modal 模式:全局监听(window)\n // - embed 模式:只在根容器 focus 时监听,避免影响外部页面交互\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && mode === 'modal') {\n onClose?.();\n } else if (e.key === 'ArrowLeft' && currentIndex > 0) {\n onNavigate?.(currentIndex - 1);\n } else if (e.key === 'ArrowRight' && currentIndex < normalizedFiles.length - 1) {\n onNavigate?.(currentIndex + 1);\n }\n };\n\n if (mode === 'modal') {\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n } else {\n const el = rootRef.current;\n if (!el) return;\n el.addEventListener('keydown', handleKeyDown as EventListener);\n return () => el.removeEventListener('keydown', handleKeyDown as EventListener);\n }\n }, [mode, currentIndex, normalizedFiles.length, onClose, onNavigate]);\n\n const handleZoomIn = useCallback(() => {\n setZoom((prev) => Math.min(prev + 0.1, 10));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setZoom((prev) => Math.max(prev - 0.1, 0.01));\n }, []);\n\n const handleRotate = useCallback(() => {\n setRotation((prev) => prev + 90);\n }, []);\n\n const handleRotateLeft = useCallback(() => {\n setRotation((prev) => prev - 90);\n }, []);\n\n const handleFitToWidth = useCallback(() => {\n if (contentRef.current && contentNaturalWidth > 0 && contentNaturalHeight > 0) {\n const containerWidth = contentRef.current.clientWidth;\n const containerHeight = contentRef.current.clientHeight;\n const scaleX = containerWidth / contentNaturalWidth;\n const scaleY = containerHeight / contentNaturalHeight;\n const newZoom = Math.min(scaleX, scaleY);\n setZoom(Math.max(0.01, Math.min(10, newZoom)));\n } else {\n setZoom(1);\n }\n setRotation(0);\n setImageResetKey(k => k + 1);\n }, [contentNaturalWidth, contentNaturalHeight]);\n\n const handleOriginalSize = useCallback(() => {\n setZoom(1);\n setRotation(0);\n setImageResetKey(k => k + 1);\n }, []);\n\n const handleZoomChange = useCallback((newZoom: number) => {\n setZoom(newZoom);\n }, []);\n\n const handleReset = useCallback(() => {\n setZoom(1);\n setRotation(0);\n setImageResetKey(k => k + 1);\n }, []);\n\n const fetcher = useFetcher();\n const handleDownload = useCallback(async () => {\n if (!currentFile) return;\n if (onDownload) {\n await onDownload(currentFile);\n return;\n }\n try {\n await downloadFileWithFetcher(currentFile.url, currentFile.name, fetcher);\n } catch (err) {\n console.error('[file-preview] download failed:', err);\n }\n }, [currentFile, onDownload, fetcher]);\n\n const handleEpubChapterChange = useCallback((current: number, total: number) => {\n setEpubCurrent(current);\n setEpubTotal(total);\n }, []);\n\n const handleMobiChapterChange = useCallback((current: number, total: number) => {\n setMobiCurrent(current);\n setMobiTotal(total);\n }, []);\n\n const handleZipStatsChange = useCallback((stats: ZipToolbarStats | null) => {\n setZipStats(stats);\n }, []);\n\n if (!currentFile) return null;\n\n const showCloseButton = mode === 'modal' && !!onClose;\n\n // 工具栏配置 — 各 Renderer 自行声明。命中自定义渲染器时优先使用其 getToolbarGroups\n const toolGroups: ToolbarGroup[] = (() => {\n if (customRenderer) {\n return customRenderer.getToolbarGroups?.(currentFile, customCtx) ?? [];\n }\n if (fileType === 'image') {\n return getImageToolbarGroups({\n zoom,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n onFitToWidth: handleFitToWidth,\n onOriginalSize: handleOriginalSize,\n onRotateLeft: handleRotateLeft,\n onRotateRight: handleRotate,\n onReset: handleReset,\n t,\n });\n }\n if (fileType === 'pdf') {\n return getPdfToolbarGroups({\n zoom,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n onReset: handleReset,\n t,\n });\n }\n if (fileType === 'epub') {\n return getEpubToolbarGroups({\n epubRef,\n current: epubCurrent,\n total: epubTotal,\n fullWidth: epubFullWidth,\n t,\n });\n }\n if (fileType === 'mobi') {\n return getMobiToolbarGroups({\n mobiRef,\n current: mobiCurrent,\n total: mobiTotal,\n fullWidth: mobiFullWidth,\n t,\n });\n }\n if (fileType === 'zip') {\n return getZipToolbarGroups({ stats: zipStats, t });\n }\n if (fileType === 'text') {\n const ext = currentFile.name.split('.').pop()?.toLowerCase() || '';\n return getTextToolbarGroups({\n wordWrap: textWordWrap,\n onToggleWrap: () => setTextWordWrap(prev => !prev),\n isHtml: ext === 'html' || ext === 'htm',\n htmlPreview: textHtmlPreview,\n onToggleHtmlPreview: () => setTextHtmlPreview(prev => !prev),\n t,\n });\n }\n if (fileType === 'markdown') {\n return getMarkdownToolbarGroups({\n viewMode: markdownViewMode,\n onToggleViewMode: () => setMarkdownViewMode(prev => prev === 'preview' ? 'source' : 'preview'),\n t,\n });\n }\n return [];\n })();\n\n // 操作组:下载、关闭(通用,不属于任何 Renderer)\n const actionGroups: ToolbarGroup[] = [\n {\n items: [\n { type: 'button', icon: <Download className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('common.download'), action: handleDownload },\n ],\n },\n ...(showCloseButton ? [{\n items: [\n { type: 'button' as const, icon: <X className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('common.close'), action: onClose! },\n ],\n }] : []),\n ];\n\n const renderToolbarItems = (groups: ToolbarGroup[], dividerClass: string) =>\n groups.map((group, gi, arr) => (\n <React.Fragment key={gi}>\n {group.items.map((item, ii) =>\n item.type === 'button' ? (\n <ToolbarButton\n key={`${gi}-${ii}`}\n icon={item.icon}\n label={item.tooltip}\n onClick={item.action}\n disabled={item.disabled}\n />\n ) : (\n <span\n key={`${gi}-${ii}`}\n className=\"rfp-text-xs rfp-text-center rfp-font-medium rfp-tabular-nums rfp-text-fg-tertiary\"\n style={{ minWidth: item.minWidth || 'auto' }}\n >\n {item.content}\n </span>\n )\n )}\n {gi < arr.length - 1 && <div className={`rfp-w-px rfp-h-4 rfp-bg-divide ${dividerClass}`} />}\n </React.Fragment>\n ));\n\n return (\n <LocaleProvider locale={locale} messages={userMessages}>\n <ThemeProvider theme={resolvedTheme}>\n <div\n ref={rootRef}\n tabIndex={mode === 'embed' ? 0 : -1}\n data-theme={resolvedTheme}\n className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-flex-col rfp-overflow-hidden rfp-outline-none\"\n >\n {/* 顶部工具栏 - 全屏融合式 */}\n {!headless && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"rfp-flex-shrink-0 rfp-z-10 rfp-backdrop-blur-md rfp-border-b rfp-bg-surface-toolbar rfp-border-line\"\n style={{ paddingTop: 'env(safe-area-inset-top, 0px)' }}\n >\n {/* 第一行:文件名 + 分页 + 关闭/下载(移动端右侧)/ 全部按钮(桌面端) */}\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-3 md:rfp-px-5 rfp-py-1.5 md:rfp-py-2.5\">\n {/* 左侧:文件名 + 分页 */}\n <div className=\"rfp-flex rfp-items-center rfp-flex-1 rfp-min-w-0 rfp-mr-2 md:rfp-mr-3\">\n <h2 className=\"rfp-font-medium rfp-text-xs md:rfp-text-sm rfp-truncate rfp-text-fg-primary\">\n {currentFile.name}\n </h2>\n <span className=\"rfp-text-xs rfp-ml-2 rfp-flex-shrink-0 rfp-text-fg-muted\">\n {currentIndex + 1}/{normalizedFiles.length}\n </span>\n </div>\n\n {/* 移动端:仅显示下载+关闭 */}\n <div className=\"rfp-flex rfp-items-center rfp-gap-1 md:rfp-hidden rfp-flex-shrink-0\">\n {renderToolbarItems(actionGroups, 'rfp-mx-0.5')}\n </div>\n\n {/* 桌面端:所有工具按钮 */}\n <div className=\"rfp-hidden md:rfp-flex rfp-items-center rfp-gap-1 rfp-flex-shrink-0\">\n {renderToolbarItems(toolGroups, 'rfp-mx-1')}\n {toolGroups.length > 0 && <div className=\"rfp-w-px rfp-h-4 rfp-mx-1 rfp-bg-divide\" />}\n {renderToolbarItems(actionGroups, 'rfp-mx-1')}\n </div>\n </div>\n\n {/* 第二行:移动端工具按钮(image/pdf/epub) */}\n {toolGroups.length > 0 && (\n <div className=\"rfp-flex rfp-items-center rfp-gap-1 rfp-px-3 rfp-pb-1.5 rfp-overflow-x-auto scrollbar-hide md:rfp-hidden\">\n {renderToolbarItems(toolGroups, 'rfp-mx-0.5')}\n </div>\n )}\n </motion.div>\n )}\n\n {/* 内容区域 */}\n <div\n ref={contentRef}\n className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center rfp-overflow-auto\"\n onMouseMove={handleMouseMove}\n >\n {customRenderer ? (\n customRenderer.render(currentFile, customCtx)\n ) : (\n <Suspense fallback={<RendererLoading />}>\n {fileType === 'image' && (\n <ImageRenderer\n url={resolvedUrl}\n zoom={zoom}\n rotation={rotation}\n resetKey={imageResetKey}\n fileSize={currentFile.size}\n onZoomChange={handleZoomChange}\n onNaturalWidthChange={setContentNaturalWidth}\n onNaturalHeightChange={setContentNaturalHeight}\n />\n )}\n {fileType === 'pdf' && (\n <PdfRenderer\n url={resolvedUrl}\n zoom={zoom}\n currentPage={currentPage}\n onPageChange={setCurrentPage}\n onTotalPagesChange={setTotalPages}\n onPageWidthChange={setContentNaturalWidth}\n />\n )}\n {fileType === 'docx' && <DocxRenderer url={resolvedUrl} />}\n {fileType === 'xlsx' && <XlsxRenderer url={resolvedUrl} />}\n {fileType === 'pptx' && <PptxRenderer url={resolvedUrl} />}\n {fileType === 'msg' && <MsgRenderer url={resolvedUrl} />}\n {fileType === 'epub' && (\n <EpubRenderer\n ref={epubRef}\n url={resolvedUrl}\n onChapterChange={handleEpubChapterChange}\n onFullWidthChange={setEpubFullWidth}\n />\n )}\n {fileType === 'mobi' && (\n <MobiRenderer\n ref={mobiRef}\n url={resolvedUrl}\n onChapterChange={handleMobiChapterChange}\n onFullWidthChange={setMobiFullWidth}\n />\n )}\n {fileType === 'video' && <VideoRenderer url={resolvedUrl} />}\n {fileType === 'audio' && (\n <AudioRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'markdown' && <MarkdownRenderer url={resolvedUrl} viewMode={markdownViewMode} />}\n {fileType === 'json' && (\n <JsonRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'csv' && (\n <CsvRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'xml' && (\n <XmlRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'subtitle' && (\n <SubtitleRenderer url={resolvedUrl} fileName={currentFile.name} />\n )}\n {fileType === 'zip' && (\n zipNestingDepth >= MAX_ZIP_NESTING_DEPTH ? (\n <UnsupportedRenderer\n fileName={currentFile.name}\n fileType={currentFile.type}\n onDownload={handleDownload}\n />\n ) : (\n <ZipRenderer url={resolvedUrl} onStatsChange={handleZipStatsChange} nestingDepth={zipNestingDepth} />\n )\n )}\n {fileType === 'text' && (\n <TextRenderer\n url={resolvedUrl}\n fileName={currentFile.name}\n wordWrap={textWordWrap}\n htmlPreview={textHtmlPreview}\n />\n )}\n {fileType === 'font' && <FontRenderer url={resolvedUrl} />}\n {fileType === 'unsupported' && (\n <UnsupportedRenderer\n fileName={currentFile.name}\n fileType={currentFile.type}\n onDownload={handleDownload}\n />\n )}\n </Suspense>\n )}\n </div>\n\n {/* 左右导航箭头 - 自动隐藏 */}\n {!headless && normalizedFiles.length > 1 && (\n <>\n {currentIndex > 0 && (\n <motion.button\n initial={{ opacity: 0 }}\n animate={{ opacity: navVisible ? 1 : 0, x: navVisible ? 0 : -20 }}\n transition={{ duration: 0.2 }}\n onClick={() => onNavigate?.(currentIndex - 1)}\n onMouseEnter={() => setNavVisible(true)}\n style={{ pointerEvents: navVisible ? 'auto' : 'none' }}\n className=\"rfp-absolute rfp-z-20 rfp-left-2 md:rfp-left-4 rfp-top-1/2 -rfp-translate-y-1/2 rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-rounded-full rfp-backdrop-blur-xl rfp-border rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-shadow-2xl rfp-bg-surface-nav rfp-border-line hover:rfp-bg-surface-nav-hover rfp-text-fg-primary\"\n >\n <ChevronLeft className=\"rfp-w-5 rfp-h-5 md:rfp-w-6 md:rfp-h-6\" />\n </motion.button>\n )}\n\n {currentIndex < normalizedFiles.length - 1 && (\n <motion.button\n initial={{ opacity: 0 }}\n animate={{ opacity: navVisible ? 1 : 0, x: navVisible ? 0 : 20 }}\n transition={{ duration: 0.2 }}\n onClick={() => onNavigate?.(currentIndex + 1)}\n onMouseEnter={() => setNavVisible(true)}\n style={{ pointerEvents: navVisible ? 'auto' : 'none' }}\n className=\"rfp-absolute rfp-z-20 rfp-right-2 md:rfp-right-4 rfp-top-1/2 -rfp-translate-y-1/2 rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-rounded-full rfp-backdrop-blur-xl rfp-border rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-shadow-2xl rfp-bg-surface-nav rfp-border-line hover:rfp-bg-surface-nav-hover rfp-text-fg-primary\"\n >\n <ChevronRight className=\"rfp-w-5 rfp-h-5 md:rfp-w-6 md:rfp-h-6\" />\n </motion.button>\n )}\n </>\n )}\n </div>\n </ThemeProvider>\n </LocaleProvider>\n );\n};\n\n// 工具栏按钮组件\ninterface ToolbarButtonProps {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n}\n\nconst ToolbarButton: React.FC<ToolbarButtonProps> = ({ icon, label, onClick, disabled }) => {\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className={`rfp-relative rfp-group rfp-p-2 md:rfp-p-1.5 rfp-rounded-md rfp-transition-all rfp-select-none ${\n disabled\n ? 'rfp-text-fg-disabled rfp-cursor-not-allowed'\n : 'rfp-text-fg-primary hover:rfp-bg-surface-2 active:rfp-bg-surface-3'\n }`}\n >\n {icon}\n <span className=\"rfp-absolute rfp-left-1/2 -rfp-translate-x-1/2 rfp-top-full rfp-mt-1.5 rfp-px-2 rfp-py-1 rfp-text-xs rfp-rounded rfp-whitespace-nowrap rfp-pointer-events-none rfp-opacity-0 rfp-invisible group-hover:rfp-opacity-100 group-hover:rfp-visible rfp-transition-opacity rfp-duration-200 rfp-z-50 rfp-bg-fg-primary rfp-text-fg-inverse\">\n <span className=\"rfp-absolute rfp-left-1/2 -rfp-translate-x-1/2 -rfp-top-1 rfp-w-2 rfp-h-2 rfp-rotate-45 rfp-bg-fg-primary\" />\n <span className=\"rfp-relative\">{label}</span>\n </span>\n </button>\n );\n};\n","import { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { PreviewFileInput, CustomRenderer } from './types';\nimport { FilePreviewContent } from './FilePreviewContent';\nimport type { Locale, Messages, Theme, CustomRendererEventPayload, PreviewFile, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';\n\ninterface FilePreviewModalProps {\n files: PreviewFileInput[];\n currentIndex: number;\n isOpen: boolean;\n onClose: () => void;\n onNavigate?: (index: number) => void;\n customRenderers?: CustomRenderer[];\n /** 国际化语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义翻译字典 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n /** 无头模式:隐藏工具栏和导航箭头 */\n headless?: boolean;\n /** 主题模式,默认 'dark' */\n theme?: Theme;\n /** 自定义渲染器派发的事件出口 */\n onCustomEvent?: (event: CustomRendererEventPayload) => void;\n /** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */\n requestInit?: RequestInitFactory;\n /** 自定义请求处理器:完全接管库内 fetch */\n requestHandler?: RequestHandler;\n /** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */\n onDownload?: (file: PreviewFile) => void | Promise<void>;\n}\n\nexport const FilePreviewModal: React.FC<FilePreviewModalProps> = ({\n files,\n currentIndex,\n isOpen,\n onClose,\n onNavigate,\n customRenderers = [],\n locale,\n messages,\n headless,\n theme = 'dark',\n onCustomEvent,\n requestInit,\n requestHandler,\n shouldFetchAsBlob,\n onDownload,\n}) => {\n const [systemDark, setSystemDark] = useState(() =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : true,\n );\n\n useEffect(() => {\n if (theme !== 'auto') return;\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [theme]);\n\n const resolvedTheme = theme === 'auto' ? (systemDark ? 'dark' : 'light') : theme;\n\n // 锁定 body 滚动\n useEffect(() => {\n if (isOpen) {\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n\n document.body.style.overflow = 'hidden';\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n };\n }\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n const modalContent = (\n <div className=\"rfp-root\" data-theme={resolvedTheme}>\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"rfp-fixed rfp-inset-0 rfp-z-[9999] rfp-flex rfp-items-center rfp-justify-center rfp-backdrop-blur-md rfp-overflow-hidden rfp-bg-surface-overlay\"\n onClick={onClose}\n onWheel={(e) => e.stopPropagation()}\n >\n <div\n className=\"rfp-relative rfp-w-full rfp-h-full\"\n onClick={(e) => e.stopPropagation()}\n >\n <FilePreviewContent\n mode=\"modal\"\n files={files}\n currentIndex={currentIndex}\n onClose={onClose}\n onNavigate={onNavigate}\n customRenderers={customRenderers}\n locale={locale}\n messages={messages}\n headless={headless}\n theme={theme}\n onCustomEvent={onCustomEvent}\n requestInit={requestInit}\n requestHandler={requestHandler}\n shouldFetchAsBlob={shouldFetchAsBlob}\n onDownload={onDownload}\n />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n\n return createPortal(modalContent, document.body);\n};\n","import { useEffect, useState } from 'react';\nimport { PreviewFileInput, CustomRenderer } from './types';\nimport { FilePreviewContent } from './FilePreviewContent';\nimport type { Locale, Messages, Theme, CustomRendererEventPayload, PreviewFile, RequestHandler, RequestInitFactory, ShouldFetchAsBlob } from '@eternalheart/file-preview-core';\n\ninterface FilePreviewEmbedProps {\n files: PreviewFileInput[];\n currentIndex?: number;\n onNavigate?: (index: number) => void;\n customRenderers?: CustomRenderer[];\n /** 宽度,默认 100% 填充父容器 */\n width?: number | string;\n /** 高度,默认 100% 填充父容器 */\n height?: number | string;\n className?: string;\n style?: React.CSSProperties;\n /** 国际化语言,默认 'zh-CN' */\n locale?: Locale;\n /** 用户自定义翻译字典 */\n messages?: Partial<Record<Locale, Partial<Messages>>>;\n /** 无头模式:隐藏工具栏和导航箭头 */\n headless?: boolean;\n /** 主题模式,默认 'dark' */\n theme?: Theme;\n /** 自定义渲染器派发的事件出口 */\n onCustomEvent?: (event: CustomRendererEventPayload) => void;\n /** 自定义 RequestInit(或工厂函数):注入 Authorization 等鉴权头 */\n requestInit?: RequestInitFactory;\n /** 自定义请求处理器:完全接管库内 fetch */\n requestHandler?: RequestHandler;\n /** 返回 true 时,对应文件先 fetcher→blob URL 后喂给 image/video/audio/pdf 等 renderer */\n shouldFetchAsBlob?: ShouldFetchAsBlob;\n /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */\n onDownload?: (file: PreviewFile) => void | Promise<void>;\n}\n\nexport const FilePreviewEmbed: React.FC<FilePreviewEmbedProps> = ({\n files,\n currentIndex = 0,\n onNavigate,\n customRenderers = [],\n width = '100%',\n height = '100%',\n className,\n style,\n locale,\n messages,\n headless,\n theme = 'dark',\n onCustomEvent,\n requestInit,\n requestHandler,\n shouldFetchAsBlob,\n onDownload,\n}) => {\n const [systemDark, setSystemDark] = useState(() =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n : true,\n );\n\n useEffect(() => {\n if (theme !== 'auto') return;\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n const handler = (e: MediaQueryListEvent) => setSystemDark(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [theme]);\n\n const resolvedTheme = theme === 'auto' ? (systemDark ? 'dark' : 'light') : theme;\n\n return (\n <div\n className={`rfp-root ${className ?? ''}`}\n style={{ width, height, ...style }}\n data-theme={resolvedTheme}\n >\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-overflow-hidden rfp-bg-surface-overlay\">\n <FilePreviewContent\n mode=\"embed\"\n files={files}\n currentIndex={currentIndex}\n onNavigate={onNavigate}\n customRenderers={customRenderers}\n locale={locale}\n messages={messages}\n headless={headless}\n theme={theme}\n onCustomEvent={onCustomEvent}\n requestInit={requestInit}\n requestHandler={requestHandler}\n shouldFetchAsBlob={shouldFetchAsBlob}\n onDownload={onDownload}\n />\n </div>\n </div>\n );\n};\n","// @ts-ignore - pdfjs-dist 类型路径\nimport * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs';\nimport { configurePdfWorker } from '@eternalheart/file-preview-core';\n\n/**\n * PDF.js Worker 配置选项\n */\nexport interface PdfConfigOptions {\n /**\n * PDF.js worker 文件路径\n * 默认使用 CDN: `https://unpkg.com/pdfjs-dist@${version}/build/pdf.worker.min.mjs`\n */\n workerSrc?: string;\n\n /**\n * CMap 文件目录路径\n * 默认使用 CDN: `https://unpkg.com/pdfjs-dist@${version}/cmaps/`\n */\n cMapUrl?: string;\n\n /**\n * 是否使用压缩的 CMap 文件\n * 默认: true\n */\n cMapPacked?: boolean;\n}\n\n/**\n * 配置 PDF.js\n *\n * @example\n * ```ts\n * // 使用本地静态文件(推荐用于生产环境)\n * configurePdfjs({\n * workerSrc: '/pdfjs/pdf.worker.min.mjs',\n * cMapUrl: '/pdfjs/cmaps/',\n * cMapPacked: true\n * });\n * ```\n *\n * @example\n * ```ts\n * // 使用 CDN(默认配置)\n * configurePdfjs(); // 自动使用 unpkg CDN\n * ```\n */\nexport function configurePdfjs(options?: PdfConfigOptions) {\n configurePdfWorker(pdfjsLib, options);\n}\n\nexport { pdfjsLib as pdfjs };\n","// 导入样式\nimport './index.css';\n\n// 导入版本号\nimport packageJson from '../package.json';\n\n// 导出版本号\nexport const VERSION = packageJson.version;\n\n// 导出主组件\nexport { FilePreviewModal } from './FilePreviewModal';\nexport { FilePreviewEmbed } from './FilePreviewEmbed';\nexport { FilePreviewContent } from './FilePreviewContent';\n\n// 导出类型定义\nexport type {\n PreviewFile,\n PreviewFileLink,\n PreviewFileInput,\n FileType,\n ToolbarAction,\n PreviewState,\n CustomRenderer,\n CustomRendererContext,\n CustomRendererEventPayload,\n} from './types';\n\n// 导出工具函数和常量\nexport { normalizeFile, normalizeFiles } from './utils/fileNormalizer';\nexport { SUPPORTED_FILE_TYPES } from '@eternalheart/file-preview-core';\n\n// 导出 PDF.js 配置函数和类型\nexport { configurePdfjs, pdfjs } from './utils/pdfConfig';\nexport type { PdfConfigOptions } from './utils/pdfConfig';\n\n// 导出 i18n 国际化\nexport { LocaleProvider, useTranslator, useLocale } from './i18n/LocaleContext';\nexport type { LocaleProviderProps, LocaleContextValue } from './i18n/LocaleContext';\nexport type {\n Locale,\n Messages,\n MessageKey,\n Translator,\n TranslateParams,\n CreateTranslatorOptions,\n Theme,\n} from '@eternalheart/file-preview-core';\n\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { motion } from 'framer-motion';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ninterface ImageRendererProps {\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n onZoomChange?: (zoom: number) => void;\n onNaturalWidthChange?: (width: number) => void;\n onNaturalHeightChange?: (height: number) => void;\n}\n\nexport const ImageRenderer: React.FC<ImageRendererProps> = ({\n url,\n zoom,\n rotation,\n resetKey,\n fileSize,\n onZoomChange,\n onNaturalWidthChange,\n onNaturalHeightChange\n}) => {\n const t = useTranslator();\n const [loaded, setLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [internalZoom, setInternalZoom] = useState(1);\n const [naturalSize, setNaturalSize] = useState({ width: 0, height: 0 });\n const imgRef = useRef<HTMLImageElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setLoaded(false);\n setError(null);\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n }, [url]);\n\n // 当外部 zoom 改变时,同步内部 zoom\n useEffect(() => {\n setInternalZoom(zoom);\n }, [zoom]);\n\n // 适应窗口/原始尺寸等操作时重置位置居中\n useEffect(() => {\n if (resetKey !== undefined) {\n setPosition({ x: 0, y: 0 });\n }\n }, [resetKey]);\n\n const handleLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(true);\n const img = e.currentTarget;\n setNaturalSize({ width: img.naturalWidth, height: img.naturalHeight });\n onNaturalWidthChange?.(img.naturalWidth);\n onNaturalHeightChange?.(img.naturalHeight);\n };\n\n // 边界限制:确保图片至少有一部分可见\n const clampPosition = useCallback((pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.current;\n if (!container || naturalSize.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.width * currentZoom;\n const imgH = naturalSize.height * currentZoom;\n\n // 至少保留 margin px 的图片在视口内\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n }, [naturalSize]);\n\n const handleError = () => {\n setError(t('image.load_failed'));\n setLoaded(true);\n };\n\n // 双击复原:居中 + 缩放100%\n const handleDoubleClick = () => {\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n onZoomChange?.(1);\n };\n\n // 鼠标滚轮缩放 —— 以鼠标位置为缩放原点\n // 使用原生事件 + passive: false,确保 preventDefault 生效,\n // 避免滚轮事件冒泡触发外层(如嵌入模式下的页面滚动)\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n\n setInternalZoom(prev => {\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n setPosition(pos => clampPosition({\n x: mouseX - scale * (mouseX - pos.x),\n y: mouseY - scale * (mouseY - pos.y),\n }, newZoom));\n\n onZoomChange?.(newZoom);\n return newZoom;\n });\n };\n\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n return () => container.removeEventListener('wheel', handleWheelNative);\n }, [onZoomChange, clampPosition]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (e.button !== 0) return;\n setIsDragging(true);\n setDragStart({\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n });\n }, [position]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDragging) return;\n setPosition(clampPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n }, internalZoom));\n }, [isDragging, dragStart, internalZoom, clampPosition]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-relative rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-overflow-hidden\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {!loaded && !error && (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {error && (\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n <motion.img\n ref={imgRef}\n src={url}\n alt=\"Preview\"\n className={`rfp-max-w-none rfp-select-none ${!loaded ? 'rfp-hidden' : ''}`}\n style={{\n transform: `translate(${position.x}px, ${position.y}px) scale(${internalZoom}) rotate(${rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging ? 'none' : 'transform 0.3s ease-out',\n }}\n onLoad={handleLoad}\n onError={handleError}\n onDoubleClick={handleDoubleClick}\n initial={{ opacity: 0 }}\n animate={{ opacity: loaded ? 1 : 0 }}\n transition={{ duration: 0.3 }}\n draggable={false}\n />\n\n {/* 右下角分辨率 */}\n {loaded && !error && naturalSize.width > 0 && (\n <div className=\"rfp-absolute rfp-bottom-2 rfp-right-3 rfp-text-[10px] rfp-text-fg-disabled hover:rfp-text-fg-secondary rfp-transition-colors rfp-pointer-events-auto rfp-select-none rfp-cursor-default\">\n {naturalSize.width} × {naturalSize.height}{fileSize != null && ` · ${fileSize < 1024 ? `${fileSize} B` : fileSize < 1024 * 1024 ? `${(fileSize / 1024).toFixed(1)} KB` : `${(fileSize / (1024 * 1024)).toFixed(1)} MB`}`}\n </div>\n )}\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { useTranslator } from '../../i18n/LocaleContext';\n// @ts-ignore - pdfjs-dist 类型路径\nimport * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs';\n\ninterface PdfPageProxy {\n getViewport(opts: { scale: number }): { width: number; height: number };\n render(opts: { canvasContext: CanvasRenderingContext2D; viewport: { width: number; height: number } }): {\n promise: Promise<void>;\n cancel(): void;\n };\n}\n\ninterface PdfDocumentProxy {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfPageProxy>;\n destroy(): void;\n}\n\ninterface PageState {\n element: HTMLDivElement;\n rendered: boolean;\n rendering: boolean;\n renderTask: { cancel(): void } | null;\n}\n\ninterface PdfRendererProps {\n url: string;\n zoom: number;\n currentPage: number;\n onPageChange: (page: number) => void;\n onTotalPagesChange: (total: number) => void;\n onPageWidthChange?: (width: number) => void;\n}\n\nexport const PdfRenderer: React.FC<PdfRendererProps> = ({\n url,\n zoom,\n currentPage,\n onPageChange,\n onTotalPagesChange,\n onPageWidthChange,\n}) => {\n const t = useTranslator();\n const [numPages, setNumPages] = useState<number>(0);\n const [error, setError] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const containerRef = useRef<HTMLDivElement>(null);\n const pdfDocRef = useRef<PdfDocumentProxy | null>(null);\n const pageStatesRef = useRef<Map<number, PageState>>(new Map());\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n // 渲染单个页面\n const renderPage = useCallback(async (pageNumber: number, scale: number) => {\n if (!pdfDocRef.current) return;\n const state = pageStatesRef.current.get(pageNumber);\n if (!state || state.rendering) return;\n\n state.rendering = true;\n\n try {\n const page = await pdfDocRef.current.getPage(pageNumber);\n const viewport = page.getViewport({ scale });\n\n const canvas = document.createElement('canvas');\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n canvas.style.maxWidth = '100%';\n canvas.style.height = 'auto';\n canvas.style.borderRadius = '0';\n canvas.style.display = 'block';\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const renderTask = page.render({ canvasContext: ctx, viewport });\n state.renderTask = renderTask;\n await renderTask.promise;\n\n // 上报第一页原始宽度\n if (pageNumber === 1 && onPageWidthChange) {\n const baseViewport = page.getViewport({ scale: 1 });\n onPageWidthChange(baseViewport.width);\n }\n\n state.element.innerHTML = '';\n state.element.appendChild(canvas);\n\n // 页码标签\n const label = document.createElement('div');\n label.textContent = String(pageNumber);\n label.className = 'rfp-absolute rfp-top-2 rfp-right-2 rfp-bg-surface-nav-hover rfp-backdrop-blur-sm rfp-text-fg-primary rfp-text-xs rfp-px-3 rfp-py-1 rfp-rounded-full';\n state.element.appendChild(label);\n\n state.rendered = true;\n } catch (err: any) {\n if (err?.name !== 'RenderingCancelledException') {\n console.error(`渲染页面 ${pageNumber} 失败:`, err);\n }\n } finally {\n state.rendering = false;\n state.renderTask = null;\n }\n }, [onPageWidthChange]);\n\n // 清理页面 canvas\n const clearPageCanvas = useCallback((pageNumber: number) => {\n const state = pageStatesRef.current.get(pageNumber);\n if (!state) return;\n\n // 取消正在进行的渲染\n if (state.renderTask) {\n state.renderTask.cancel();\n state.renderTask = null;\n }\n\n // 清理 canvas\n const canvas = state.element.querySelector('canvas');\n if (canvas) {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n canvas.remove();\n }\n\n state.element.innerHTML = '';\n state.rendered = false;\n state.rendering = false;\n }, []);\n\n // 初始化页面占位符\n const initPagePlaceholders = useCallback(() => {\n if (!pdfDocRef.current || !containerRef.current) return;\n\n const wrapper = containerRef.current.querySelector('.pdf-pages') as HTMLDivElement | null;\n if (!wrapper) return;\n\n wrapper.innerHTML = '';\n pageStatesRef.current.clear();\n\n for (let i = 1; i <= numPages; i++) {\n const pageDiv = document.createElement('div');\n pageDiv.className = 'rfp-relative rfp-flex rfp-justify-center rfp-min-h-[800px]';\n pageDiv.setAttribute('data-page-number', String(i));\n wrapper.appendChild(pageDiv);\n\n pageStatesRef.current.set(i, {\n element: pageDiv,\n rendered: false,\n rendering: false,\n renderTask: null,\n });\n\n // 观察页面元素\n if (observerRef.current) {\n observerRef.current.observe(pageDiv);\n }\n }\n }, [numPages]);\n\n // 加载 PDF 文档\n const loadPdf = useCallback(async () => {\n setError(null);\n setIsLoading(true);\n setNumPages(0);\n\n if (pdfDocRef.current) {\n try {\n pdfDocRef.current.destroy();\n } catch {\n // ignore\n }\n pdfDocRef.current = null;\n }\n\n try {\n const loadingTask = pdfjsLib.getDocument({ url });\n pdfDocRef.current = (await loadingTask.promise) as PdfDocumentProxy;\n const total = pdfDocRef.current.numPages;\n\n setNumPages(total);\n onTotalPagesChange(total);\n onPageChange(1);\n setIsLoading(false);\n } catch (err) {\n console.error('PDF 加载错误:', err);\n setError(t('pdf.load_failed'));\n setIsLoading(false);\n }\n }, [url, onTotalPagesChange, onPageChange, t]);\n\n // 滚动处理\n const handleScroll = useCallback(() => {\n if (!containerRef.current || pageStatesRef.current.size === 0) return;\n\n const container = containerRef.current;\n const scrollTop = container.scrollTop;\n const containerHeight = container.clientHeight;\n const scrollCenter = scrollTop + containerHeight / 2;\n\n let currentVisiblePage = 1;\n let minDistance = Infinity;\n\n pageStatesRef.current.forEach((state, pageNumber) => {\n const rect = state.element.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const pageCenter = rect.top - containerRect.top + rect.height / 2 + scrollTop;\n const distance = Math.abs(pageCenter - scrollCenter);\n\n if (distance < minDistance) {\n minDistance = distance;\n currentVisiblePage = pageNumber;\n }\n });\n\n if (currentVisiblePage !== currentPage) {\n onPageChange(currentVisiblePage);\n }\n }, [currentPage, onPageChange]);\n\n // 初始化 IntersectionObserver\n useEffect(() => {\n observerRef.current = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n const pageNumber = Number(entry.target.getAttribute('data-page-number'));\n if (!pageNumber) return;\n\n if (entry.isIntersecting) {\n // 页面进入视口,渲染\n renderPage(pageNumber, zoom);\n } else {\n // 页面离开视口,清理\n const state = pageStatesRef.current.get(pageNumber);\n if (state && state.rendered) {\n clearPageCanvas(pageNumber);\n }\n }\n });\n },\n {\n root: containerRef.current,\n rootMargin: '500px 0px',\n threshold: 0,\n }\n );\n\n return () => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n };\n }, [zoom, renderPage, clearPageCanvas]);\n\n // 监听 URL 变化\n useEffect(() => {\n loadPdf();\n }, [loadPdf]);\n\n // 监听 numPages 变化,初始化占位符\n useEffect(() => {\n if (numPages > 0) {\n // 等待 DOM 更新后初始化占位符\n setTimeout(() => {\n initPagePlaceholders();\n }, 0);\n }\n }, [numPages, initPagePlaceholders]);\n\n // 监听 zoom 变化(防抖)\n useEffect(() => {\n const timer = setTimeout(() => {\n // 清理所有已渲染页面\n pageStatesRef.current.forEach((state, pageNumber) => {\n if (state.rendered) {\n clearPageCanvas(pageNumber);\n }\n });\n\n // 触发重新渲染\n if (observerRef.current && containerRef.current) {\n pageStatesRef.current.forEach((state) => {\n observerRef.current?.unobserve(state.element);\n observerRef.current?.observe(state.element);\n });\n }\n }, 150);\n\n return () => clearTimeout(timer);\n }, [zoom, clearPageCanvas]);\n\n // 监听滚动事件\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener('scroll', handleScroll);\n return () => container.removeEventListener('scroll', handleScroll);\n }, [handleScroll]);\n\n // 清理\n useEffect(() => {\n return () => {\n // 清理所有渲染任务\n pageStatesRef.current.forEach((state) => {\n if (state.renderTask) {\n state.renderTask.cancel();\n }\n });\n pageStatesRef.current.clear();\n\n if (pdfDocRef.current) {\n try {\n pdfDocRef.current.destroy();\n } catch {\n // ignore\n }\n pdfDocRef.current = null;\n }\n };\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full rfp-overflow-auto rfp-py-4 md:rfp-py-8 rfp-px-2 md:rfp-px-4\"\n >\n {error && (\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n {!error && isLoading && (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-min-h-screen\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {!error && !isLoading && (\n <div className=\"pdf-pages rfp-flex rfp-flex-col rfp-gap-4\" />\n )}\n\n {/* 底部页码指示器 */}\n {numPages > 0 && (\n <div className=\"rfp-sticky rfp-bottom-2 md:rfp-bottom-4 rfp-mt-4 md:rfp-mt-8 rfp-bg-surface-nav-hover rfp-backdrop-blur-xl rfp-text-fg-primary rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-rounded-full rfp-text-xs md:rfp-text-sm rfp-font-medium rfp-shadow-2xl rfp-border rfp-border-line-weak\">\n 第 {currentPage} 页 / 共 {numPages} 页\n </div>\n )}\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport mammoth from 'mammoth';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface DocxRendererProps {\n url: string;\n}\n\n// A4 page dimensions (96dpi)\nconst PAGE_HEIGHT = 1123;\nconst PAGE_PADDING_Y = 60;\nconst PAGE_PADDING_X = 50;\nconst PAGE_CONTENT_HEIGHT = PAGE_HEIGHT - PAGE_PADDING_Y * 2;\nconst PAGE_GAP = 24;\n\nconst contentStyle: React.CSSProperties = {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n lineHeight: '1.8',\n color: '#333',\n};\n\nexport const DocxRenderer: React.FC<DocxRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [html, setHtml] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [pages, setPages] = useState<string[]>([]);\n const measureRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const loadDocx = async () => {\n setLoading(true);\n setError(null);\n setHtml('');\n\n try {\n const response = await fetcher(url);\n if (!response.ok) {\n throw new Error('文件加载失败');\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const result = await mammoth.convertToHtml({ arrayBuffer });\n setHtml(result.value);\n } catch (err) {\n console.error('Docx 解析错误:', err);\n setError(t('docx.parse_failed'));\n } finally {\n setLoading(false);\n }\n };\n\n loadDocx();\n }, [url, fetcher, t]);\n\n const paginate = useCallback(() => {\n const container = measureRef.current;\n if (!container || !html) return;\n\n const children = Array.from(container.children) as HTMLElement[];\n if (children.length === 0) {\n setPages([html]);\n return;\n }\n\n const result: string[][] = [[]];\n let currentPageUsed = 0;\n\n for (const child of children) {\n const h = child.offsetHeight;\n\n // If adding this block would exceed page content area and page isn't empty,\n // start a new page\n if (currentPageUsed > 0 && currentPageUsed + h > PAGE_CONTENT_HEIGHT) {\n result.push([]);\n currentPageUsed = 0;\n }\n\n result[result.length - 1].push(child.outerHTML);\n currentPageUsed += h;\n }\n\n // At least one page\n if (result.length === 0) result.push([]);\n\n setPages(result.map(blocks => blocks.join('')));\n }, [html]);\n\n useEffect(() => {\n if (!html || !measureRef.current) return;\n requestAnimationFrame(() => {\n paginate();\n });\n }, [html, paginate]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n className=\"rfp-w-full rfp-h-full rfp-overflow-auto\"\n style={{ background: 'rgba(0, 0, 0, 0.15)' }}\n >\n {/* Hidden measurement div — same width as page content area */}\n <div\n ref={measureRef}\n dangerouslySetInnerHTML={{ __html: html }}\n style={{\n ...contentStyle,\n position: 'absolute',\n visibility: 'hidden',\n width: `${794 - PAGE_PADDING_X * 2}px`,\n pointerEvents: 'none',\n }}\n />\n\n {/* Visible pages */}\n <div\n className=\"rfp-py-6 md:rfp-py-10 rfp-flex rfp-flex-col rfp-items-center\"\n style={{ gap: `${PAGE_GAP}px` }}\n >\n {(pages.length > 0 ? pages : ['']).map((pageHtml, i) => (\n <div\n key={i}\n style={{\n width: '100%',\n maxWidth: '794px',\n minHeight: `${PAGE_HEIGHT}px`,\n background: 'white',\n boxShadow: '0 2px 12px rgba(0, 0, 0, 0.15)',\n flexShrink: 0,\n padding: `${PAGE_PADDING_Y}px ${PAGE_PADDING_X}px`,\n }}\n >\n <div\n dangerouslySetInnerHTML={{ __html: pageHtml }}\n style={contentStyle}\n />\n </div>\n ))}\n </div>\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { FileSpreadsheet } from 'lucide-react';\nimport ExcelJS from 'exceljs';\nimport Spreadsheet from 'x-data-spreadsheet';\nimport 'x-data-spreadsheet/dist/xspreadsheet.css';\nimport { convertWorkbookToSpreadsheetData } from '../../utils/excelDataConverter';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface XlsxRendererProps {\n url: string;\n}\n\nexport const XlsxRenderer: React.FC<XlsxRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const spreadsheetRef = useRef<Spreadsheet | null>(null);\n const sheetDataRef = useRef<Record<string, unknown>[] | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 800, height: 600 };\n const rawWidth = containerRef.current.clientWidth;\n const rawHeight = containerRef.current.clientHeight;\n const width = rawWidth > 100 ? rawWidth : 800;\n const height = rawHeight > 100 ? rawHeight : 600;\n return { width, height };\n }, []);\n\n const mountSpreadsheet = useCallback(() => {\n if (!containerRef.current || !sheetDataRef.current) return;\n\n // 清空容器\n containerRef.current.innerHTML = '';\n spreadsheetRef.current = null;\n\n const { width, height } = calculateDimensions();\n const isMobile = width < 640;\n\n const s = new Spreadsheet(containerRef.current, {\n mode: 'read',\n showToolbar: false,\n showContextmenu: false,\n showGrid: true,\n row: {\n len: 100,\n height: 25,\n },\n col: {\n len: 26,\n width: isMobile ? 80 : 100,\n indexWidth: isMobile ? 40 : 60,\n minWidth: isMobile ? 40 : 60,\n },\n view: {\n height: () => height,\n width: () => width,\n },\n });\n\n s.loadData(sheetDataRef.current as unknown as Record<string, unknown>);\n spreadsheetRef.current = s;\n }, [calculateDimensions]);\n\n // 监听容器尺寸变化\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensionsRef.current = newDimensions;\n\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (sheetDataRef.current) {\n mountSpreadsheet();\n }\n }, 500);\n };\n\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, mountSpreadsheet]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadExcel = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await fetcher(url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(t('xlsx.not_found'));\n } else if (response.status === 403) {\n throw new Error('无权限访问此文件');\n } else {\n throw new Error(`文件加载失败 (${response.status})`);\n }\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error('文件为空');\n }\n\n // 使用 exceljs 解析\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(arrayBuffer);\n\n // 转换为 x-data-spreadsheet 数据格式\n const sheetData = convertWorkbookToSpreadsheetData(workbook);\n\n if (!isMounted) return;\n\n sheetDataRef.current = sheetData as unknown as Record<string, unknown>[];\n\n // 挂载 x-data-spreadsheet\n mountSpreadsheet();\n\n setLoading(false);\n } catch (err) {\n if (isMounted) {\n console.error('Excel 解析错误:', err);\n let errorMsg = t('xlsx.parse_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n }\n setError(errorMsg);\n setLoading(false);\n }\n }\n };\n\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n loadExcel();\n });\n }, 100);\n\n return () => {\n isMounted = false;\n clearTimeout(timer);\n sheetDataRef.current = null;\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n spreadsheetRef.current = null;\n };\n }, [url, mountSpreadsheet]);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {/* 加载状态 */}\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('xlsx.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 错误状态 */}\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <div className=\"rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-green-500 rfp-via-emerald-500 rfp-to-teal-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl\">\n <FileSpreadsheet className=\"rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary\" />\n </div>\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium\">{t('xlsx.load_failed')}</p>\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6\">\n {error}\n </p>\n <a\n href={url}\n download\n className=\"rfp-inline-flex rfp-items-center rfp-gap-2 rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-bg-gradient-to-r rfp-from-purple-500 rfp-to-pink-500 rfp-text-fg-primary rfp-text-sm md:rfp-text-base rfp-rounded-lg md:rfp-rounded-xl hover:rfp-scale-105 rfp-transition-all rfp-shadow-lg\"\n >\n <svg className=\"rfp-w-4 rfp-h-4 md:rfp-w-5 md:rfp-h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n {t('common.download')}\n </a>\n <p className=\"rfp-text-xs rfp-text-fg-muted rfp-mt-3 md:rfp-mt-4\">\n 提示:可以使用 Microsoft Excel 或 WPS 打开\n </p>\n </div>\n </div>\n )}\n\n {/* Spreadsheet 容器 */}\n {!error && (\n <div\n ref={containerRef}\n className=\"xlsx-spreadsheet-container rfp-w-full rfp-h-full\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { Presentation } from 'lucide-react';\nimport { init } from 'pptx-preview';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface PptxRendererProps {\n url: string;\n /** 是否平铺展示所有页面,默认 true */\n tiled?: boolean;\n}\n\nexport const PptxRenderer: React.FC<PptxRendererProps> = ({ url, tiled = true }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [slideCount, setSlideCount] = useState(0);\n const containerRef = useRef<HTMLDivElement>(null);\n const previewerRef = useRef<ReturnType<typeof init> | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const arrayBufferRef = useRef<ArrayBuffer | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n // 计算容器尺寸,带回退逻辑\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 960, height: 540 };\n const rawWidth = containerRef.current.clientWidth;\n const parentWidth = containerRef.current.parentElement?.clientWidth || 0;\n // 如果容器宽度太小,回退到父容器宽度或默认最小值\n const containerWidth = rawWidth > 100 ? rawWidth : (parentWidth > 100 ? parentWidth : 300);\n // 16:9 比例\n const height = Math.floor(containerWidth * 9 / 16);\n return { width: containerWidth, height };\n }, []);\n\n // 重新初始化预览器\n const reinitializePreviewer = useCallback(async () => {\n if (!containerRef.current || !arrayBufferRef.current || slideCount === 0) return;\n\n try {\n // 销毁旧的预览器\n if (previewerRef.current) {\n try {\n previewerRef.current.destroy();\n } catch {\n // 忽略销毁错误\n }\n }\n\n // 清空容器\n containerRef.current.innerHTML = '';\n\n // 获取当前容器尺寸\n const currentDimensions = calculateDimensions();\n\n // 初始化新的预览器,平铺模式下高度按页数计算\n const previewer = init(containerRef.current, {\n width: currentDimensions.width,\n height: tiled ? currentDimensions.height * slideCount : currentDimensions.height,\n mode: tiled ? 'list' : 'slide',\n });\n previewerRef.current = previewer;\n\n // 重新预览\n await previewer.preview(arrayBufferRef.current);\n } catch {\n // 重新初始化失败,静默处理\n }\n }, [calculateDimensions, tiled, slideCount]);\n\n // 监听容器尺寸变化\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n // 跳过初始渲染时的尺寸检查\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n\n // 检查尺寸是否真正变化(至少变化10px才触发)\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) {\n return;\n }\n\n // 更新最后的尺寸\n lastDimensionsRef.current = newDimensions;\n\n // 清除之前的定时器\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // 防抖:800ms 后重新初始化预览器\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (previewerRef.current && arrayBufferRef.current) {\n reinitializePreviewer();\n }\n }, 800);\n };\n\n // 创建 ResizeObserver\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n // 开始观察容器\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, reinitializePreviewer]);\n\n useEffect(() => {\n let isMounted = true;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const loadPptx = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n // 设置30秒超时\n timeoutId = setTimeout(() => {\n if (isMounted) {\n setError(t('pptx.timeout'));\n setLoading(false);\n }\n }, 30000);\n\n try {\n // 获取文件,处理 CORS 和重定向\n const response = await fetcher(url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(t('pptx.not_found'));\n } else if (response.status === 403) {\n throw new Error('无权限访问此文件');\n } else if (response.status >= 500) {\n throw new Error('服务器错误,请稍后重试');\n } else {\n throw new Error(`文件加载失败 (${response.status})`);\n }\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n // 验证文件大小\n if (arrayBuffer.byteLength === 0) {\n throw new Error('文件为空');\n }\n\n arrayBufferRef.current = arrayBuffer;\n\n if (!isMounted) return;\n\n // 步骤 1: 创建隐藏容器,预处理获取 slideCount\n const hiddenContainer = document.createElement('div');\n hiddenContainer.style.cssText = 'position:absolute;left:-9999px;top:-9999px;visibility:hidden';\n document.body.appendChild(hiddenContainer);\n\n try {\n // 在隐藏容器中初始化临时预览器获取页数\n const tempPreviewer = init(hiddenContainer, {\n width: 100,\n height: 100,\n mode: 'slide',\n });\n\n try {\n await tempPreviewer.preview(arrayBuffer);\n } catch {\n throw new Error(t('pptx.invalid_format'));\n }\n\n const count = tempPreviewer.slideCount;\n\n if (!count || count === 0) {\n throw new Error(t('pptx.no_pages'));\n }\n\n // 销毁临时预览器\n tempPreviewer.destroy();\n\n if (!isMounted) return;\n\n // 保存 slideCount\n setSlideCount(count);\n\n // 步骤 2: 清空真实容器并初始化\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n\n const currentDimensions = calculateDimensions();\n\n // 步骤 3: 初始化真实预览器,平铺模式下使用正确的总高度\n const previewer = init(containerRef.current, {\n width: currentDimensions.width,\n height: tiled ? currentDimensions.height * count : currentDimensions.height,\n mode: tiled ? 'list' : 'slide',\n });\n previewerRef.current = previewer;\n\n // 步骤 4: 预览 PPTX\n await previewer.preview(arrayBuffer);\n\n // 清除超时定时器\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n if (isMounted) {\n setLoading(false);\n }\n } finally {\n // 移除隐藏容器\n if (document.body.contains(hiddenContainer)) {\n document.body.removeChild(hiddenContainer);\n }\n }\n } catch (err) {\n // 清除超时定时器\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n if (isMounted) {\n let errorMsg = t('pptx.parse_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n } else if (typeof err === 'string') {\n errorMsg = err;\n }\n setError(errorMsg);\n setLoading(false);\n }\n }\n };\n\n // 延迟执行,使用 requestAnimationFrame 确保 DOM 已准备好\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n loadPptx();\n });\n });\n }, 150);\n\n // 清理函数\n return () => {\n isMounted = false;\n clearTimeout(timer);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n arrayBufferRef.current = null;\n setSlideCount(0);\n if (previewerRef.current) {\n try {\n previewerRef.current.destroy();\n } catch {\n // 忽略销毁错误\n }\n }\n previewerRef.current = null;\n };\n }, [url, calculateDimensions, tiled]);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {/* 加载状态 - 绝对定位覆盖 */}\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('pptx.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 错误状态 - 绝对定位覆盖 */}\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <div className=\"rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-orange-500 rfp-via-red-500 rfp-to-pink-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl\">\n <Presentation className=\"rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary\" />\n </div>\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium\">{t('pptx.load_failed')}</p>\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6\">\n {error}\n </p>\n <a\n href={url}\n download\n className=\"rfp-inline-flex rfp-items-center rfp-gap-2 rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-bg-gradient-to-r rfp-from-purple-500 rfp-to-pink-500 rfp-text-fg-primary rfp-text-sm md:rfp-text-base rfp-rounded-lg md:rfp-rounded-xl hover:rfp-scale-105 rfp-transition-all rfp-shadow-lg\"\n >\n <svg className=\"rfp-w-4 rfp-h-4 md:rfp-w-5 md:rfp-h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n </svg>\n {t('common.download')}\n </a>\n <p className=\"rfp-text-xs rfp-text-fg-muted rfp-mt-3 md:rfp-mt-4\">\n 提示:可以使用 Microsoft PowerPoint 或 WPS 打开\n </p>\n </div>\n </div>\n )}\n\n {/* PPT 容器 - 仅在非错误状态下渲染 */}\n {!error && (\n <div\n ref={containerRef}\n className=\"pptx-wrapper rfp-w-full rfp-max-w-full md:rfp-max-w-6xl\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n};\n","import { useState, useEffect } from 'react';\nimport MsgReader from '@kenjiuno/msgreader';\nimport type { FieldsData } from '@kenjiuno/msgreader';\nimport { User, Users, Paperclip, Calendar, Mail, Tag, Clock, Hash } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface MsgRendererProps {\n url: string;\n}\n\nfunction formatRecipients(recipients: FieldsData[] | undefined, type: 'to' | 'cc' | 'bcc'): string {\n if (!recipients) return '';\n return recipients\n .filter((r) => r.recipType === type)\n .map((r) => {\n const name = r.name || '';\n const email = r.smtpAddress || r.email || '';\n if (name && email && name !== email) {\n return `${name} <${email}>`;\n }\n return name || email;\n })\n .filter(Boolean)\n .join('; ');\n}\n\nfunction formatDate(dateStr: string | undefined): string {\n if (!dateStr) return '';\n try {\n const date = new Date(dateStr);\n if (isNaN(date.getTime())) return dateStr;\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\nfunction decodeHtmlBody(fields: FieldsData, emptyBodyText: string): string {\n // 优先使用 bodyHtml (string 类型)\n if (fields.bodyHtml) {\n return fields.bodyHtml;\n }\n // 其次尝试 html (Uint8Array 类型)\n if (fields.html) {\n try {\n const decoder = new TextDecoder('utf-8');\n return decoder.decode(fields.html);\n } catch {\n // fallback\n }\n }\n // 最后使用纯文本,转换为简单 HTML\n if (fields.body) {\n return `<pre style=\"white-space: pre-wrap; word-wrap: break-word; font-family: system-ui, sans-serif;\">${fields.body.replace(/&/g, '&').replace(/\\x3c/g, '<').replace(/>/g, '>')\n }</pre>`;\n }\n return `<p style=\"color: #999;\">${emptyBodyText}</p>`;\n}\n\nfunction formatMessageClass(messageClass: string | undefined): string {\n if (!messageClass) return '';\n const classMap: Record<string, string> = {\n 'IPM.Note': 'Email',\n 'IPM.Note.SMIME': 'Encrypted Email',\n 'IPM.Note.SMIME.MultipartSigned': 'Signed Email',\n 'IPM.Appointment': 'Appointment',\n 'IPM.Schedule.Meeting.Request': 'Meeting Request',\n 'IPM.Schedule.Meeting.Canceled': 'Meeting Cancellation',\n 'IPM.Contact': 'Contact',\n 'IPM.Task': 'Task',\n 'IPM.StickyNote': 'Sticky Note',\n };\n return classMap[messageClass] || messageClass;\n}\n\nconst labelStyle: React.CSSProperties = {\n flexShrink: 0,\n color: '#6b7280',\n fontWeight: 500,\n marginRight: '8px',\n whiteSpace: 'nowrap',\n};\n\nconst rowStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n padding: '6px 0',\n};\n\nconst iconWrapStyle: React.CSSProperties = {\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n height: '1.4em',\n};\n\nconst iconStyle: React.CSSProperties = {\n flexShrink: 0,\n color: '#9ca3af',\n};\n\nconst valueStyle: React.CSSProperties = {\n color: '#111827',\n wordBreak: 'break-word' as const,\n flex: 1,\n};\n\nexport const MsgRenderer: React.FC<MsgRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [fields, setFields] = useState<FieldsData | null>(null);\n\n useEffect(() => {\n const loadMsg = async () => {\n setLoading(true);\n setError(null);\n setFields(null);\n\n try {\n const response = await fetcher(url);\n if (!response.ok) {\n throw new Error('文件加载失败');\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const msgReader = new MsgReader(arrayBuffer);\n const fileData = msgReader.getFileData();\n setFields(fileData);\n } catch (err) {\n console.error('MSG 解析错误:', err);\n setError(t('msg.parse_failed'));\n } finally {\n setLoading(false);\n }\n };\n\n loadMsg();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !fields) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('msg.parse_failed_short')}</p>\n </div>\n </div>\n );\n }\n\n const toStr = formatRecipients(fields.recipients, 'to');\n const ccStr = formatRecipients(fields.recipients, 'cc');\n const bccStr = formatRecipients(fields.recipients, 'bcc');\n const senderName = fields.senderName || '';\n const senderEmail = fields.senderSmtpAddress || fields.senderEmail || '';\n const sender = senderName && senderEmail && senderName !== senderEmail\n ? `${senderName} <${senderEmail}>`\n : senderName || senderEmail;\n const sentDate = formatDate(fields.clientSubmitTime);\n const receivedDate = formatDate(fields.messageDeliveryTime);\n const createdDate = formatDate(fields.creationTime);\n const lastModified = formatDate(fields.lastModificationTime);\n const subject = fields.subject || '(无主题)';\n const attachments = (fields.attachments || []).filter((a) => !a.attachmentHidden);\n const bodyHtml = decodeHtmlBody(fields, t('msg.empty_body'));\n const messageClass = formatMessageClass(fields.messageClass);\n const messageId = fields.messageId || '';\n const fieldsAny = fields as FieldsData & Record<string, unknown>;\n const importance = typeof fieldsAny.importance === 'number' ? fieldsAny.importance : undefined;\n const importanceLabel = importance === 2 ? 'High' : importance === 0 ? 'Low' : '';\n const sensitivity = typeof fieldsAny.sensitivity === 'number' ? fieldsAny.sensitivity : undefined;\n const sensitivityLabels: Record<number, string> = {\n 0: 'Normal',\n 1: 'Personal',\n 2: 'Private',\n 3: 'Confidential',\n };\n const sensitivityLabel = sensitivity !== undefined && sensitivity !== 0 ? sensitivityLabels[sensitivity] || '' : '';\n\n return (\n <div\n className=\"rfp-w-full rfp-h-full rfp-overflow-auto\"\n style={{ background: 'white' }}\n >\n <div\n style={{\n width: '100%',\n background: 'white',\n minHeight: '100%',\n }}\n >\n {/* 邮件头部 */}\n <div style={{ borderBottom: '1px solid #e5e7eb', padding: 'clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)', background: '#f9fafb' }}>\n {/* 主题 */}\n <h2 style={{ margin: '0 0 16px 0', fontSize: 'clamp(16px, 2.5vw, 20px)', fontWeight: 600, color: '#111827', lineHeight: 1.4 }}>\n {subject}\n </h2>\n\n {/* 元信息 */}\n <div style={{ display: 'flex', flexDirection: 'column', fontSize: 'clamp(12px, 1.8vw, 14px)', color: '#4b5563' }}>\n {sender && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><User size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>From</span>\n <span style={valueStyle}>{sender}</span>\n </div>\n </div>\n )}\n\n {toStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>To</span>\n <span style={valueStyle}>{toStr}</span>\n </div>\n </div>\n )}\n\n {ccStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Cc</span>\n <span style={valueStyle}>{ccStr}</span>\n </div>\n </div>\n )}\n\n {bccStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Bcc</span>\n <span style={valueStyle}>{bccStr}</span>\n </div>\n </div>\n )}\n\n {sentDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Calendar size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Sent</span>\n <span style={valueStyle}>{sentDate}</span>\n </div>\n </div>\n )}\n\n {receivedDate && receivedDate !== sentDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Clock size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Received</span>\n <span style={valueStyle}>{receivedDate}</span>\n </div>\n </div>\n )}\n\n {!sentDate && !receivedDate && createdDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Calendar size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Date</span>\n <span style={valueStyle}>{createdDate}</span>\n </div>\n </div>\n )}\n\n {importanceLabel && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Tag size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Importance</span>\n <span style={{\n ...valueStyle,\n color: importance === 2 ? '#dc2626' : '#2563eb',\n fontWeight: 500,\n }}>\n {importanceLabel}\n </span>\n </div>\n </div>\n )}\n\n {sensitivityLabel && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Tag size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Sensitivity</span>\n <span style={valueStyle}>{sensitivityLabel}</span>\n </div>\n </div>\n )}\n\n {messageClass && messageClass !== 'Email' && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Mail size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Type</span>\n <span style={valueStyle}>{messageClass}</span>\n </div>\n </div>\n )}\n\n {attachments.length > 0 && (\n <div style={{ ...rowStyle, borderTop: '1px solid #e5e7eb', marginTop: '4px', paddingTop: '10px' }}>\n <span style={iconWrapStyle}><Paperclip size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Attachments</span>\n <div style={{ ...valueStyle, display: 'flex', flexWrap: 'wrap', gap: '6px' }}>\n {attachments.map((a, i) => {\n const name = a.fileName || a.name || '未知文件';\n const size = a.contentLength;\n const sizeStr = size\n ? size > 1048576\n ? `${(size / 1048576).toFixed(1)} MB`\n : size > 1024\n ? `${(size / 1024).toFixed(0)} KB`\n : `${size} B`\n : '';\n return (\n <span\n key={i}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n padding: '2px 8px',\n background: '#f3f4f6',\n borderRadius: '4px',\n fontSize: '13px',\n color: '#374151',\n border: '1px solid #e5e7eb',\n }}\n >\n {name}\n {sizeStr && (\n <span style={{ color: '#9ca3af', fontSize: '12px' }}>({sizeStr})</span>\n )}\n </span>\n );\n })}\n </div>\n </div>\n </div>\n )}\n\n {messageId && (\n <div style={{ ...rowStyle, borderTop: attachments.length > 0 ? 'none' : '1px solid #e5e7eb', marginTop: '4px', paddingTop: '10px' }}>\n <span style={iconWrapStyle}><Hash size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Message-ID</span>\n <span style={{ ...valueStyle, fontSize: '12px', color: '#9ca3af', fontFamily: 'monospace' }}>{messageId}</span>\n </div>\n </div>\n )}\n\n {lastModified && lastModified !== sentDate && lastModified !== receivedDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Clock size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Modified</span>\n <span style={{ ...valueStyle, fontSize: '12px', color: '#9ca3af' }}>{lastModified}</span>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* 邮件正文 */}\n <div\n style={{\n padding: 'clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n lineHeight: '1.6',\n color: '#333',\n overflowX: 'auto',\n }}\n dangerouslySetInnerHTML={{ __html: bodyHtml }}\n />\n </div>\n </div>\n );\n};\n","import { useEffect, useRef, useState, useCallback, useImperativeHandle, forwardRef } from 'react';\nimport ePub from '@likecoin/epub-ts';\nimport { X } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\n// 全局注入 epubjs 容器样式(只注入一次)\nif (typeof document !== 'undefined' && !document.getElementById('rfp-epub-styles')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'rfp-epub-styles';\n styleEl.textContent = `\n .epub-container { overflow-y: auto !important; scrollbar-width: thin; }\n .epub-container::-webkit-scrollbar { width: 8px; }\n .epub-container::-webkit-scrollbar-track { background: transparent; }\n .epub-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }\n .epub-container::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }\n .epub-view > iframe { background: white; }\n `;\n document.head.appendChild(styleEl);\n}\n\nexport interface TocItem {\n label: string;\n href: string;\n subitems?: TocItem[];\n}\n\nexport interface EpubRendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface EpubRendererProps {\n url: string;\n onChapterChange?: (current: number, total: number) => void;\n onFullWidthChange?: (isFullWidth: boolean) => void;\n}\n\ninterface RenditionLike {\n display: (target?: string) => Promise<unknown>;\n next: () => Promise<unknown>;\n prev: () => Promise<unknown>;\n on: (event: string, cb: (...args: unknown[]) => void) => void;\n resize: (width: number, height: number) => void;\n currentLocation: () => unknown;\n destroy?: () => void;\n themes: {\n register: (name: string, styles: Record<string, unknown>) => void;\n select: (name: string) => void;\n };\n}\n\ninterface BookLike {\n ready: Promise<unknown>;\n loaded: { navigation: Promise<unknown> };\n locations: {\n generate: (chars: number) => Promise<string[]>;\n length: () => number;\n locationFromCfi: (cfi: string) => number;\n };\n renderTo: (el: HTMLElement, opts: Record<string, unknown>) => RenditionLike;\n destroy: () => void;\n}\n\nconst A4_WIDTH = 794;\n\nexport const EpubRenderer = forwardRef<EpubRendererHandle, EpubRendererProps>(\n ({ url, onChapterChange, onFullWidthChange }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const viewerRef = useRef<HTMLDivElement>(null);\n const bookRef = useRef<BookLike | null>(null);\n const renditionRef = useRef<RenditionLike | null>(null);\n const onChapterChangeRef = useRef(onChapterChange);\n const onFullWidthChangeRef = useRef(onFullWidthChange);\n onChapterChangeRef.current = onChapterChange;\n onFullWidthChangeRef.current = onFullWidthChange;\n\n const totalLocationsRef = useRef(0);\n const lastCfiRef = useRef<string | null>(null);\n const isFullWidthRef = useRef(false);\n\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isFullWidth, setIsFullWidth] = useState(false);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const tocRef = useRef<TocItem[]>([]);\n tocRef.current = toc;\n\n isFullWidthRef.current = isFullWidth;\n\n const handlePrev = useCallback(() => {\n renditionRef.current?.prev();\n }, []);\n\n const handleNext = useCallback(() => {\n renditionRef.current?.next();\n }, []);\n\n // 滚动监听:接近底部时强制触发 check 加载后续 section\n const scrollContainerRef = useRef<Element | null>(null);\n const scrollRafRef = useRef(0);\n\n const onScrollRef = useRef((_e?: Event) => {\n const container = scrollContainerRef.current;\n if (!container) return;\n const el = container as HTMLElement;\n const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 200;\n if (nearBottom) {\n try {\n const mgr = (renditionRef.current as unknown as { manager?: { check?: (t?: number, e?: number) => Promise<unknown> } })?.manager;\n mgr?.check?.(500, 500);\n } catch { /* ignore */ }\n }\n });\n\n const reattachScrollListener = useCallback(() => {\n // 清理旧监听\n if (scrollContainerRef.current) {\n scrollContainerRef.current.removeEventListener('scroll', onScrollRef.current);\n scrollContainerRef.current = null;\n }\n cancelAnimationFrame(scrollRafRef.current);\n\n const tryAttach = () => {\n const container = viewerRef.current?.querySelector('.epub-container') ?? null;\n if (!container) {\n scrollRafRef.current = requestAnimationFrame(tryAttach);\n return;\n }\n scrollContainerRef.current = container;\n container.addEventListener('scroll', onScrollRef.current, { passive: true });\n };\n scrollRafRef.current = requestAnimationFrame(tryAttach);\n }, []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n onFullWidthChangeRef.current?.(newVal);\n // 等 CSS transition 完成后再 resize 并恢复位置\n setTimeout(() => {\n const viewer = viewerRef.current;\n const rendition = renditionRef.current;\n if (!viewer || !rendition) return;\n rendition.resize(viewer.offsetWidth, viewer.offsetHeight);\n // 重排后恢复阅读位置\n if (lastCfiRef.current) {\n rendition.display(lastCfiRef.current);\n }\n // resize/display 可能重建 .epub-container,需要重新绑定滚动监听\n reattachScrollListener();\n }, 350);\n }, [reattachScrollListener]);\n\n const toggleToc = useCallback(() => {\n setShowToc(prev => !prev);\n }, []);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n renditionRef.current?.display(href);\n setShowToc(false);\n }, []);\n\n useImperativeHandle(ref, () => ({\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n viewer.innerHTML = '';\n lastCfiRef.current = null;\n totalLocationsRef.current = 0;\n\n let cancelled = false;\n // StrictMode 下 effect 会立即 mount→unmount→mount\n // 用 microtask 延迟初始化,让第一次的 cleanup 先执行,避免 epubjs 内部状态被污染\n const loadTimer = window.setTimeout(() => {\n if (cancelled) return;\n load();\n }, 0);\n\n const load = async () => {\n try {\n let bookInput: string | ArrayBuffer = url;\n if (url.startsWith('blob:')) {\n const resp = await fetcher(url);\n bookInput = await resp.arrayBuffer();\n }\n\n const book = ePub(bookInput) as unknown as BookLike;\n bookRef.current = book;\n\n const rendition = book.renderTo(viewer, {\n manager: 'continuous',\n flow: 'scrolled',\n width: '100%',\n height: '100%',\n });\n renditionRef.current = rendition;\n\n rendition.themes.register('default', {\n body: {\n background: '#ffffff !important',\n color: '#1a1a1a !important',\n 'font-family': '\"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important',\n 'font-size': '16px !important',\n 'line-height': '2 !important',\n padding: '40px 60px !important',\n 'max-width': '100% !important',\n 'box-sizing': 'border-box !important',\n 'word-break': 'break-word !important',\n 'overflow-wrap': 'break-word !important',\n },\n p: { 'text-indent': '2em !important', margin: '0.8em 0 !important' },\n h1: { 'text-align': 'center !important', margin: '1.5em 0 1em !important' },\n h2: { margin: '1.2em 0 0.8em !important' },\n h3: { margin: '1em 0 0.6em !important' },\n img: { 'max-width': '100% !important', height: 'auto !important' },\n a: { color: '#2563eb !important', 'text-decoration': 'none !important' },\n });\n rendition.themes.select('default');\n\n await book.ready;\n\n // 异步生成 locations 索引(用于实时页数)\n book.locations.generate(1024).then(() => {\n if (cancelled) return;\n totalLocationsRef.current = book.locations.length();\n // 触发一次更新让父组件拿到 total\n const loc = renditionRef.current?.currentLocation() as { start?: { location?: number; cfi?: string } } | undefined;\n const cur = loc?.start?.location ?? 0;\n onChapterChangeRef.current?.(cur + 1, totalLocationsRef.current);\n }).catch(() => { /* ignore */ });\n\n // 获取目录\n const nav = await book.loaded.navigation as { toc?: TocItem[] };\n if (!cancelled && Array.isArray(nav?.toc)) {\n setToc(nav.toc);\n }\n\n await rendition.display();\n\n if (cancelled) return;\n\n setLoading(false);\n onChapterChangeRef.current?.(1, totalLocationsRef.current || 1);\n\n rendition.on('relocated', (location: unknown) => {\n const loc = location as { start?: { cfi?: string; location?: number; href?: string } };\n if (loc?.start?.cfi) {\n lastCfiRef.current = loc.start.cfi;\n }\n if (loc?.start?.href) {\n // 根据 spine href 查找匹配的 TOC 项\n const spineHref = loc.start.href;\n const matches: string[] = [];\n const collect = (items: TocItem[]) => {\n for (const item of items) {\n const base = item.href.split('#')[0];\n if (base && (spineHref === base || spineHref.endsWith('/' + base) || spineHref.endsWith(base))) {\n matches.push(item.href);\n }\n if (item.subitems) collect(item.subitems);\n }\n };\n collect(tocRef.current);\n if (matches.length === 1) {\n // 唯一匹配,直接设置\n setActiveTocHref(matches[0]);\n }\n // 多个匹配(同一文件不同 anchor)时保持当前选中(由点击设置)\n }\n const cur = loc?.start?.location;\n const total = totalLocationsRef.current;\n if (typeof cur === 'number' && total > 0) {\n onChapterChangeRef.current?.(cur + 1, total);\n }\n });\n\n } catch (err) {\n console.error('EPUB 加载错误:', err);\n if (!cancelled) {\n setError(t('epub.load_failed'));\n setLoading(false);\n }\n }\n };\n\n return () => {\n cancelled = true;\n window.clearTimeout(loadTimer);\n try { renditionRef.current?.destroy?.(); } catch { /* ignore */ }\n try { bookRef.current?.destroy(); } catch { /* ignore */ }\n renditionRef.current = null;\n bookRef.current = null;\n };\n }, [url]);\n\n useEffect(() => {\n const onResize = () => {\n const viewer = viewerRef.current;\n if (!viewer || !renditionRef.current) return;\n renditionRef.current.resize(viewer.offsetWidth, viewer.offsetHeight);\n };\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, []);\n\n useEffect(() => {\n reattachScrollListener();\n return () => {\n cancelAnimationFrame(scrollRafRef.current);\n scrollContainerRef.current?.removeEventListener('scroll', onScrollRef.current);\n };\n }, [url, reattachScrollListener]);\n\n const isActive = useCallback((href: string) => {\n return href === activeTocHref;\n }, [activeTocHref]);\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ marginLeft: depth > 0 ? 16 : 0 }}>\n {items.map((item, i) => {\n const active = isActive(item.href);\n return (\n <li key={`${item.href}-${i}`}>\n <button\n onClick={() => handleTocClick(item.href)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${active\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label.trim()}\n </button>\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n );\n })}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-[#f5f5f0] rfp-overflow-hidden\">\n {error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 - 滑入动画 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{\n opacity: showToc ? 1 : 0,\n pointerEvents: showToc ? 'auto' : 'none',\n }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={viewerRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n overflow: 'hidden',\n }}\n />\n )}\n </div>\n );\n }\n);\n","import {\n useEffect,\n useRef,\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n} from 'react';\nimport { X } from 'lucide-react';\nimport 'foliate-js/view.js';\nimport type { FoliateView, TocItem } from 'foliate-js/view.js';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\nconst READER_CSS = `\n @namespace epub \"http://www.idpf.org/2007/ops\";\n html { color-scheme: light; }\n body {\n background: #ffffff !important;\n color: #1a1a1a !important;\n font-family: \"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important;\n font-size: 16px !important;\n line-height: 2 !important;\n max-width: 100% !important;\n box-sizing: border-box !important;\n word-break: break-word !important;\n overflow-wrap: break-word !important;\n }\n p, li, blockquote, dd { line-height: 2; text-align: justify; }\n p { text-indent: 2em; margin: 0.8em 0; }\n h1 { text-align: center; margin: 1.5em 0 1em; }\n h2 { margin: 1.2em 0 0.8em; }\n h3 { margin: 1em 0 0.6em; }\n img { max-width: 100% !important; height: auto !important; }\n a { color: #2563eb; text-decoration: none; }\n pre { white-space: pre-wrap !important; }\n`;\n\nconst A4_WIDTH = 794;\n\nexport interface MobiRendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface MobiRendererProps {\n url: string;\n onChapterChange?: (current: number, total: number) => void;\n onFullWidthChange?: (isFullWidth: boolean) => void;\n}\n\nexport const MobiRenderer = forwardRef<MobiRendererHandle, MobiRendererProps>(\n ({ url, onChapterChange, onFullWidthChange }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const hostRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<FoliateView | null>(null);\n const onChapterChangeRef = useRef(onChapterChange);\n const onFullWidthChangeRef = useRef(onFullWidthChange);\n onChapterChangeRef.current = onChapterChange;\n onFullWidthChangeRef.current = onFullWidthChange;\n\n // 模拟 epub.js 的 locations 显示\n const totalLocationsRef = useRef(1);\n\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const [isFullWidth, setIsFullWidth] = useState(false);\n const isFullWidthRef = useRef(false);\n isFullWidthRef.current = isFullWidth;\n\n const reportProgress = useCallback((current: number, total: number) => {\n if (total > 0) totalLocationsRef.current = total;\n onChapterChangeRef.current?.(Math.max(1, current + 1), totalLocationsRef.current);\n }, []);\n\n const handlePrev = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.prev().catch(() => {});\n }, []);\n\n const handleNext = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.next().catch(() => {});\n }, []);\n\n const toggleToc = useCallback(() => setShowToc((prev) => !prev), []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n onFullWidthChangeRef.current?.(newVal);\n // 宽度改变后 paginator 需要重新分页\n const view = viewRef.current;\n if (!view) return;\n const renderer = (view as unknown as { renderer?: HTMLElement }).renderer;\n if (renderer) {\n renderer.setAttribute('max-inline-size', newVal ? '9999' : '720');\n }\n }, []);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n setShowToc(false);\n viewRef.current?.goTo(href).catch(() => {});\n }, []);\n\n useImperativeHandle(ref, () => ({\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n setActiveTocHref('');\n host.replaceChildren();\n\n let cancelled = false;\n let view: FoliateView | null = null;\n\n const load = async () => {\n try {\n if (cancelled) return;\n\n view = document.createElement('foliate-view') as FoliateView;\n host.appendChild(view);\n viewRef.current = view;\n\n // 先注册事件\n view.addEventListener('relocate', (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (!detail) return;\n // SectionProgress 返回的 location 对象: { current, next, total }\n const loc = detail.location as { current?: number; total?: number } | undefined;\n if (loc && typeof loc.current === 'number' && typeof loc.total === 'number') {\n reportProgress(loc.current, loc.total);\n } else {\n // fallback:用 section 级别估算\n const sections = viewRef.current?.book?.sections ?? [];\n const idx = detail.index ?? 0;\n const frac = detail.fraction ?? 0;\n const total = Math.max(sections.length, 1);\n const current = Math.round((idx + frac) / total * total);\n reportProgress(current, total);\n }\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) {\n setActiveTocHref(tocItem.href);\n }\n });\n\n const res = await fetcher(url);\n if (!res.ok) throw new Error(`请求失败: ${res.status}`);\n const blob = await res.blob();\n let name = 'book.mobi';\n try {\n const u = new URL(url, window.location.href);\n const base = u.pathname.split('/').pop();\n if (base) name = decodeURIComponent(base);\n } catch { /* blob: URL */ }\n const file = new File([blob], name);\n\n await view.open(file);\n if (cancelled) { view.book?.destroy?.(); return; }\n\n // 配置 paginator:paginated 模式(默认),带动画\n const renderer = (view as unknown as { renderer: HTMLElement & {\n setStyles?: (css: string) => void;\n next?: () => Promise<void>;\n } }).renderer;\n\n if (renderer) {\n // flow=\"paginated\" 是默认值,不需要显式设置\n renderer.setAttribute('animated', '');\n renderer.setAttribute('max-inline-size', '720');\n renderer.setAttribute('margin', '48');\n renderer.setAttribute('gap', '5%');\n renderer.setStyles?.(READER_CSS);\n // 必须调 next() 渲染首页\n await renderer.next?.();\n }\n\n setToc(view.book?.toc ?? []);\n setLoading(false);\n reportProgress(0, view.book?.sections.length ?? 1);\n } catch (err) {\n console.error('MOBI/AZW3 加载错误:', err);\n if (!cancelled) {\n setError(t('mobi.load_failed'));\n setLoading(false);\n }\n }\n };\n\n load();\n\n return () => {\n cancelled = true;\n try { viewRef.current?.book?.destroy?.(); } catch { /* ignore */ }\n viewRef.current = null;\n host.replaceChildren();\n };\n }, [url, reportProgress]);\n\n const isActive = useCallback(\n (href: string | undefined) => !!href && href === activeTocHref,\n [activeTocHref]\n );\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ listStyle: 'none', padding: 0, margin: depth > 0 ? '0 0 0 16px' : 0 }}>\n {items.map((item, i) => (\n <li key={`${item.href ?? item.label}-${i}`}>\n {item.href ? (\n <button\n onClick={() => handleTocClick(item.href!)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${\n isActive(item.href)\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label?.trim()}\n </button>\n ) : (\n <div className=\"rfp-w-full rfp-py-2 rfp-px-3 rfp-text-sm rfp-text-fg-tertiary rfp-truncate\">\n {item.label?.trim()}\n </div>\n )}\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-[#f5f5f0] rfp-overflow-hidden\">\n {error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-secondary rfp-text-center rfp-p-6\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n )}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{ opacity: showToc ? 1 : 0, pointerEvents: showToc ? 'auto' : 'none' }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={hostRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n }}\n />\n )}\n </div>\n );\n }\n);\n\nMobiRenderer.displayName = 'MobiRenderer';\n","import { useRef, useEffect, useState } from 'react';\nimport videojs from 'video.js';\nimport 'video.js/dist/video-js.css';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ntype VideoJsPlayer = ReturnType<typeof videojs>;\n\ninterface VideoRendererProps {\n url: string;\n}\n\n// 根据 URL 获取视频 MIME 类型\nconst getVideoType = (url: string): string => {\n const ext = url.split('.').pop()?.toLowerCase().split('?')[0] || '';\n const typeMap: Record<string, string> = {\n mp4: 'video/mp4',\n webm: 'video/webm',\n ogg: 'video/ogg',\n ogv: 'video/ogg',\n mov: 'video/quicktime', // MOV 使用 QuickTime MIME 类型\n avi: 'video/x-msvideo',\n mkv: 'video/x-matroska',\n m4v: 'video/mp4',\n '3gp': 'video/3gpp',\n flv: 'video/x-flv',\n };\n return typeMap[ext] || 'video/mp4';\n};\n\nexport const VideoRenderer: React.FC<VideoRendererProps> = ({ url }) => {\n const t = useTranslator();\n const [error, setError] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const videoRef = useRef<HTMLDivElement>(null);\n const playerRef = useRef<VideoJsPlayer | null>(null);\n\n useEffect(() => {\n // 确保 Video.js 播放器只初始化一次\n if (!playerRef.current && videoRef.current) {\n const videoElement = document.createElement('video-js');\n videoElement.classList.add('vjs-big-play-centered', 'vjs-theme-apple');\n videoRef.current.appendChild(videoElement);\n\n const videoType = getVideoType(url);\n\n // 为 MOV 格式提供多个 MIME 类型作为备用\n const sources = videoType === 'video/quicktime'\n ? [\n { src: url, type: 'video/quicktime' },\n { src: url, type: 'video/mp4' } // 备用方案\n ]\n : [{ src: url, type: videoType }];\n\n const player = videojs(videoElement, {\n controls: true,\n fill: true,\n preload: 'auto',\n controlBar: {\n children: [\n 'playToggle',\n 'volumePanel',\n 'currentTimeDisplay',\n 'timeDivider',\n 'durationDisplay',\n 'progressControl',\n 'remainingTimeDisplay',\n 'fullscreenToggle'\n ],\n volumePanel: {\n inline: false\n }\n },\n html5: {\n vhs: {\n overrideNative: true\n },\n nativeVideoTracks: false,\n nativeAudioTracks: false,\n nativeTextTracks: false\n },\n sources\n });\n\n // 确保视频保持比例\n const videoEl = player.el().querySelector('video');\n if (videoEl) {\n (videoEl as HTMLVideoElement).style.objectFit = 'contain';\n }\n\n // 监听加载完成\n player.on('loadeddata', () => {\n setIsLoading(false);\n });\n\n player.on('error', () => {\n const error = player.error();\n console.error('Video.js error:', error);\n setError(t('video.load_failed_with_error', { error: error?.message || t('common.unknown_error') }));\n setIsLoading(false);\n });\n\n playerRef.current = player;\n }\n }, [url]);\n\n // 清理函数\n useEffect(() => {\n const player = playerRef.current;\n\n return () => {\n if (player && !player.isDisposed()) {\n player.dispose();\n playerRef.current = null;\n }\n };\n }, []);\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-16 rfp-h-16 rfp-mx-auto rfp-mb-4 rfp-rounded-full rfp-bg-red-500/10 rfp-flex rfp-items-center rfp-justify-center\">\n <svg className=\"rfp-w-8 rfp-h-8 rfp-text-red-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\" />\n </svg>\n </div>\n <p className=\"rfp-text-lg rfp-font-medium rfp-text-fg-primary rfp-mb-2\">{t('video.load_failed')}</p>\n <p className=\"rfp-text-sm rfp-text-fg-tertiary\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-full rfp-h-full rfp-relative\">\n {/* 加载状态 */}\n {isLoading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-3 rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-3 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('video.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 视频播放器容器 */}\n <div\n ref={videoRef}\n className=\"rfp-overflow-hidden rfp-w-full rfp-h-full [&_video]:rfp-object-contain\"\n style={{\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05)'\n }}\n />\n </div>\n </div>\n );\n};\n","import { useState, useRef, useEffect, useCallback } from 'react';\n\ninterface UseAudioPlayerOptions {\n url: string;\n skipSeconds?: number;\n}\n\ninterface UseAudioPlayerReturn {\n audioRef: React.RefObject<HTMLAudioElement>;\n isPlaying: boolean;\n isLoading: boolean;\n isLoop: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n isMuted: boolean;\n error: string | null;\n togglePlay: () => void;\n seek: (time: number) => void;\n skip: (seconds: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n toggleLoop: () => void;\n formatTime: (time: number) => string;\n}\n\nexport function useAudioPlayer({\n url,\n}: UseAudioPlayerOptions): UseAudioPlayerReturn {\n const audioRef = useRef<HTMLAudioElement>(null);\n const [isPlaying, setIsPlaying] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [isMuted, setIsMuted] = useState(false);\n const [isLoop, setIsLoop] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n // 重置加载状态\n setIsLoading(true);\n setError(null);\n\n const onTimeUpdate = () => {\n if (!isNaN(audio.currentTime)) {\n setCurrentTime(audio.currentTime);\n }\n };\n\n const onDurationChange = () => {\n if (!isNaN(audio.duration) && isFinite(audio.duration)) {\n setDuration(audio.duration);\n }\n };\n\n const onCanPlay = () => {\n setIsLoading(false);\n onDurationChange();\n };\n\n const onWaiting = () => setIsLoading(true);\n const onPlaying = () => {\n setIsLoading(false);\n setIsPlaying(true);\n };\n\n // 由 audio 事件驱动播放状态,而非手动设置\n const onPlay = () => setIsPlaying(true);\n const onPause = () => setIsPlaying(false);\n const onEnded = () => setIsPlaying(false);\n\n const onError = () => {\n setError('音频加载失败');\n setIsLoading(false);\n };\n\n audio.addEventListener('timeupdate', onTimeUpdate);\n audio.addEventListener('loadedmetadata', onDurationChange);\n audio.addEventListener('durationchange', onDurationChange);\n audio.addEventListener('canplay', onCanPlay);\n audio.addEventListener('waiting', onWaiting);\n audio.addEventListener('playing', onPlaying);\n audio.addEventListener('play', onPlay);\n audio.addEventListener('pause', onPause);\n audio.addEventListener('ended', onEnded);\n audio.addEventListener('error', onError);\n\n // 如果 audio 已经就绪\n if (audio.readyState >= 3) {\n setIsLoading(false);\n onDurationChange();\n } else if (audio.readyState >= 1) {\n onDurationChange();\n }\n\n return () => {\n audio.removeEventListener('timeupdate', onTimeUpdate);\n audio.removeEventListener('loadedmetadata', onDurationChange);\n audio.removeEventListener('durationchange', onDurationChange);\n audio.removeEventListener('canplay', onCanPlay);\n audio.removeEventListener('waiting', onWaiting);\n audio.removeEventListener('playing', onPlaying);\n audio.removeEventListener('play', onPlay);\n audio.removeEventListener('pause', onPause);\n audio.removeEventListener('ended', onEnded);\n audio.removeEventListener('error', onError);\n };\n }, [url]);\n\n const togglePlay = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n if (audio.paused) {\n audio.play().catch(() => {\n // 浏览器自动播放策略拒绝\n });\n } else {\n audio.pause();\n }\n }, []);\n\n const seek = useCallback((time: number) => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.currentTime = time;\n setCurrentTime(time);\n }, []);\n\n const skip = useCallback(\n (seconds: number) => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.currentTime = Math.max(\n 0,\n Math.min(audio.currentTime + seconds, audio.duration || Infinity)\n );\n },\n []\n );\n\n const setVolume = useCallback((vol: number) => {\n const audio = audioRef.current;\n if (!audio) return;\n const clamped = Math.max(0, Math.min(1, vol));\n audio.volume = clamped;\n setVolumeState(clamped);\n if (clamped > 0) {\n audio.muted = false;\n setIsMuted(false);\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.muted = !audio.muted;\n setIsMuted(audio.muted);\n }, []);\n\n const toggleLoop = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n const next = !audio.loop;\n audio.loop = next;\n setIsLoop(next);\n }, []);\n\n const formatTime = useCallback((time: number) => {\n if (!isFinite(time) || isNaN(time) || time < 0) return '0:00';\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n }, []);\n\n return {\n audioRef,\n isPlaying,\n isLoading,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n };\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { Play, Pause, Volume2, VolumeX, Volume1, SkipBack, SkipForward, Repeat } from 'lucide-react';\nimport { useAudioPlayer } from '../../hooks/useAudioPlayer';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\n/** 文本溢出时自动横向滚动 */\nconst MarqueeText: React.FC<{\n text: string;\n className?: string;\n style?: React.CSSProperties;\n}> = ({ text, className = '', style }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const innerRef = useRef<HTMLDivElement>(null);\n const [overflow, setOverflow] = useState(false);\n const [scrollDist, setScrollDist] = useState(0);\n\n useEffect(() => {\n const check = () => {\n const container = containerRef.current;\n const inner = innerRef.current;\n if (!container || !inner) return;\n const cw = container.clientWidth;\n const tw = inner.scrollWidth;\n setOverflow(tw > cw);\n setScrollDist(tw);\n };\n check();\n const observer = new ResizeObserver(check);\n if (containerRef.current) observer.observe(containerRef.current);\n return () => observer.disconnect();\n }, [text]);\n\n const gap = 60;\n const totalScroll = scrollDist + gap;\n const dur = totalScroll / 40;\n\n return (\n <div\n ref={containerRef}\n className={`rfp-overflow-hidden rfp-whitespace-nowrap ${className}`}\n style={style}\n >\n {overflow ? (\n <motion.div\n className=\"rfp-inline-flex rfp-whitespace-nowrap\"\n animate={{ x: [0, -totalScroll] }}\n transition={{ duration: dur, repeat: Infinity, ease: 'linear', repeatDelay: 1.5 }}\n >\n <span>{text}</span>\n <span style={{ width: gap }} className=\"rfp-inline-block\" />\n <span>{text}</span>\n </motion.div>\n ) : null}\n {/* 始终渲染用于测量的隐藏层 */}\n <div\n ref={innerRef}\n className=\"rfp-whitespace-nowrap\"\n style={overflow ? { position: 'absolute', visibility: 'hidden', pointerEvents: 'none' } : undefined}\n >\n {text}\n </div>\n </div>\n );\n};\n\n/** SVG 唱臂组件 */\nconst Tonearm: React.FC<{ isPlaying: boolean }> = ({ isPlaying }) => (\n <motion.div\n className=\"rfp-absolute\"\n style={{\n top: '-6px',\n right: '2px',\n width: '100px',\n height: '120px',\n transformOrigin: '76px 16px',\n zIndex: 5,\n }}\n animate={{ rotate: isPlaying ? 16 : 0 }}\n transition={{ duration: 0.8, ease: [0.4, 0, 0.2, 1] }}\n >\n <svg\n width=\"100\"\n height=\"120\"\n viewBox=\"0 0 100 120\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* 底座阴影 */}\n <circle cx=\"76\" cy=\"16\" r=\"13\" fill=\"rgba(0,0,0,0.3)\" />\n {/* 底座外圈 */}\n <circle cx=\"76\" cy=\"16\" r=\"11\" fill=\"url(#baseGrad)\" />\n {/* 底座内圈 */}\n <circle cx=\"76\" cy=\"16\" r=\"6\" fill=\"url(#baseInnerGrad)\" />\n {/* 底座中心轴 */}\n <circle cx=\"76\" cy=\"16\" r=\"2.5\" fill=\"#222\" stroke=\"#555\" strokeWidth=\"0.5\" />\n\n {/* 臂杆 */}\n <path\n d=\"M74 22 L56 88\"\n stroke=\"url(#armGrad)\"\n strokeWidth=\"3.5\"\n strokeLinecap=\"round\"\n />\n {/* 臂杆高光 */}\n <path\n d=\"M74.8 22 L56.8 88\"\n stroke=\"rgba(255,255,255,0.06)\"\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n />\n\n {/* 唱头座 (Headshell) */}\n <rect x=\"50\" y=\"86\" width=\"12\" height=\"7\" rx=\"1.5\" fill=\"url(#headGrad)\" />\n {/* 唱头 (Cartridge) */}\n <rect x=\"52.5\" y=\"92\" width=\"7\" height=\"9\" rx=\"1\" fill=\"url(#cartridgeGrad)\" />\n {/* 唱针 (Stylus) */}\n <line x1=\"56\" y1=\"101\" x2=\"56\" y2=\"105\" stroke=\"#bbb\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n <circle cx=\"56\" cy=\"105.5\" r=\"0.8\" fill=\"#ddd\" />\n\n {/* 渐变定义 */}\n <defs>\n <radialGradient id=\"baseGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stopColor=\"#555\" />\n <stop offset=\"100%\" stopColor=\"#1a1a1a\" />\n </radialGradient>\n <radialGradient id=\"baseInnerGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stopColor=\"#666\" />\n <stop offset=\"100%\" stopColor=\"#333\" />\n </radialGradient>\n <linearGradient id=\"armGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#555\" />\n <stop offset=\"50%\" stopColor=\"#444\" />\n <stop offset=\"100%\" stopColor=\"#333\" />\n </linearGradient>\n <linearGradient id=\"headGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#555\" />\n <stop offset=\"100%\" stopColor=\"#333\" />\n </linearGradient>\n <linearGradient id=\"cartridgeGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#444\" />\n <stop offset=\"100%\" stopColor=\"#222\" />\n </linearGradient>\n </defs>\n </svg>\n </motion.div>\n);\n\ninterface AudioRendererProps {\n url: string;\n fileName: string;\n}\n\nexport const AudioRenderer: React.FC<AudioRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const {\n audioRef,\n isPlaying,\n isLoading,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n } = useAudioPlayer({ url });\n\n const [showVolume, setShowVolume] = useState(false);\n const volumeRef = useRef<HTMLDivElement>(null);\n const volumeTimerRef = useRef<ReturnType<typeof setTimeout>>();\n\n const progress = duration > 0 ? currentTime / duration : 0;\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (volumeRef.current && !volumeRef.current.contains(e.target as Node)) {\n setShowVolume(false);\n }\n };\n if (showVolume) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [showVolume]);\n\n const handleVolumeEnter = () => {\n clearTimeout(volumeTimerRef.current);\n setShowVolume(true);\n };\n\n const handleVolumeLeave = () => {\n volumeTimerRef.current = setTimeout(() => setShowVolume(false), 300);\n };\n\n const VolumeIcon = isMuted || volume === 0 ? VolumeX : volume < 0.5 ? Volume1 : Volume2;\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-p-4 md:rfp-p-8 rfp-gap-5 md:rfp-gap-8 rfp-select-none\">\n {/* 唱片机整体 */}\n <div className=\"rfp-relative\" style={{ width: '260px', height: '240px' }}>\n {/* 外圈光晕 */}\n <motion.div\n className=\"rfp-absolute rfp-rounded-full\"\n style={{\n width: '220px',\n height: '220px',\n top: '18px',\n left: '8px',\n background: 'radial-gradient(circle, rgba(129,140,248,0.12) 0%, transparent 70%)',\n }}\n animate={isPlaying ? { scale: [1, 1.08, 1], opacity: [0.5, 1, 0.5] } : { scale: 1, opacity: 0.2 }}\n transition={isPlaying ? { duration: 3, repeat: Infinity, ease: 'easeInOut' } : { duration: 0.5 }}\n />\n\n {/* 唱片主体 */}\n <div\n className=\"rfp-absolute rfp-rounded-full rfp-overflow-hidden\"\n style={{\n width: '200px',\n height: '200px',\n top: '28px',\n left: '18px',\n background: `\n radial-gradient(circle at center, transparent 95%, rgba(30,30,30,0.8) 95.5%, #111 97%),\n radial-gradient(circle at center, transparent 38%, rgba(50,50,50,0.5) 38.15%, transparent 38.4%),\n radial-gradient(circle at center, transparent 45%, rgba(50,50,50,0.3) 45.15%, transparent 45.4%),\n radial-gradient(circle at center, transparent 52%, rgba(50,50,50,0.5) 52.15%, transparent 52.4%),\n radial-gradient(circle at center, transparent 59%, rgba(50,50,50,0.3) 59.15%, transparent 59.4%),\n radial-gradient(circle at center, transparent 66%, rgba(50,50,50,0.5) 66.15%, transparent 66.4%),\n radial-gradient(circle at center, transparent 73%, rgba(50,50,50,0.3) 73.15%, transparent 73.4%),\n radial-gradient(circle at center, transparent 80%, rgba(50,50,50,0.4) 80.15%, transparent 80.4%),\n radial-gradient(circle at center, transparent 87%, rgba(50,50,50,0.3) 87.15%, transparent 87.4%),\n conic-gradient(from 0deg, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c, #212121, #1a1a1a, #252525, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c)\n `,\n boxShadow: isPlaying\n ? '0 0 36px rgba(129,140,248,0.1), 0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)'\n : '0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)',\n animation: 'rfp-vinyl-spin 8s linear infinite',\n animationPlayState: isPlaying ? 'running' : 'paused',\n }}\n >\n {/* 中心标签 */}\n <div\n className=\"rfp-absolute rfp-rounded-full\"\n style={{\n width: '34%',\n height: '34%',\n top: '33%',\n left: '33%',\n background: 'radial-gradient(circle at 40% 38%, #818cf8, #6366f1, #4f46e5, #4338ca)',\n boxShadow: 'inset 0 1px 3px rgba(255,255,255,0.25), inset 0 -1px 3px rgba(0,0,0,0.3), 0 0 8px rgba(0,0,0,0.3)',\n }}\n >\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-rounded-full rfp-opacity-20\"\n style={{\n background: `\n radial-gradient(circle at center, transparent 30%, rgba(0,0,0,0.3) 31%, transparent 32%),\n radial-gradient(circle at center, transparent 50%, rgba(0,0,0,0.2) 51%, transparent 52%),\n radial-gradient(circle at center, transparent 70%, rgba(0,0,0,0.3) 71%, transparent 72%),\n radial-gradient(circle at center, transparent 88%, rgba(0,0,0,0.2) 89%, transparent 90%)\n `,\n }}\n />\n <div\n className=\"rfp-absolute rfp-rounded-full\"\n style={{\n width: '14%',\n height: '14%',\n top: '43%',\n left: '43%',\n background: 'radial-gradient(circle at 40% 40%, #333, #0d0d0d)',\n boxShadow: 'inset 0 1px 3px rgba(0,0,0,0.9), 0 0 2px rgba(0,0,0,0.5)',\n }}\n />\n </div>\n\n {isLoading && (\n <motion.div\n className=\"rfp-absolute rfp-inset-0 rfp-rounded-full\"\n style={{ border: '2px solid rgba(129,140,248,0.3)' }}\n animate={{ scale: [1, 1.02, 1], opacity: [0.3, 0.6, 0.3] }}\n transition={{ duration: 1.5, repeat: Infinity }}\n />\n )}\n </div>\n\n {/* 唱臂 */}\n <Tonearm isPlaying={isPlaying} />\n </div>\n\n {/* 文件名 */}\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <MarqueeText\n text={fileName}\n className=\"rfp-text-lg md:rfp-text-xl rfp-font-medium rfp-mb-1 rfp-text-fg-primary\"\n />\n <p className=\"rfp-text-xs rfp-tracking-widest rfp-uppercase rfp-text-accent\">\n Audio\n </p>\n </div>\n\n {/* 控制面板 */}\n <div\n className=\"rfp-w-full rfp-max-w-sm md:rfp-max-w-md rfp-rounded-2xl rfp-p-4 md:rfp-p-6 rfp-border rfp-bg-surface-1 rfp-border-line-weak\"\n style={{ backdropFilter: 'blur(16px)' }}\n >\n {/* 进度条 */}\n <div className=\"rfp-mb-5\">\n <div className=\"rfp-relative rfp-h-4 rfp-flex rfp-items-center\">\n <div className=\"rfp-absolute rfp-w-full rfp-h-[5px] rfp-rounded-full rfp-bg-surface-2\" />\n <div\n className=\"rfp-absolute rfp-h-[5px] rfp-rounded-full rfp-pointer-events-none\"\n style={{\n width: `${progress * 100}%`,\n background: 'linear-gradient(90deg, var(--fp-accent), var(--fp-accent-hover))',\n boxShadow: isPlaying ? '0 0 8px rgba(129,140,248,0.4)' : 'none',\n transition: 'width 0.1s linear',\n }}\n />\n <input\n type=\"range\"\n min=\"0\"\n max={duration > 0 ? duration : currentTime || 100}\n step=\"any\"\n value={currentTime}\n onChange={(e) => seek(parseFloat(e.target.value))}\n disabled={duration <= 0}\n aria-label={t('audio.aria.progress')}\n className=\"audio-slider rfp-absolute rfp-w-full\"\n />\n </div>\n <div className=\"rfp-flex rfp-justify-between rfp-text-xs rfp-mt-2.5 rfp-text-fg-tertiary\">\n <span style={{ fontVariantNumeric: 'tabular-nums' }}>{formatTime(currentTime)}</span>\n <span style={{ fontVariantNumeric: 'tabular-nums' }}>{duration > 0 ? formatTime(duration) : '--:--'}</span>\n </div>\n </div>\n\n {/* 控制按钮 */}\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-gap-3\">\n {/* 循环 */}\n <motion.button\n onClick={toggleLoop}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={isLoop ? t('audio.aria.loop_off') : t('audio.aria.loop_on')}\n className={`rfp-w-9 rfp-h-9 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors ${\n isLoop\n ? 'rfp-bg-accent-soft rfp-text-accent'\n : 'rfp-bg-surface-2 rfp-text-fg-tertiary'\n }`}\n >\n <Repeat className=\"rfp-w-4 rfp-h-4\" />\n </motion.button>\n\n {/* 后退 */}\n <motion.button\n onClick={() => skip(-10)}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={t('audio.aria.backward_10')}\n className=\"rfp-w-10 rfp-h-10 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-bg-surface-2 rfp-text-fg-secondary\"\n >\n <SkipBack className=\"rfp-w-[18px] rfp-h-[18px]\" />\n </motion.button>\n\n {/* 播放/暂停 */}\n <motion.button\n onClick={togglePlay}\n whileHover={{ scale: 1.06 }}\n whileTap={{ scale: 0.94 }}\n aria-label={isPlaying ? t('audio.aria.pause') : t('audio.aria.play')}\n className=\"rfp-w-14 rfp-h-14 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center\"\n style={{\n background: 'linear-gradient(135deg, var(--fp-accent-hover), var(--fp-accent))',\n color: '#fff',\n boxShadow: '0 4px 20px rgba(99,102,241,0.35)',\n }}\n >\n {isPlaying ? (\n <Pause className=\"rfp-w-6 rfp-h-6\" />\n ) : (\n <Play className=\"rfp-w-6 rfp-h-6 rfp-ml-0.5\" />\n )}\n </motion.button>\n\n {/* 前进 */}\n <motion.button\n onClick={() => skip(10)}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={t('audio.aria.forward_10')}\n className=\"rfp-w-10 rfp-h-10 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors rfp-bg-surface-2 rfp-text-fg-secondary\"\n >\n <SkipForward className=\"rfp-w-[18px] rfp-h-[18px]\" />\n </motion.button>\n\n {/* 音量 */}\n <div\n ref={volumeRef}\n className=\"rfp-relative\"\n onMouseEnter={handleVolumeEnter}\n onMouseLeave={handleVolumeLeave}\n >\n <motion.button\n onClick={toggleMute}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.92 }}\n aria-label={isMuted ? t('audio.aria.unmute') : t('audio.aria.mute')}\n className={`rfp-w-9 rfp-h-9 rfp-rounded-full rfp-flex rfp-items-center rfp-justify-center rfp-transition-colors ${\n showVolume\n ? 'rfp-bg-accent-soft rfp-text-accent'\n : 'rfp-bg-surface-2 rfp-text-fg-secondary'\n }`}\n >\n <VolumeIcon className=\"rfp-w-4 rfp-h-4\" />\n </motion.button>\n\n <AnimatePresence>\n {showVolume && (\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ duration: 0.12 }}\n className=\"rfp-absolute rfp-bottom-full rfp-mb-2 rfp-rounded-xl rfp-p-3 rfp-border rfp-bg-surface-3 rfp-border-line\"\n style={{\n left: '50%',\n marginLeft: '-27px',\n backdropFilter: 'blur(16px)',\n }}\n onMouseEnter={handleVolumeEnter}\n onMouseLeave={handleVolumeLeave}\n >\n <div className=\"rfp-flex rfp-flex-col rfp-items-center rfp-gap-2\" style={{ height: '100px' }}>\n <div className=\"rfp-relative rfp-flex rfp-items-center rfp-justify-center\" style={{ width: '24px', height: '80px' }}>\n <div\n className=\"rfp-absolute rfp-rounded-full rfp-bg-surface-2\"\n style={{ width: '3px', height: '100%' }}\n />\n <div\n className=\"rfp-absolute rfp-bottom-0 rfp-rounded-full rfp-pointer-events-none\"\n style={{\n width: '3px',\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: 'var(--fp-accent-hover)',\n transition: 'height 0.1s linear',\n }}\n />\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n value={isMuted ? 0 : volume}\n onChange={(e) => setVolume(parseFloat(e.target.value))}\n aria-label={t('audio.aria.volume')}\n className=\"volume-slider-vertical rfp-absolute\"\n style={{\n width: '80px',\n height: '24px',\n transform: 'rotate(-90deg)',\n transformOrigin: 'center center',\n }}\n />\n </div>\n <span className=\"rfp-text-[10px] rfp-tabular-nums rfp-text-fg-tertiary\">\n {Math.round((isMuted ? 0 : volume) * 100)}\n </span>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n </div>\n </div>\n\n <audio ref={audioRef} src={url} className=\"rfp-hidden\" />\n </div>\n );\n};\n","import { useState, useEffect } from 'react';\nimport { codeToHtml } from 'shiki';\nimport { useResolvedTheme } from '../ThemeContext';\n\n/**\n * 用 shiki 把代码高亮成 HTML(与 vue-file-preview 同引擎、同主题,保证两端视觉一致)。\n *\n * - dark 主题用 `dark-plus`(VSCode Dark Plus)\n * - light 主题用 `github-light`(GitHub Light)\n *\n * shiki 输出的 <pre> 自带 inline 背景/前景色,主题切换时必须重新高亮,\n * 因此 resolvedTheme 进入依赖数组。\n *\n * @returns\n * - `html`: 高亮后的 HTML 字符串(失败或加载中为 '')\n * - `loading`: 是否正在高亮\n */\nexport function useShikiHighlight(code: string, lang: string): { html: string; loading: boolean } {\n const resolvedTheme = useResolvedTheme();\n const [html, setHtml] = useState('');\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n codeToHtml(code, {\n lang,\n theme: resolvedTheme === 'light' ? 'github-light' : 'dark-plus',\n })\n .then((out) => {\n if (!cancelled) {\n setHtml(out);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setHtml('');\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [code, lang, resolvedTheme]);\n\n return { html, loading };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport rehypeRaw from 'rehype-raw';\nimport { Copy, Check } from 'lucide-react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\nimport 'katex/dist/katex.min.css';\n\ninterface MarkdownRendererProps {\n url: string;\n viewMode?: 'preview' | 'source';\n}\n\nconst useCopy = (text: string) => {\n const [copied, setCopied] = useState(false);\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n }\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }, [text]);\n return { copied, handleCopy };\n};\n\n/** 内联版复制按钮:放在代码块 header 行内,始终可见 */\nconst InlineCopyButton = ({ text }: { text: string }) => {\n const t = useTranslator();\n const { copied, handleCopy } = useCopy(text);\n return (\n <button\n onClick={handleCopy}\n className=\"rfp-p-1 rfp-rounded rfp-text-fg-muted hover:rfp-text-fg-secondary rfp-transition-colors rfp-flex rfp-items-center rfp-gap-1\"\n title={copied ? t('markdown.copied') : t('markdown.copy_code')}\n >\n {copied ? <Check size={13} /> : <Copy size={13} />}\n </button>\n );\n};\n\n/** 浮动版复制按钮:无 header 时绝对定位于代码块右上角(hover 显示) */\nconst FloatingCopyButton = ({ text }: { text: string }) => {\n const t = useTranslator();\n const { copied, handleCopy } = useCopy(text);\n return (\n <button\n onClick={handleCopy}\n className=\"rfp-absolute rfp-top-2 rfp-right-2 rfp-p-1.5 rfp-rounded-md rfp-bg-surface-2 hover:rfp-bg-surface-3 rfp-text-fg-tertiary hover:rfp-text-fg-secondary rfp-transition-colors rfp-opacity-0 group-hover:rfp-opacity-100 rfp-border rfp-border-line\"\n title={copied ? t('markdown.copied') : t('markdown.copy_code')}\n >\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n );\n};\n\n/** 带语言标注的代码块:shiki 高亮 + header + 复制按钮 */\nconst ShikiCodeBlock = ({ code, lang }: { code: string; lang: string }) => {\n const { html } = useShikiHighlight(code, lang);\n return (\n <div className=\"rfp-relative rfp-group rfp-my-4\">\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-1.5 rfp-bg-surface-1 rfp-border rfp-border-line-weak rfp-rounded-t-md rfp-border-b-0\">\n <span className=\"rfp-text-xs rfp-text-fg-secondary rfp-font-mono rfp-select-none\">{lang}</span>\n <InlineCopyButton text={code} />\n </div>\n {html ? (\n <div\n className=\"rfp-shiki-wrapper rfp-rounded-b-md rfp-border rfp-border-line-weak rfp-border-t-0 rfp-overflow-x-auto\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre\n className=\"rfp-m-0 rfp-rounded-b-md rfp-border rfp-border-line-weak rfp-border-t-0 rfp-overflow-x-auto rfp-p-4 rfp-bg-code-bg\"\n style={{ fontSize: '13px', lineHeight: '1.5' }}\n >\n <code className=\"rfp-font-mono rfp-text-code-fg rfp-text-sm\">{code}</code>\n </pre>\n )}\n </div>\n );\n};\n\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ url, viewMode = 'preview' }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const { html: sourceHtml } = useShikiHighlight(\n viewMode === 'source' ? content : '',\n 'markdown',\n );\n\n useEffect(() => {\n const loadMarkdown = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher });\n setContent(text);\n } catch (err) {\n setError(t('markdown.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n\n loadMarkdown();\n }, [url, fetcher, t]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n // 源码视图\n if (viewMode === 'source') {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {sourceHtml ? (\n <div\n className=\"rfp-shiki-wrapper with-line-numbers\"\n dangerouslySetInnerHTML={{ __html: sourceHtml }}\n />\n ) : (\n <pre className=\"rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm rfp-whitespace-pre-wrap rfp-break-words\">\n {content}\n </pre>\n )}\n </div>\n );\n }\n\n // 预览视图\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-p-6 md:rfp-p-10\">\n <div className=\"rfp-max-w-full md:rfp-max-w-4xl rfp-mx-auto\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkMath]}\n rehypePlugins={[rehypeRaw, rehypeKatex]}\n components={{\n code({ node, inline, className, children, ...props }: any) {\n const match = /language-(\\w+)/.exec(className || '');\n const codeString = String(children).replace(/\\n$/, '');\n if (!inline && match) {\n // 有语言标注的代码块 - shiki 高亮\n return <ShikiCodeBlock code={codeString} lang={match[1]} />;\n }\n if (!inline) {\n // 无语言标注的代码块 - 纯文本暗色显示\n return (\n <div className=\"rfp-relative rfp-group rfp-my-4\">\n <FloatingCopyButton text={codeString} />\n <pre\n className=\"rfp-m-0 rfp-rounded-md rfp-border rfp-border-line-weak rfp-overflow-x-auto rfp-p-4 rfp-bg-code-bg\"\n style={{ fontSize: '13px', lineHeight: '1.5' }}\n >\n <code className=\"rfp-font-mono rfp-text-code-fg rfp-text-sm\">{children}</code>\n </pre>\n </div>\n );\n }\n // 行内代码\n return (\n <code\n className=\"rfp-bg-surface-2 rfp-px-1.5 rfp-py-0.5 rfp-rounded rfp-text-sm rfp-font-mono rfp-text-fg-primary rfp-border rfp-border-line-weak\"\n {...props}\n >\n {children}\n </code>\n );\n },\n h1: ({ children }) => (\n <h1 className=\"rfp-text-3xl rfp-font-semibold rfp-mb-4 rfp-mt-6 rfp-text-fg-primary first:rfp-mt-0\">\n {children}\n </h1>\n ),\n h2: ({ children }) => (\n <h2 className=\"rfp-text-2xl rfp-font-semibold rfp-mb-3 rfp-mt-8 rfp-text-fg-primary\">\n {children}\n </h2>\n ),\n h3: ({ children }) => (\n <h3 className=\"rfp-text-xl rfp-font-semibold rfp-mb-2 rfp-mt-6 rfp-text-fg-primary\">{children}</h3>\n ),\n h4: ({ children }) => (\n <h4 className=\"rfp-text-lg rfp-font-semibold rfp-mb-2 rfp-mt-4 rfp-text-fg-primary\">{children}</h4>\n ),\n p: ({ children }) => (\n <p className=\"rfp-text-fg-secondary rfp-mb-4 rfp-leading-7 rfp-text-base\">{children}</p>\n ),\n a: ({ href, children }) => (\n <a\n href={href}\n className=\"rfp-text-indigo-400 hover:rfp-text-indigo-300 rfp-underline rfp-decoration-indigo-600 hover:rfp-decoration-indigo-400\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </a>\n ),\n ul: ({ children }) => (\n <ul className=\"rfp-list-disc rfp-pl-6 rfp-mb-4 rfp-text-fg-secondary rfp-space-y-1\">{children}</ul>\n ),\n ol: ({ children }) => (\n <ol className=\"rfp-list-decimal rfp-pl-6 rfp-mb-4 rfp-text-fg-secondary rfp-space-y-1\">{children}</ol>\n ),\n li: ({ children }) => <li className=\"rfp-leading-7\">{children}</li>,\n blockquote: ({ children }) => (\n <blockquote className=\"rfp-border-l-4 rfp-border-line-strong rfp-pl-4 rfp-text-fg-tertiary rfp-my-4 rfp-italic\">\n {children}\n </blockquote>\n ),\n table: ({ children }) => (\n <div className=\"rfp-overflow-x-auto rfp-my-4 rfp-rounded-md rfp-border rfp-border-line\">\n <table className=\"rfp-min-w-full rfp-divide-y rfp-divide-divide\">{children}</table>\n </div>\n ),\n thead: ({ children }) => <thead className=\"rfp-bg-surface-1\">{children}</thead>,\n tbody: ({ children }) => (\n <tbody className=\"rfp-divide-y rfp-divide-divide rfp-bg-transparent\">{children}</tbody>\n ),\n tr: ({ children }) => (\n <tr className=\"hover:rfp-bg-surface-1 rfp-transition-colors\">{children}</tr>\n ),\n th: ({ children }) => (\n <th className=\"rfp-px-4 rfp-py-3 rfp-text-left rfp-text-xs rfp-font-semibold rfp-text-fg-tertiary rfp-uppercase rfp-tracking-wider\">\n {children}\n </th>\n ),\n td: ({ children }) => (\n <td className=\"rfp-px-4 rfp-py-3 rfp-text-sm rfp-text-fg-secondary\">{children}</td>\n ),\n hr: () => <hr className=\"rfp-border-line rfp-my-6\" />,\n img: ({ src, alt }) => (\n <img\n src={src}\n alt={alt}\n className=\"rfp-rounded-md rfp-max-w-full rfp-h-auto rfp-my-4 rfp-mx-auto rfp-block rfp-shadow-sm\"\n />\n ),\n input: ({ type, checked, ...props }) => {\n if (type === 'checkbox') {\n return (\n <input\n type=\"checkbox\"\n checked={checked}\n readOnly\n className=\"rfp-mr-2 rfp-rounded rfp-border-line\"\n {...props}\n />\n );\n }\n return <input type={type} {...props} />;\n },\n strong: ({ children }) => (\n <strong className=\"rfp-font-semibold rfp-text-fg-primary\">{children}</strong>\n ),\n em: ({ children }) => <em className=\"rfp-italic\">{children}</em>,\n del: ({ children }) => (\n <del className=\"rfp-text-fg-muted rfp-line-through\">{children}</del>\n ),\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n </div>\n );\n};\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { ChevronRight, ChevronDown } from 'lucide-react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useResolvedTheme, type ResolvedTheme } from '../../ThemeContext';\n\ninterface JsonRendererProps {\n url: string;\n fileName: string;\n}\n\ninterface JsonColors {\n key: string;\n string: string;\n number: string;\n keyword: string;\n bracket: string; // { } [ ]\n colon: string; // :\n collapsed: string; // \"N items / N keys\" 折叠提示\n arrow: string; // 折叠箭头\n}\n\n// VSCode Dark Plus / GitHub Light 两套配色,与 react-syntax-highlighter 的 vscDarkPlus / vs 主题保持一致\nconst DARK_COLORS: JsonColors = {\n key: '#9cdcfe',\n string: '#ce9178',\n number: '#b5cea8',\n keyword: '#569cd6',\n bracket: '#d4d4d4',\n colon: 'rgb(255 255 255 / 0.6)',\n collapsed: 'rgb(255 255 255 / 0.4)',\n arrow: 'rgb(255 255 255 / 0.5)',\n};\n\nconst LIGHT_COLORS: JsonColors = {\n key: '#005cc5',\n string: '#032f62',\n number: '#005cc5',\n keyword: '#d73a49',\n bracket: '#24292e',\n colon: 'rgb(23 23 23 / 0.6)',\n collapsed: 'rgb(23 23 23 / 0.45)',\n arrow: 'rgb(23 23 23 / 0.55)',\n};\n\n// ---------- JSON 树节点 ----------\n\ninterface JsonNodeProps {\n keyName?: string;\n value: unknown;\n depth: number;\n defaultExpanded: boolean;\n colors: JsonColors;\n}\n\nconst JsonNode: React.FC<JsonNodeProps> = ({ keyName, value, depth, defaultExpanded, colors }) => {\n const t = useTranslator();\n const [expanded, setExpanded] = useState(defaultExpanded);\n const indent = depth * 20;\n\n const toggle = useCallback(() => setExpanded(prev => !prev), []);\n\n // 基本类型\n if (value === null || value === undefined || typeof value !== 'object') {\n return (\n <div className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm\" style={{ paddingLeft: `${indent}px` }}>\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0\" />\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n {renderPrimitive(value, colors)}\n </div>\n );\n }\n\n const isArray = Array.isArray(value);\n const entries = isArray ? (value as unknown[]) : Object.entries(value as Record<string, unknown>);\n const count = entries.length;\n const openBracket = isArray ? '[' : '{';\n const closeBracket = isArray ? ']' : '}';\n\n // 空对象/数组\n if (count === 0) {\n return (\n <div className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm\" style={{ paddingLeft: `${indent}px` }}>\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0\" />\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n <span style={{ color: colors.bracket }}>{openBracket}{closeBracket}</span>\n </div>\n );\n }\n\n return (\n <div>\n {/* 折叠行 */}\n <div\n className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm rfp-cursor-pointer hover:rfp-bg-surface-1 rfp-select-none\"\n style={{ paddingLeft: `${indent}px` }}\n onClick={toggle}\n >\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0 rfp-flex rfp-items-center rfp-justify-center\" style={{ color: colors.arrow }}>\n {expanded\n ? <ChevronDown className=\"rfp-w-3.5 rfp-h-3.5\" />\n : <ChevronRight className=\"rfp-w-3.5 rfp-h-3.5\" />\n }\n </span>\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n <span style={{ color: colors.bracket }}>{openBracket}</span>\n {!expanded && (\n <span className=\"rfp-ml-1\" style={{ color: colors.collapsed }}>\n {isArray ? `${count} ${t('json.items')}` : `${count} ${t('json.keys')}`}\n <span style={{ color: colors.bracket }}> {closeBracket}</span>\n </span>\n )}\n </div>\n\n {/* 子节点 */}\n {expanded && (\n <>\n {isArray\n ? (value as unknown[]).map((item, i) => (\n <JsonNode key={i} value={item} depth={depth + 1} defaultExpanded={depth < 1} colors={colors} />\n ))\n : Object.entries(value as Record<string, unknown>).map(([k, v]) => (\n <JsonNode key={k} keyName={k} value={v} depth={depth + 1} defaultExpanded={depth < 1} colors={colors} />\n ))\n }\n <div className=\"rfp-font-mono rfp-text-sm rfp-py-px\" style={{ paddingLeft: `${indent + 20}px`, color: colors.bracket }}>\n {closeBracket}\n </div>\n </>\n )}\n </div>\n );\n};\n\nfunction renderPrimitive(value: unknown, colors: JsonColors) {\n if (value === null) return <span style={{ color: colors.keyword, fontStyle: 'italic' }}>null</span>;\n if (value === undefined) return <span style={{ color: colors.keyword, fontStyle: 'italic' }}>undefined</span>;\n if (typeof value === 'boolean') return <span style={{ color: colors.keyword }}>{String(value)}</span>;\n if (typeof value === 'number') return <span style={{ color: colors.number }}>{String(value)}</span>;\n if (typeof value === 'string') return <span style={{ color: colors.string }}>\"{value}\"</span>;\n return <span style={{ color: colors.bracket }}>{String(value)}</span>;\n}\n\nfunction pickColors(theme: ResolvedTheme): JsonColors {\n return theme === 'light' ? LIGHT_COLORS : DARK_COLORS;\n}\n\n// ---------- Main ----------\n\nexport const JsonRenderer: React.FC<JsonRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const resolvedTheme = useResolvedTheme();\n const colors = useMemo(() => pickColors(resolvedTheme), [resolvedTheme]);\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const loadJson = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher });\n setData(JSON.parse(text));\n } catch (err) {\n setError(t('json.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n loadJson();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg rfp-py-3 rfp-pr-4\">\n <JsonNode value={data} depth={0} defaultExpanded colors={colors} />\n </div>\n );\n};\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { FileSpreadsheet } from 'lucide-react';\nimport Spreadsheet from 'x-data-spreadsheet';\nimport 'x-data-spreadsheet/dist/xspreadsheet.css';\nimport {\n parseCsv,\n guessCsvDelimiter,\n fetchTextUtf8,\n convertCsvToSpreadsheetData,\n} from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface CsvRendererProps {\n url: string;\n fileName: string;\n}\n\nexport const CsvRenderer: React.FC<CsvRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const spreadsheetRef = useRef<Spreadsheet | null>(null);\n const sheetDataRef = useRef<Record<string, unknown>[] | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 800, height: 600 };\n const rawWidth = containerRef.current.clientWidth;\n const rawHeight = containerRef.current.clientHeight;\n const width = rawWidth > 100 ? rawWidth : 800;\n const height = rawHeight > 100 ? rawHeight : 600;\n return { width, height };\n }, []);\n\n const mountSpreadsheet = useCallback(() => {\n if (!containerRef.current || !sheetDataRef.current) return;\n\n containerRef.current.innerHTML = '';\n spreadsheetRef.current = null;\n\n const { width, height } = calculateDimensions();\n const isMobile = width < 640;\n\n const s = new Spreadsheet(containerRef.current, {\n mode: 'read',\n showToolbar: false,\n showContextmenu: false,\n showGrid: true,\n row: {\n len: 100,\n height: 25,\n },\n col: {\n len: 26,\n width: isMobile ? 80 : 100,\n indexWidth: isMobile ? 40 : 60,\n minWidth: isMobile ? 40 : 60,\n },\n view: {\n height: () => height,\n width: () => width,\n },\n });\n\n s.loadData(sheetDataRef.current as unknown as Record<string, unknown>);\n spreadsheetRef.current = s;\n }, [calculateDimensions]);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensionsRef.current = newDimensions;\n\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (sheetDataRef.current) {\n mountSpreadsheet();\n }\n }, 500);\n };\n\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, mountSpreadsheet]);\n\n useEffect(() => {\n let isMounted = true;\n\n const loadCsv = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const text = await fetchTextUtf8(url, { fetcher });\n const parsed = parseCsv(text, { delimiter: guessCsvDelimiter(fileName) });\n const sheetData = convertCsvToSpreadsheetData(parsed.header, parsed.rows, fileName);\n\n if (!isMounted) return;\n\n sheetDataRef.current = sheetData as unknown as Record<string, unknown>[];\n mountSpreadsheet();\n setLoading(false);\n } catch (err) {\n if (isMounted) {\n console.error('CSV 解析错误:', err);\n setError(t('csv.load_failed'));\n setLoading(false);\n }\n }\n };\n\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n loadCsv();\n });\n }, 100);\n\n return () => {\n isMounted = false;\n clearTimeout(timer);\n sheetDataRef.current = null;\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n spreadsheetRef.current = null;\n };\n }, [url, fileName, mountSpreadsheet]);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('csv.loading')}</p>\n </div>\n </div>\n )}\n\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4\">\n <div className=\"rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-green-500 rfp-via-emerald-500 rfp-to-teal-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl\">\n <FileSpreadsheet className=\"rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary\" />\n </div>\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium\">{t('csv.load_failed')}</p>\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6\">{error}</p>\n </div>\n </div>\n )}\n\n {!error && (\n <div\n ref={containerRef}\n className=\"xlsx-spreadsheet-container rfp-w-full rfp-h-full\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n};\n","import { useState, useEffect } from 'react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\n\ninterface XmlRendererProps {\n url: string;\n fileName: string;\n}\n\n/**\n * 用 DOMParser 美化 XML:失败则原样返回\n */\nconst prettyPrintXml = (xml: string): string => {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'application/xml');\n // 检测解析错误\n const errNode = doc.querySelector('parsererror');\n if (errNode) return xml;\n // 使用 XSLT 或手动缩进:这里手动缩进更稳\n const serializer = new XMLSerializer();\n const serialized = serializer.serializeToString(doc);\n return indentXml(serialized);\n } catch {\n return xml;\n }\n};\n\nconst indentXml = (xml: string): string => {\n const PADDING = ' ';\n const reg = /(>)(<)(\\/*)/g;\n let formatted = xml.replace(reg, '$1\\n$2$3');\n // 自闭合和 CDATA 等不处理\n let pad = 0;\n return formatted\n .split('\\n')\n .map((line) => {\n let indent = 0;\n if (/^<\\/\\w/.test(line)) {\n pad = Math.max(pad - 1, 0);\n } else if (/^<\\w[^>]*[^/]>.*$/.test(line) && !/<.+<\\/.+>$/.test(line)) {\n indent = 1;\n }\n const padded = PADDING.repeat(pad) + line;\n pad += indent;\n return padded;\n })\n .join('\\n');\n};\n\nexport const XmlRenderer: React.FC<XmlRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const { html: highlighted } = useShikiHighlight(content, 'xml');\n\n useEffect(() => {\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n const raw = await fetchTextUtf8(url, { fetcher });\n setContent(prettyPrintXml(raw));\n } catch (err) {\n console.error(err);\n setError(t('xml.load_failed'));\n } finally {\n setLoading(false);\n }\n };\n load();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {highlighted ? (\n <div\n className=\"rfp-shiki-wrapper with-line-numbers\"\n dangerouslySetInnerHTML={{ __html: highlighted }}\n />\n ) : (\n <pre className=\"rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm rfp-whitespace-pre-wrap rfp-break-words\">\n {content}\n </pre>\n )}\n </div>\n );\n};\n","import { useState, useEffect, useMemo } from 'react';\nimport {\n parseSubtitle,\n formatSubtitleTime,\n fetchTextUtf8,\n type SubtitleParseResult,\n type SubtitleFormat,\n} from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\ninterface SubtitleRendererProps {\n url: string;\n fileName: string;\n}\n\nconst FORMAT_BY_EXT: Record<string, SubtitleFormat> = {\n srt: 'srt',\n vtt: 'vtt',\n lrc: 'lrc',\n elrc: 'elrc',\n ass: 'ass',\n ssa: 'ssa',\n ttml: 'ttml',\n dfxp: 'ttml',\n};\n\nconst getFormat = (fileName: string): SubtitleFormat | undefined => {\n const ext = fileName.split('.').pop()?.toLowerCase() || '';\n return FORMAT_BY_EXT[ext];\n};\n\nexport const SubtitleRenderer: React.FC<SubtitleRendererProps> = ({ url, fileName }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [text, setText] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n setText(await fetchTextUtf8(url, { fetcher }));\n } catch (err) {\n console.error(err);\n setError(t('subtitle.load_failed'));\n } finally {\n setLoading(false);\n }\n };\n load();\n }, [url]);\n\n const parsed: SubtitleParseResult | null = useMemo(() => {\n if (!text) return null;\n try {\n return parseSubtitle(text, getFormat(fileName));\n } catch (err) {\n console.error(err);\n return null;\n }\n }, [text, fileName]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !parsed) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('subtitle.parse_failed')}</p>\n </div>\n </div>\n );\n }\n\n const isLyric = parsed.format === 'lrc' || parsed.format === 'elrc';\n const meta = parsed.metadata ?? {};\n const dotHover = isLyric ? 'group-hover:rfp-bg-violet-400' : 'group-hover:rfp-bg-sky-400';\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-bg-[#0f0f12]\">\n {/* 内容滚动区 */}\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-px-6 md:rfp-px-10 rfp-pt-6 rfp-pb-16 md:rfp-pb-20\">\n <div className=\"rfp-relative rfp-max-w-5xl rfp-mx-auto\">\n {/* vertical line */}\n <div className=\"rfp-absolute rfp-left-[5px] md:rfp-left-[7px] rfp-top-2 rfp-bottom-2 rfp-w-px rfp-bg-surface-1\" />\n\n <ol className=\"rfp-space-y-5 md:rfp-space-y-6\">\n {parsed.cues.map((cue, i) => (\n <li key={`cue-${i}`} className=\"rfp-relative rfp-pl-6 md:rfp-pl-8 rfp-group\">\n {/* dot */}\n <div\n className={`rfp-absolute rfp-left-0 rfp-top-2 rfp-w-3 rfp-h-3 rfp-rounded-full rfp-bg-surface-3 rfp-border-2 rfp-border-[#0f0f12] rfp-transition-colors ${dotHover}`}\n />\n\n <div className=\"rfp-flex rfp-flex-wrap rfp-items-baseline rfp-gap-x-3 rfp-gap-y-1 rfp-mb-1.5\">\n <span className=\"rfp-text-[11px] rfp-font-mono rfp-text-fg-muted rfp-tabular-nums\">\n {formatSubtitleTime(cue.start)}\n </span>\n <span className=\"rfp-text-[11px] rfp-text-fg-disabled\">→</span>\n <span className=\"rfp-text-[11px] rfp-font-mono rfp-text-fg-muted rfp-tabular-nums\">\n {formatSubtitleTime(cue.end)}\n </span>\n <span className=\"rfp-text-[10px] rfp-font-mono rfp-text-fg-disabled rfp-tabular-nums\">\n #{cue.id ?? i + 1}\n </span>\n {cue.style && (\n <span className=\"rfp-text-[9px] rfp-uppercase rfp-tracking-widest rfp-text-fg-tertiary rfp-px-1.5 rfp-py-0.5 rfp-rounded rfp-bg-surface-1 rfp-border rfp-border-line-weak\">\n {cue.style}\n </span>\n )}\n </div>\n\n {cue.words && cue.words.length > 0 ? (\n <div className=\"rfp-flex rfp-flex-wrap rfp-gap-x-1.5 rfp-gap-y-1 rfp-text-base md:rfp-text-lg rfp-text-fg-primary rfp-leading-relaxed group-hover:rfp-text-fg-primary rfp-transition-colors\">\n {cue.words.map((word, wi) => (\n <span\n key={`w-${wi}`}\n className=\"rfp-inline-flex rfp-flex-col rfp-items-start\"\n title={formatSubtitleTime(word.start)}\n >\n <span className=\"rfp-text-[9px] rfp-text-fg-disabled rfp-font-mono rfp-leading-none rfp-tabular-nums\">\n {formatSubtitleTime(word.start).slice(3, 8)}\n </span>\n <span className=\"rfp-leading-snug\">{word.text}</span>\n </span>\n ))}\n </div>\n ) : (\n <p\n className={`rfp-whitespace-pre-wrap rfp-break-words rfp-leading-relaxed group-hover:rfp-text-fg-primary rfp-transition-colors rfp-text-fg-primary ${\n isLyric ? 'rfp-text-base md:rfp-text-xl rfp-font-medium' : 'rfp-text-sm md:rfp-text-base'\n }`}\n >\n {cue.text}\n </p>\n )}\n </li>\n ))}\n </ol>\n </div>\n </div>\n\n {/* 底部状态栏 */}\n <div className=\"rfp-pointer-events-none rfp-absolute rfp-bottom-3 rfp-right-3 md:rfp-bottom-4 md:rfp-right-4 rfp-flex rfp-items-center rfp-gap-2 rfp-px-2.5 rfp-py-1 rfp-rounded-full rfp-bg-surface-nav rfp-backdrop-blur rfp-border rfp-border-line-weak rfp-text-[10px] rfp-text-fg-tertiary rfp-font-mono rfp-tabular-nums\">\n <span>{parsed.cues.length} {isLyric ? t('subtitle.lines') : t('subtitle.cues')}</span>\n {meta.length && (\n <>\n <span className=\"rfp-text-fg-disabled\">·</span>\n <span>{meta.length}</span>\n </>\n )}\n </div>\n </div>\n );\n};\n","import React, { useEffect, useRef, useState, useCallback } from 'react';\n\nexport interface ResizableSplitProps {\n /** 左侧内容 */\n left: React.ReactNode;\n /** 右侧内容 */\n right: React.ReactNode;\n /** 左侧初始宽度(px);传入 storageKey 时会从 localStorage 读取 */\n initialLeftWidth?: number;\n /** 左侧最小宽度(px) */\n minLeftWidth?: number;\n /** 左侧最大宽度(px),同时不超过 `容器宽 - minRightWidth - 分隔线宽` */\n maxLeftWidth?: number;\n /** 右侧至少保留的宽度(px) */\n minRightWidth?: number;\n /** localStorage 持久化 key;不传则不持久化 */\n storageKey?: string;\n /** 启用横向拖动的媒体查询,默认 `(min-width: 768px)` */\n desktopMedia?: string;\n /** 容器额外类名 */\n className?: string;\n}\n\n/**\n * 通用可拖动分隔布局:\n * - 桌面端(由 `desktopMedia` 判定)横向分两栏,中间分隔线可左右拖动调整左栏宽度\n * - 移动端退化为上下堆叠,不显示分隔线\n * - 可选 `storageKey` 将宽度持久化到 localStorage\n */\nexport const ResizableSplit: React.FC<ResizableSplitProps> = ({\n left,\n right,\n initialLeftWidth = 280,\n minLeftWidth = 160,\n maxLeftWidth = 640,\n minRightWidth = 200,\n storageKey,\n desktopMedia = '(min-width: 768px)',\n className = '',\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [leftWidth, setLeftWidth] = useState<number>(() => {\n if (storageKey && typeof window !== 'undefined') {\n const saved = Number(window.localStorage.getItem(storageKey));\n if (!isNaN(saved) && saved > 0) return saved;\n }\n return initialLeftWidth;\n });\n const [dragging, setDragging] = useState(false);\n const [isDesktop, setIsDesktop] = useState(false);\n\n // 响应式:监听媒体查询\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia(desktopMedia);\n const handler = () => setIsDesktop(mq.matches);\n handler();\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, [desktopMedia]);\n\n // 拖动\n useEffect(() => {\n if (!dragging) return;\n const handleMove = (e: MouseEvent) => {\n if (!containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const cap = rect.width - minRightWidth - 6;\n const effectiveMax = Math.min(maxLeftWidth, cap);\n const newW = Math.max(minLeftWidth, Math.min(effectiveMax, x));\n setLeftWidth(newW);\n };\n const handleUp = () => setDragging(false);\n window.addEventListener('mousemove', handleMove);\n window.addEventListener('mouseup', handleUp);\n const prevCursor = document.body.style.cursor;\n const prevSelect = document.body.style.userSelect;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n return () => {\n window.removeEventListener('mousemove', handleMove);\n window.removeEventListener('mouseup', handleUp);\n document.body.style.cursor = prevCursor;\n document.body.style.userSelect = prevSelect;\n };\n }, [dragging, minLeftWidth, maxLeftWidth, minRightWidth]);\n\n // 持久化\n useEffect(() => {\n if (!storageKey || dragging) return;\n try {\n window.localStorage.setItem(storageKey, String(leftWidth));\n } catch {\n // ignore\n }\n }, [leftWidth, storageKey, dragging]);\n\n const handleDividerDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n setDragging(true);\n }, []);\n\n return (\n <div\n ref={containerRef}\n className={`rfp-w-full rfp-h-full rfp-flex rfp-flex-col md:rfp-flex-row rfp-min-h-0 rfp-min-w-0 ${className}`}\n >\n <div\n className=\"rfp-min-h-0 rfp-min-w-0 rfp-flex-shrink-0 rfp-w-full rfp-max-h-60 md:rfp-h-full md:rfp-max-h-none\"\n style={isDesktop ? { width: `${leftWidth}px` } : undefined}\n >\n {left}\n </div>\n {/* 分隔线:仅桌面显示 */}\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n onMouseDown={handleDividerDown}\n className={`rfp-hidden md:rfp-block rfp-relative rfp-w-1.5 rfp-flex-shrink-0 rfp-cursor-col-resize rfp-transition-colors ${\n dragging ? 'rfp-bg-surface-toolbar' : 'rfp-bg-surface-2 hover:rfp-bg-surface-3'\n }`}\n >\n {/* 加宽命中区,改善拖动体验 */}\n <span className=\"rfp-absolute rfp-inset-y-0 -rfp-left-1 -rfp-right-1\" />\n </div>\n <div className=\"rfp-flex-1 rfp-min-w-0 rfp-min-h-0 rfp-overflow-hidden\">{right}</div>\n </div>\n );\n};\n","import { useState, useEffect, useMemo, useCallback, useRef, lazy, Suspense } from 'react';\nimport React from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n Folder,\n FolderOpen,\n FileText,\n FileImage,\n FileCode,\n File as FileIcon,\n ChevronRight,\n} from 'lucide-react';\nimport type JSZip from 'jszip';\nimport {\n loadZip,\n listZipEntries,\n buildZipTree,\n readZipEntryBlob,\n formatFileSize,\n getFileType,\n inferMimeType,\n type ZipTreeNode,\n} from '@eternalheart/file-preview-core';\nimport { ResizableSplit } from '../../components/ResizableSplit';\nimport type { ZipToolbarStats } from './toolbar';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\n\n// 懒加载 FilePreviewContent 以打破循环依赖\nconst LazyFilePreviewContent = lazy(() =>\n import('../../FilePreviewContent').then(m => ({ default: m.FilePreviewContent }))\n);\n\ninterface ZipRendererProps {\n url: string;\n /** ZIP 嵌套深度(由 FilePreviewContent 传入) */\n nestingDepth?: number;\n /** 解析完成后向外回报统计信息(files / dirs / size),供工具栏展示 */\n onStatsChange?: (stats: ZipToolbarStats | null) => void;\n}\n\ninterface SelectedPreview {\n path: string;\n name: string;\n size: number;\n blobUrl: string;\n}\n\n/** 根据文件类型返回树节点图标 */\nconst resolveIcon = (name: string) => {\n const ft = getFileType({ id: '', name, url: '', type: '' });\n if (ft === 'image') return FileImage;\n if (ft === 'text' || ft === 'markdown' || ft === 'json' || ft === 'csv' || ft === 'xml' || ft === 'subtitle') {\n return name.endsWith('.md') || name.endsWith('.markdown') ? FileText : FileCode;\n }\n return FileIcon;\n};\n\n// ---------- Tooltip via portal ----------\n\ninterface HoverTipState {\n text: string;\n x: number;\n y: number;\n}\n\n// ---------- Tree item ----------\n\ninterface TreeItemProps {\n node: ZipTreeNode;\n depth: number;\n selectedPath: string | null;\n expanded: Set<string>;\n onToggle: (path: string) => void;\n onSelect: (node: ZipTreeNode) => void;\n onHover: (text: string, rect: DOMRect) => void;\n onLeave: () => void;\n}\n\nconst TreeItem: React.FC<TreeItemProps> = ({\n node,\n depth,\n selectedPath,\n expanded,\n onToggle,\n onSelect,\n onHover,\n onLeave,\n}) => {\n const isOpen = expanded.has(node.path);\n const isSelected = selectedPath === node.path;\n const pad = { paddingLeft: `${depth * 14 + 10}px` };\n const handleEnter = (e: React.MouseEvent<HTMLElement>) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n onHover(node.name || '/', rect);\n };\n\n if (node.isDir) {\n return (\n <>\n <button\n type=\"button\"\n onClick={() => onToggle(node.path)}\n onMouseEnter={handleEnter}\n onMouseLeave={onLeave}\n className=\"rfp-w-full rfp-flex rfp-items-center rfp-gap-1.5 rfp-py-1.5 rfp-pr-2 rfp-text-left rfp-text-fg-secondary hover:rfp-bg-surface-1 rfp-text-sm\"\n style={pad}\n >\n <ChevronRight\n className={`rfp-w-3.5 rfp-h-3.5 rfp-flex-shrink-0 rfp-transition-transform ${\n isOpen ? 'rfp-rotate-90' : ''\n }`}\n />\n {isOpen ? (\n <FolderOpen className=\"rfp-w-4 rfp-h-4 rfp-flex-shrink-0 rfp-text-amber-300/80\" />\n ) : (\n <Folder className=\"rfp-w-4 rfp-h-4 rfp-flex-shrink-0 rfp-text-amber-300/80\" />\n )}\n <span className=\"rfp-truncate rfp-flex-1 rfp-min-w-0\">{node.name || '/'}</span>\n </button>\n {isOpen &&\n node.children?.map((child) => (\n <TreeItem\n key={child.path}\n node={child}\n depth={depth + 1}\n selectedPath={selectedPath}\n expanded={expanded}\n onToggle={onToggle}\n onSelect={onSelect}\n onHover={onHover}\n onLeave={onLeave}\n />\n ))}\n </>\n );\n }\n\n const Icon = resolveIcon(node.name);\n\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(node)}\n onMouseEnter={handleEnter}\n onMouseLeave={onLeave}\n className={`rfp-w-full rfp-flex rfp-items-center rfp-gap-1.5 rfp-py-1.5 rfp-pr-2 rfp-text-left rfp-text-sm ${\n isSelected ? 'rfp-bg-surface-2 rfp-text-fg-primary' : 'rfp-text-fg-secondary hover:rfp-bg-surface-1'\n }`}\n style={pad}\n >\n <span className=\"rfp-w-3.5 rfp-h-3.5 rfp-flex-shrink-0\" />\n <Icon className=\"rfp-w-4 rfp-h-4 rfp-flex-shrink-0 rfp-text-fg-tertiary\" />\n <span className=\"rfp-flex-1 rfp-truncate rfp-min-w-0\">{node.name}</span>\n <span className=\"rfp-text-xs rfp-text-fg-disabled rfp-flex-shrink-0 rfp-ml-2\">\n {formatFileSize(node.size)}\n </span>\n </button>\n );\n};\n\n// ---------- Main Zip Renderer ----------\n\nexport const ZipRenderer: React.FC<ZipRendererProps> = ({ url, nestingDepth = 0, onStatsChange }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [zip, setZip] = useState<JSZip | null>(null);\n const [tree, setTree] = useState<ZipTreeNode | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [expanded, setExpanded] = useState<Set<string>>(new Set(['']));\n const [selected, setSelected] = useState<SelectedPreview | null>(null);\n const [previewLoading, setPreviewLoading] = useState(false);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [hoverTip, setHoverTip] = useState<HoverTipState | null>(null);\n const onStatsChangeRef = useRef(onStatsChange);\n\n useEffect(() => {\n onStatsChangeRef.current = onStatsChange;\n }, [onStatsChange]);\n\n useEffect(() => {\n let cancelled = false;\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n const res = await fetcher(url);\n if (!res.ok) throw new Error('加载失败');\n const buf = await res.arrayBuffer();\n const z = await loadZip(buf);\n if (cancelled) return;\n const entries = listZipEntries(z);\n const root = buildZipTree(entries);\n setZip(z);\n setTree(root);\n const init = new Set<string>(['']);\n if (root.children) {\n for (const c of root.children) if (c.isDir) init.add(c.path);\n }\n setExpanded(init);\n } catch (err) {\n console.error(err);\n if (!cancelled) setError(t('zip.load_failed'));\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n load();\n return () => {\n cancelled = true;\n };\n }, [url]);\n\n // 切换文件时回收 blob URL\n useEffect(() => {\n return () => {\n if (selected?.blobUrl) URL.revokeObjectURL(selected.blobUrl);\n };\n }, [selected]);\n\n const totalStats = useMemo<ZipToolbarStats | null>(() => {\n if (!tree) return null;\n let files = 0;\n let dirs = 0;\n let size = 0;\n const walk = (n: ZipTreeNode) => {\n if (n.isDir) {\n if (n.path) dirs++;\n n.children?.forEach(walk);\n } else {\n files++;\n size += n.size;\n }\n };\n walk(tree);\n return { files, dirs, size };\n }, [tree]);\n\n // 向外回报 stats\n useEffect(() => {\n onStatsChangeRef.current?.(totalStats);\n return () => {\n onStatsChangeRef.current?.(null);\n };\n }, [totalStats]);\n\n const handleToggle = useCallback((path: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n return next;\n });\n }, []);\n\n const handleHover = useCallback((text: string, rect: DOMRect) => {\n setHoverTip({\n text,\n x: rect.right + 8,\n y: rect.top + rect.height / 2,\n });\n }, []);\n\n const handleLeave = useCallback(() => {\n setHoverTip(null);\n }, []);\n\n const handleSelect = useCallback(\n async (node: ZipTreeNode) => {\n if (!zip || node.isDir) return;\n if (selected?.blobUrl) URL.revokeObjectURL(selected.blobUrl);\n setPreviewLoading(true);\n setPreviewError(null);\n\n try {\n const mime = inferMimeType(node.name);\n const blob = await readZipEntryBlob(zip, node.path, mime !== 'application/octet-stream' ? mime : undefined);\n const blobUrl = URL.createObjectURL(blob);\n setSelected({ path: node.path, name: node.name, size: node.size, blobUrl });\n } catch (err) {\n console.error(err);\n setPreviewError('条目读取失败');\n } finally {\n setPreviewLoading(false);\n }\n },\n [zip, selected]\n );\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !tree) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('zip.parse_failed')}</p>\n </div>\n </div>\n );\n }\n\n // 左侧:文件树\n const leftPane = (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto\">\n {tree.children?.map((child) => (\n <TreeItem\n key={child.path}\n node={child}\n depth={0}\n selectedPath={selected?.path ?? null}\n expanded={expanded}\n onToggle={handleToggle}\n onSelect={handleSelect}\n onHover={handleHover}\n onLeave={handleLeave}\n />\n ))}\n </div>\n );\n\n // 右侧:预览区\n const rightPane = (\n <div className=\"rfp-w-full rfp-h-full rfp-flex rfp-flex-col\">\n {!selected && (\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-muted rfp-text-sm rfp-p-6\">\n 从左侧选择一个文件以预览\n </div>\n )}\n {selected && previewLoading && (\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n {selected && !previewLoading && previewError && (\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center rfp-text-fg-secondary\">\n {previewError}\n </div>\n )}\n {selected && !previewLoading && !previewError && (\n <>\n <div className=\"rfp-flex-1 rfp-min-h-0 rfp-overflow-hidden rfp-flex rfp-relative rfp-z-0\">\n <Suspense\n fallback={\n <div className=\"rfp-flex-1 rfp-flex rfp-items-center rfp-justify-center\">\n <div className=\"rfp-w-8 rfp-h-8 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n }\n >\n <LazyFilePreviewContent\n mode=\"embed\"\n files={[{ name: selected.name, url: selected.blobUrl, type: inferMimeType(selected.name) }]}\n currentIndex={0}\n zipNestingDepth={nestingDepth + 1}\n />\n </Suspense>\n </div>\n </>\n )}\n </div>\n );\n\n return (\n <>\n <ResizableSplit\n left={leftPane}\n right={rightPane}\n initialLeftWidth={280}\n minLeftWidth={180}\n maxLeftWidth={560}\n storageKey=\"rfp-zip-split-left\"\n />\n {/* 文件名 hover tooltip(portal 到 body,避免被滚动区裁剪) */}\n {hoverTip &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n className=\"rfp-fixed rfp-z-[9999] rfp-pointer-events-none rfp-px-2 rfp-py-1 rfp-bg-[rgba(0,0,0,0.85)] rfp-text-fg-primary rfp-text-xs rfp-rounded rfp-whitespace-nowrap rfp-shadow-lg\"\n style={{\n left: `${hoverTip.x}px`,\n top: `${hoverTip.y}px`,\n transform: 'translateY(-50%)',\n }}\n >\n {hoverTip.text}\n </div>,\n document.body\n )}\n </>\n );\n};\n","import { useState, useEffect } from 'react';\nimport { fetchTextUtf8, getLanguageFromFileName } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\n\ninterface TextRendererProps {\n url: string;\n fileName: string;\n wordWrap?: boolean;\n htmlPreview?: boolean;\n}\n\nexport const TextRenderer: React.FC<TextRendererProps> = ({\n url,\n fileName,\n wordWrap = true,\n htmlPreview = false,\n}) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const language = getLanguageFromFileName(fileName);\n const { html: highlighted } = useShikiHighlight(\n language !== 'text' ? content : '',\n language,\n );\n\n useEffect(() => {\n const loadText = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url, { fetcher });\n setContent(text);\n } catch (err) {\n setError(t('text.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n\n loadText();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n // HTML 预览模式\n if (htmlPreview && (language === 'html')) {\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-bg-surface-toolbar\">\n <iframe\n srcDoc={content}\n sandbox=\"allow-same-origin\"\n className=\"rfp-w-full rfp-h-full rfp-border-0\"\n title={fileName}\n />\n </div>\n );\n }\n\n // 源码模式\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {language === 'text' || !highlighted ? (\n <pre\n className={`rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm ${\n wordWrap ? 'rfp-whitespace-pre-wrap rfp-break-words' : 'rfp-whitespace-pre'\n }`}\n >\n {content}\n </pre>\n ) : (\n <div\n className={`rfp-shiki-wrapper with-line-numbers ${wordWrap ? '' : 'no-wrap'}`}\n dangerouslySetInnerHTML={{ __html: highlighted }}\n />\n )}\n </div>\n );\n};\n","import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { parse } from 'opentype.js';\nimport type { Font as OpentypeFont } from 'opentype.js';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useResolvedTheme } from '../../ThemeContext';\n\nexport interface FontRendererProps {\n url: string;\n}\n\ninterface FontMetadata {\n family: string;\n subfamily: string;\n version: string;\n designer: string;\n glyphCount: number;\n format: string;\n}\n\nconst DEFAULT_SAMPLES = {\n latin: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ\\nabcdefghijklmnopqrstuvwxyz\\n0123456789 .,;:!?@#$%&*()[]{}',\n chinese: '春夏秋冬东南西北天地人和风雨雷电山水日月',\n mixed: 'The Quick Brown Fox Jumps Over The Lazy Dog\\n敏捷的棕色狐狸跳过了懒狗',\n};\n\nconst SIZES = [72, 48, 36, 24, 18];\n\n// 渲染模式:FontFace 用原生字体渲染,Canvas 用 opentype.js 软渲染(兼容浏览器拒绝的字体)\ntype RenderMode = 'fontface' | 'canvas';\n\nexport const FontRenderer: React.FC<FontRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const resolvedTheme = useResolvedTheme();\n const [font, setFont] = useState<OpentypeFont | null>(null);\n const [metadata, setMetadata] = useState<FontMetadata | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [customText, setCustomText] = useState('');\n const [renderMode, setRenderMode] = useState<RenderMode>('fontface');\n const fontFaceRef = useRef<FontFace | null>(null);\n\n useEffect(() => {\n let mounted = true;\n\n const loadFont = async () => {\n try {\n setLoading(true);\n setError(null);\n\n // 使用 fetcher 替代原生 fetch(支持鉴权)\n const response = await fetcher(url);\n if (!response.ok) {\n throw new Error('Failed to load font file');\n }\n const arrayBuffer = await response.arrayBuffer();\n\n if (!mounted) return;\n\n // 为 FontFace 克隆一份 ArrayBuffer,避免 opentype.js 的 parse 影响其状态\n const faceBuffer = arrayBuffer.slice(0);\n\n // 解析字体文件(opentype.js 容忍度高于浏览器 OTS)\n // parse 返回值与官方 Font 类型存在不一致(opentype.js 类型定义瑕疵),用 unknown 二次转换\n const fontData = parse(arrayBuffer) as unknown as OpentypeFont;\n\n if (!fontData) {\n throw new Error('Font data is invalid');\n }\n\n // 提取元数据\n const names = fontData.names || {};\n const meta: FontMetadata = {\n family: names.fontFamily?.en || names.fontFamily?.['zh-Hans'] || names.postScriptName?.en || 'Unknown',\n subfamily: names.fontSubfamily?.en || names.fontSubfamily?.['zh-Hans'] || '',\n version: names.version?.en || '',\n designer: names.designer?.en || '',\n glyphCount: fontData.numGlyphs || 0,\n format: detectFormat(url),\n };\n\n if (!mounted) return;\n setFont(fontData);\n setMetadata(meta);\n\n // 尝试用 FontFace API 加载字体(浏览器原生渲染,性能好)\n // 失败时降级到 Canvas 软渲染(opentype.js 容忍度更高)\n try {\n const face = new FontFace('PreviewFont', faceBuffer);\n await face.load();\n if (!mounted) return;\n document.fonts.add(face);\n fontFaceRef.current = face;\n setRenderMode('fontface');\n } catch (faceErr) {\n // 浏览器拒绝该字体(通常是 OTS sanitizer 校验失败),降级到 Canvas 渲染\n console.warn('[FontRenderer] FontFace API rejected, fallback to Canvas:', faceErr);\n if (!mounted) return;\n setRenderMode('canvas');\n }\n\n if (mounted) setLoading(false);\n } catch (err) {\n if (!mounted) return;\n console.error('[FontRenderer] Error:', err);\n let errorMsg = t('font.load_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n }\n setError(errorMsg);\n setLoading(false);\n }\n };\n\n loadFont();\n\n return () => {\n mounted = false;\n if (fontFaceRef.current) {\n document.fonts.delete(fontFaceRef.current);\n fontFaceRef.current = null;\n }\n };\n }, [url, fetcher, t]);\n\n const detectFormat = (url: string): string => {\n const ext = url.split('.').pop()?.toLowerCase().split('?')[0] || '';\n const formatMap: Record<string, string> = {\n ttf: 'TrueType (TTF)',\n otf: 'OpenType (OTF)',\n woff: 'Web Open Font Format (WOFF)',\n woff2: 'Web Open Font Format 2 (WOFF2)',\n };\n return formatMap[ext] || 'TTF';\n };\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary\">{t('font.loading')}</div>\n </div>\n );\n }\n\n if (error || !font || !metadata) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary\">{error || t('font.parse_failed')}</div>\n </div>\n );\n }\n\n const displayText = customText || DEFAULT_SAMPLES.mixed;\n\n return (\n <div className=\"rfp-flex rfp-flex-col rfp-w-full rfp-h-full rfp-overflow-hidden rfp-min-w-0\">\n {/* 元数据区 */}\n <div className=\"rfp-flex-shrink-0 rfp-px-6 rfp-py-4 rfp-bg-surface-1 rfp-border-b rfp-border-line-weak rfp-min-w-0\">\n <div className=\"rfp-grid rfp-grid-cols-2 rfp-gap-x-6 rfp-gap-y-2 rfp-text-sm rfp-min-w-0\">\n <div className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-min-w-0\">\n <span className=\"rfp-text-fg-tertiary rfp-flex-shrink-0\">{t('font.meta.family')}:</span>\n <span className=\"rfp-text-fg-primary rfp-font-semibold rfp-truncate\">{metadata.family}</span>\n </div>\n {metadata.subfamily && (\n <div className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-min-w-0\">\n <span className=\"rfp-text-fg-tertiary rfp-flex-shrink-0\">{t('font.meta.subfamily')}:</span>\n <span className=\"rfp-text-fg-primary rfp-truncate\">{metadata.subfamily}</span>\n </div>\n )}\n <div className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-min-w-0\">\n <span className=\"rfp-text-fg-tertiary rfp-flex-shrink-0\">{t('font.meta.format')}:</span>\n <span className=\"rfp-text-fg-primary rfp-truncate\">{metadata.format}</span>\n </div>\n <div className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-min-w-0\">\n <span className=\"rfp-text-fg-tertiary rfp-flex-shrink-0\">{t('font.meta.glyphs')}:</span>\n <span className=\"rfp-text-fg-primary rfp-truncate\">{metadata.glyphCount}</span>\n </div>\n {metadata.designer && (\n <div className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-min-w-0\">\n <span className=\"rfp-text-fg-tertiary rfp-flex-shrink-0\">{t('font.meta.designer')}:</span>\n <span className=\"rfp-text-fg-primary rfp-truncate\">{metadata.designer}</span>\n </div>\n )}\n {metadata.version && (\n <div className=\"rfp-flex rfp-items-center rfp-gap-2 rfp-min-w-0\">\n <span className=\"rfp-text-fg-tertiary rfp-flex-shrink-0\">{t('font.meta.version')}:</span>\n <span className=\"rfp-text-fg-primary rfp-truncate\">{metadata.version}</span>\n </div>\n )}\n </div>\n </div>\n\n {/* 预览区 */}\n <div className=\"rfp-flex-1 rfp-overflow-auto rfp-min-w-0\">\n <div className=\"rfp-px-6 rfp-py-6 rfp-space-y-8 rfp-min-w-0\">\n {/* 自定义输入框 */}\n <div className=\"rfp-min-w-0\">\n <label className=\"rfp-block rfp-text-xs rfp-text-fg-tertiary rfp-mb-2\">\n {t('font.sample_text_placeholder')}\n </label>\n <textarea\n className=\"rfp-block rfp-w-full rfp-box-border rfp-px-3 rfp-py-2.5 rfp-bg-surface-2 rfp-text-fg-primary rfp-text-sm rfp-leading-relaxed rfp-border rfp-border-line rfp-rounded-md rfp-resize-y focus:rfp-outline-none focus:rfp-border-line-strong\"\n rows={2}\n placeholder={t('font.sample_text_placeholder')}\n value={customText}\n onChange={(e) => setCustomText(e.target.value)}\n style={{ minHeight: '64px', maxHeight: '160px' }}\n />\n </div>\n\n {/* 多字号展示 */}\n <div className=\"rfp-space-y-6 rfp-min-w-0\">\n {SIZES.map((size) => (\n <div key={size} className=\"rfp-space-y-2 rfp-min-w-0\">\n <div className=\"rfp-text-xs rfp-text-fg-tertiary\">{size}px</div>\n <FontPreviewLine\n font={font}\n text={displayText}\n fontSize={size}\n renderMode={renderMode}\n theme={resolvedTheme}\n />\n </div>\n ))}\n </div>\n\n {/* 字符集样例 */}\n <div className=\"rfp-space-y-6 rfp-pt-6 rfp-border-t rfp-border-line-weak rfp-min-w-0\">\n <div className=\"rfp-min-w-0\">\n <div className=\"rfp-text-sm rfp-text-fg-tertiary rfp-mb-3\">Latin Alphabet</div>\n <FontPreviewLine\n font={font}\n text={DEFAULT_SAMPLES.latin}\n fontSize={24}\n renderMode={renderMode}\n theme={resolvedTheme}\n />\n </div>\n\n <div className=\"rfp-min-w-0\">\n <div className=\"rfp-text-sm rfp-text-fg-tertiary rfp-mb-3\">Chinese Characters</div>\n <FontPreviewLine\n font={font}\n text={DEFAULT_SAMPLES.chinese}\n fontSize={24}\n renderMode={renderMode}\n theme={resolvedTheme}\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\ninterface FontPreviewLineProps {\n font: OpentypeFont;\n text: string;\n fontSize: number;\n renderMode: RenderMode;\n theme: 'dark' | 'light';\n}\n\n// 单行字体预览:FontFace 模式用 div + CSS font-family(自动换行),\n// Canvas 模式用 opentype.js 软渲染并按容器宽度自动断行\nconst FontPreviewLine: React.FC<FontPreviewLineProps> = ({ font, text, fontSize, renderMode, theme }) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const drawCanvas = useCallback(() => {\n const wrapper = wrapperRef.current;\n const canvas = canvasRef.current;\n if (!wrapper || !canvas || renderMode !== 'canvas') return;\n\n const containerWidth = wrapper.clientWidth || 600;\n const dpr = window.devicePixelRatio || 1;\n const lineHeight = fontSize * 1.4;\n const fillColor = theme === 'light' ? '#1f2937' : '#f3f4f6';\n\n // 按容器宽度做软换行:先按 \\n 拆段,再按字宽贪心断行\n const wrapLine = (line: string): string[] => {\n if (!line) return [''];\n const result: string[] = [];\n let buf = '';\n for (const ch of Array.from(line)) {\n const next = buf + ch;\n const w = font.getAdvanceWidth(next, fontSize);\n if (w > containerWidth && buf) {\n result.push(buf);\n buf = ch;\n } else {\n buf = next;\n }\n }\n if (buf) result.push(buf);\n return result;\n };\n\n const wrappedLines: string[] = [];\n text.split('\\n').forEach((seg) => {\n wrapLine(seg).forEach((l) => wrappedLines.push(l));\n });\n\n const width = containerWidth;\n const height = lineHeight * wrappedLines.length + 4;\n\n // 高 DPI 适配\n canvas.width = Math.max(1, Math.floor(width * dpr));\n canvas.height = Math.max(1, Math.floor(height * dpr));\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, width, height);\n\n wrappedLines.forEach((line, idx) => {\n const path = font.getPath(line, 0, fontSize + idx * lineHeight, fontSize);\n path.fill = fillColor;\n path.draw(ctx);\n });\n }, [font, text, fontSize, renderMode, theme]);\n\n useEffect(() => {\n if (renderMode !== 'canvas') return;\n drawCanvas();\n // 容器尺寸变化时重绘\n const wrapper = wrapperRef.current;\n if (!wrapper || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => drawCanvas());\n observer.observe(wrapper);\n return () => observer.disconnect();\n }, [drawCanvas, renderMode]);\n\n if (renderMode === 'canvas') {\n return (\n <div ref={wrapperRef} className=\"rfp-w-full\">\n <canvas ref={canvasRef} className=\"rfp-block\" />\n </div>\n );\n }\n\n return (\n <div\n ref={wrapperRef}\n className=\"rfp-w-full rfp-text-fg-primary rfp-whitespace-pre-wrap rfp-break-words\"\n style={{\n fontFamily: 'PreviewFont, sans-serif',\n fontSize: `${fontSize}px`,\n lineHeight: 1.4,\n }}\n >\n {text}\n </div>\n );\n};\n"],"names":["dt","U","e","n","k","t","A","o","ft","ut","r","pt","ht","xt","bt","a","i","s","c","u","d","f","$","Ft","B","W","wt","vt","yt","E","_t","z","Z","V","L","l","p","T","R","O","m","q","h","F","b","g","x","D","N","w","y","v","_","S","H","Ct","kt","j","St","Tt","Et","G","J","X","K","Q","M","Y","tt","et","ot","nt","rt","P","zt","Lt","Dt","it","at","C","st","lt","Nt","LocaleContext","createContext","LocaleProvider","locale","messages","children","value","useMemo","createTranslator","jsx","fallbackTranslator","getFallbackTranslator","useTranslator","ctx","useContext","useLocale","ThemeContext","ThemeProvider","theme","useResolvedTheme","OriginalSizeIcon","className","getImageToolbarGroups","ZoomOut","ZoomIn","Scan","RotateCcw","RotateCw","RefreshCw","getPdfToolbarGroups","getEpubToolbarGroups","List","_a","ChevronLeft","ChevronRight","Minimize2","Maximize2","getMobiToolbarGroups","getZipToolbarGroups","stats","formatFileSize","getTextToolbarGroups","groups","WrapText","Code","Eye","getMarkdownToolbarGroups","defaultValue","url","init","RequestContext","RequestProvider","requestInit","requestHandler","shouldFetchAsBlob","createFetcher","useFetcher","useResolvedUrl","file","fetcher","needBlob","resolved","setResolved","useState","createdRef","useRef","useEffect","cancelled","fetchAsBlobUrl","blobUrl","err","ImageRenderer","lazy","index$h","PdfRenderer","index$g","DocxRenderer","index$f","XlsxRenderer","index$e","PptxRenderer","index$d","MsgRenderer","index$c","EpubRenderer","index$b","MobiRenderer","index$a","VideoRenderer","index$9","AudioRenderer","index$8","MarkdownRenderer","index$7","JsonRenderer","index$6","CsvRenderer","index$5","XmlRenderer","index$4","SubtitleRenderer","index$3","ZipRenderer","index$2","TextRenderer","index$1","FontRenderer","index","UnsupportedRenderer","fileName","fileType","onDownload","jsxs","FileQuestion","Download","RendererLoading","MAX_ZIP_NESTING_DEPTH","FilePreviewContent","props","FilePreviewContentInner","files","currentIndex","onNavigate","customRenderers","mode","onClose","zipNestingDepth","userMessages","headless","onCustomEvent","_requestInit","_requestHandler","_shouldFetchAsBlob","systemDark","setSystemDark","mql","handler","resolvedTheme","zoom","setZoom","rotation","setRotation","currentPage","setCurrentPage","setTotalPages","contentNaturalWidth","setContentNaturalWidth","contentNaturalHeight","setContentNaturalHeight","imageResetKey","setImageResetKey","contentRef","rootRef","epubRef","epubCurrent","setEpubCurrent","epubTotal","setEpubTotal","epubFullWidth","setEpubFullWidth","mobiRef","mobiCurrent","setMobiCurrent","mobiTotal","setMobiTotal","mobiFullWidth","setMobiFullWidth","zipStats","setZipStats","textWordWrap","setTextWordWrap","textHtmlPreview","setTextHtmlPreview","markdownViewMode","setMarkdownViewMode","navVisible","setNavVisible","navHideTimerRef","NAV_HIDE_DELAY","resetNavTimer","useCallback","handleMouseMove","normalizedFiles","normalizeFiles","currentFile","resolvedUrl","customRenderer","renderer","getFileType","emitCustom","name","payload","customCtx","containerWidth","containerHeight","scaleX","scaleY","newZoom","handleKeyDown","el","handleZoomIn","prev","handleZoomOut","handleRotate","handleRotateLeft","handleFitToWidth","handleOriginalSize","handleZoomChange","handleReset","handleDownload","downloadFileWithFetcher","handleEpubChapterChange","current","total","handleMobiChapterChange","handleZipStatsChange","showCloseButton","toolGroups","ext","_b","actionGroups","renderToolbarItems","dividerClass","group","gi","arr","React","item","ii","ToolbarButton","motion","Suspense","Fragment","icon","label","onClick","disabled","FilePreviewModal","isOpen","originalOverflow","originalPaddingRight","scrollbarWidth","modalContent","AnimatePresence","createPortal","FilePreviewEmbed","width","height","style","configurePdfjs","options","configurePdfWorker","pdfjsLib","VERSION","packageJson","resetKey","fileSize","onZoomChange","onNaturalWidthChange","onNaturalHeightChange","loaded","setLoaded","error","setError","position","setPosition","isDragging","setIsDragging","dragStart","setDragStart","internalZoom","setInternalZoom","naturalSize","setNaturalSize","imgRef","containerRef","handleLoad","img","clampPosition","pos","currentZoom","container","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleError","handleDoubleClick","handleWheelNative","rect","mouseX","mouseY","delta","scale","handleMouseDown","handleMouseUp","onPageChange","onTotalPagesChange","onPageWidthChange","numPages","setNumPages","isLoading","setIsLoading","pdfDocRef","pageStatesRef","observerRef","renderPage","pageNumber","state","page","viewport","canvas","renderTask","baseViewport","clearPageCanvas","initPagePlaceholders","wrapper","pageDiv","loadPdf","loadingTask","handleScroll","scrollTop","scrollCenter","currentVisiblePage","minDistance","containerRect","pageCenter","distance","entries","entry","timer","PAGE_HEIGHT","PAGE_PADDING_Y","PAGE_PADDING_X","PAGE_CONTENT_HEIGHT","PAGE_GAP","contentStyle","html","setHtml","loading","setLoading","pages","setPages","measureRef","response","arrayBuffer","result","mammoth","paginate","currentPageUsed","child","blocks","pageHtml","spreadsheetRef","sheetDataRef","resizeObserverRef","resizeTimeoutRef","lastDimensionsRef","calculateDimensions","rawWidth","rawHeight","mountSpreadsheet","isMobile","Spreadsheet","isInitialRender","updateDimensions","newDimensions","lastDimensions","widthDiff","heightDiff","isMounted","loadExcel","workbook","ExcelJS","sheetData","convertWorkbookToSpreadsheetData","errorMsg","FileSpreadsheet","tiled","slideCount","setSlideCount","previewerRef","arrayBufferRef","parentWidth","reinitializePreviewer","currentDimensions","previewer","timeoutId","loadPptx","hiddenContainer","tempPreviewer","count","Presentation","formatRecipients","recipients","type","email","formatDate","dateStr","date","decodeHtmlBody","fields","emptyBodyText","formatMessageClass","messageClass","labelStyle","rowStyle","iconWrapStyle","iconStyle","valueStyle","setFields","fileData","MsgReader","toStr","ccStr","bccStr","senderName","senderEmail","sender","sentDate","receivedDate","createdDate","lastModified","subject","attachments","bodyHtml","messageId","fieldsAny","importance","importanceLabel","sensitivity","sensitivityLabel","User","Users","Calendar","Clock","Tag","Mail","Paperclip","size","sizeStr","Hash","styleEl","A4_WIDTH","forwardRef","onChapterChange","onFullWidthChange","ref","viewerRef","bookRef","renditionRef","onChapterChangeRef","onFullWidthChangeRef","totalLocationsRef","lastCfiRef","isFullWidthRef","isFullWidth","setIsFullWidth","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","tocRef","handlePrev","handleNext","scrollContainerRef","scrollRafRef","onScrollRef","_e","mgr","reattachScrollListener","tryAttach","toggleFullWidth","newVal","viewer","rendition","toggleToc","handleTocClick","href","useImperativeHandle","loadTimer","load","bookInput","book","ePub","loc","cur","_c","nav","location","spineHref","matches","collect","items","base","_d","onResize","isActive","renderTocItems","depth","active","READER_CSS","hostRef","viewRef","reportProgress","view","host","detail","sections","idx","frac","tocItem","res","blob","_f","getVideoType","videoRef","playerRef","videoElement","videoType","player","videojs","videoEl","useAudioPlayer","audioRef","isPlaying","setIsPlaying","currentTime","setCurrentTime","duration","setDuration","volume","setVolumeState","isMuted","setIsMuted","isLoop","setIsLoop","audio","onTimeUpdate","onDurationChange","onCanPlay","onWaiting","onPlaying","onPlay","onPause","onEnded","onError","togglePlay","seek","time","skip","seconds","setVolume","vol","clamped","toggleMute","toggleLoop","next","formatTime","minutes","MarqueeText","text","innerRef","overflow","setOverflow","scrollDist","setScrollDist","check","inner","cw","tw","observer","gap","totalScroll","dur","Tonearm","showVolume","setShowVolume","volumeRef","volumeTimerRef","progress","handleClickOutside","handleVolumeEnter","handleVolumeLeave","VolumeIcon","VolumeX","Volume1","Volume2","Repeat","SkipBack","Pause","Play","SkipForward","useShikiHighlight","code","lang","codeToHtml","out","useCopy","copied","setCopied","handleCopy","textarea","InlineCopyButton","Check","Copy","FloatingCopyButton","ShikiCodeBlock","viewMode","content","setContent","sourceHtml","fetchTextUtf8","ReactMarkdown","remarkGfm","remarkMath","rehypeRaw","rehypeKatex","node","inline","match","codeString","src","alt","checked","DARK_COLORS","LIGHT_COLORS","JsonNode","keyName","defaultExpanded","colors","expanded","setExpanded","indent","toggle","renderPrimitive","isArray","openBracket","closeBracket","ChevronDown","pickColors","data","setData","loadCsv","parsed","parseCsv","guessCsvDelimiter","convertCsvToSpreadsheetData","prettyPrintXml","xml","doc","serialized","indentXml","PADDING","reg","formatted","pad","line","padded","highlighted","raw","FORMAT_BY_EXT","getFormat","setText","parseSubtitle","isLyric","meta","dotHover","cue","formatSubtitleTime","word","wi","ResizableSplit","left","right","initialLeftWidth","minLeftWidth","maxLeftWidth","minRightWidth","storageKey","desktopMedia","leftWidth","setLeftWidth","saved","dragging","setDragging","isDesktop","setIsDesktop","mq","handleMove","cap","effectiveMax","newW","handleUp","prevCursor","prevSelect","handleDividerDown","LazyFilePreviewContent","FilePreviewContent$1","resolveIcon","FileImage","FileText","FileCode","FileIcon","TreeItem","selectedPath","onToggle","onSelect","onHover","onLeave","isSelected","handleEnter","FolderOpen","Folder","Icon","nestingDepth","onStatsChange","zip","setZip","tree","setTree","selected","setSelected","previewLoading","setPreviewLoading","previewError","setPreviewError","hoverTip","setHoverTip","onStatsChangeRef","buf","loadZip","listZipEntries","root","buildZipTree","totalStats","dirs","walk","handleToggle","path","handleHover","handleLeave","handleSelect","mime","inferMimeType","readZipEntryBlob","leftPane","rightPane","wordWrap","htmlPreview","language","getLanguageFromFileName","DEFAULT_SAMPLES","SIZES","font","setFont","metadata","setMetadata","customText","setCustomText","renderMode","setRenderMode","fontFaceRef","mounted","faceBuffer","fontData","parse","names","_g","detectFormat","face","faceErr","displayText","FontPreviewLine","fontSize","wrapperRef","canvasRef","drawCanvas","dpr","lineHeight","fillColor","wrapLine","ch","wrappedLines","seg"],"mappings":"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"}
|