@eternalheart/vue-file-preview 1.3.11 → 1.3.13
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 +27 -0
- package/README.zh-CN.md +27 -0
- package/lib/FilePreviewContent.vue.d.ts.map +1 -1
- package/lib/chunks/{index-DLPnWmJm.mjs → index-B2lqsdp7.mjs} +2 -2
- package/lib/chunks/{index-DLPnWmJm.mjs.map → index-B2lqsdp7.mjs.map} +1 -1
- package/lib/chunks/{index-hRgOoqVw.mjs → index-BHi1WRQZ.mjs} +2 -2
- package/lib/chunks/{index-hRgOoqVw.mjs.map → index-BHi1WRQZ.mjs.map} +1 -1
- package/lib/chunks/{index-BHPmd4HF.mjs → index-BTW1xwB9.mjs} +2 -2
- package/lib/chunks/{index-BHPmd4HF.mjs.map → index-BTW1xwB9.mjs.map} +1 -1
- package/lib/chunks/{index-C0vSFXmh.mjs → index-BvegaxQF.mjs} +2 -2
- package/lib/chunks/{index-C0vSFXmh.mjs.map → index-BvegaxQF.mjs.map} +1 -1
- package/lib/chunks/{index-C65zV1vs.mjs → index-CYt6tpQC.mjs} +2 -2
- package/lib/chunks/{index-C65zV1vs.mjs.map → index-CYt6tpQC.mjs.map} +1 -1
- package/lib/chunks/{index-t1Plo3ud.mjs → index-Cjnw238n.mjs} +2 -2
- package/lib/chunks/{index-t1Plo3ud.mjs.map → index-Cjnw238n.mjs.map} +1 -1
- package/lib/chunks/{index-BT-U9HYI.mjs → index-Ctd0JQ6K.mjs} +2 -2
- package/lib/chunks/{index-BT-U9HYI.mjs.map → index-Ctd0JQ6K.mjs.map} +1 -1
- package/lib/chunks/index-CyrFxdIJ.mjs +318 -0
- package/lib/chunks/index-CyrFxdIJ.mjs.map +1 -0
- package/lib/chunks/{index-Cu1up6RM.mjs → index-DBw8tvyb.mjs} +2 -2
- package/lib/chunks/{index-Cu1up6RM.mjs.map → index-DBw8tvyb.mjs.map} +1 -1
- package/lib/chunks/{index-BKu5DkdG.mjs → index-DEoR7aDN.mjs} +2 -2
- package/lib/chunks/{index-BKu5DkdG.mjs.map → index-DEoR7aDN.mjs.map} +1 -1
- package/lib/chunks/{index-CMgtGmRN.mjs → index-DIe0vHlt.mjs} +9 -9
- package/lib/chunks/{index-CMgtGmRN.mjs.map → index-DIe0vHlt.mjs.map} +1 -1
- package/lib/chunks/index-DT9dPz8I.mjs +279 -0
- package/lib/chunks/index-DT9dPz8I.mjs.map +1 -0
- package/lib/chunks/{index-B9RAbllH.mjs → index-DTtHrdBl.mjs} +6 -6
- package/lib/chunks/{index-B9RAbllH.mjs.map → index-DTtHrdBl.mjs.map} +1 -1
- package/lib/chunks/{index-Dln8hyPZ.mjs → index-DX_NBPzS.mjs} +2 -2
- package/lib/chunks/{index-Dln8hyPZ.mjs.map → index-DX_NBPzS.mjs.map} +1 -1
- package/lib/chunks/{index-BA-SUKkf.mjs → index-Dw1U4YqT.mjs} +2 -2
- package/lib/chunks/{index-BA-SUKkf.mjs.map → index-Dw1U4YqT.mjs.map} +1 -1
- package/lib/chunks/{index-DNFQFaF3.mjs → index-DyipSoKh.mjs} +2 -2
- package/lib/chunks/{index-DNFQFaF3.mjs.map → index-DyipSoKh.mjs.map} +1 -1
- package/lib/chunks/{index-B3-ezDVJ.mjs → index-GGGDPwxX.mjs} +2 -2
- package/lib/chunks/{index-B3-ezDVJ.mjs.map → index-GGGDPwxX.mjs.map} +1 -1
- package/lib/chunks/{index-CQFN4h-t.mjs → index-Oxwizt6-.mjs} +609 -581
- package/lib/chunks/index-Oxwizt6-.mjs.map +1 -0
- package/lib/chunks/{index-CY2vJrBJ.mjs → index-Zwl5J-Uw.mjs} +2 -2
- package/lib/chunks/{index-CY2vJrBJ.mjs.map → index-Zwl5J-Uw.mjs.map} +1 -1
- package/lib/components/NavArrows.vue.d.ts +17 -0
- package/lib/components/NavArrows.vue.d.ts.map +1 -0
- package/lib/components/ResizableSplit.vue.d.ts +17 -2
- package/lib/components/ResizableSplit.vue.d.ts.map +1 -1
- package/lib/index.cjs +32 -32
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.mjs +1 -1
- package/lib/renderers/Image/index.vue.d.ts.map +1 -1
- package/lib/renderers/Text/index.vue.d.ts.map +1 -1
- package/lib/renderers/Xml/index.vue.d.ts.map +1 -1
- package/lib/renderers/Zip/index.vue.d.ts.map +1 -1
- package/package.json +1 -1
- package/lib/chunks/index-CQFN4h-t.mjs.map +0 -1
- package/lib/chunks/index-ijv9F2cZ.mjs +0 -280
- package/lib/chunks/index-ijv9F2cZ.mjs.map +0 -1
- package/lib/chunks/index-y7gaKu36.mjs +0 -234
- package/lib/chunks/index-y7gaKu36.mjs.map +0 -1
- package/lib/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/78-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/78-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/lib/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/lib/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/CNS2-V.bcmap +0 -3
- package/lib/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/ETenms-B5-H.bcmap +0 -3
- package/lib/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GB-H.bcmap +0 -4
- package/lib/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/lib/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/lib/pdfjs/cmaps/LICENSE +0 -36
- package/lib/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/Roman.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/lib/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/lib/pdfjs/cmaps/V.bcmap +0 -0
- package/lib/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/lib/pdfjs/pdf.worker.min.mjs +0 -21
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { defineComponent as U, ref as u, computed as S, onMounted as Y, onBeforeUnmount as _, watch as F, openBlock as s, createElementBlock as c, createElementVNode as p, normalizeStyle as E, renderSlot as B, normalizeClass as T, resolveComponent as ee, createVNode as W, unref as C, createBlock as R, resolveDynamicComponent as K, toDisplayString as D, Fragment as I, renderList as O, createCommentVNode as P, defineAsyncComponent as te, withCtx as N, Teleport as ne } from "vue";
|
|
2
|
-
import { _ as A, F as le, C as oe, u as se, a as ae, d as H, j as ie, D as re, A as fe, R as ve } from "./index-CQFN4h-t.mjs";
|
|
3
|
-
import { FileImage as de, FileText as ue, FileCode as pe, File as ce, ChevronRight as me, FolderOpen as he, Folder as we } from "lucide-vue-next";
|
|
4
|
-
import { _ as ye } from "./RendererError.vue_vue_type_script_setup_true_lang-CbgZBSDr.mjs";
|
|
5
|
-
const xe = { class: "vfp-flex-1 vfp-min-w-0 vfp-min-h-0 vfp-overflow-hidden" }, ge = /* @__PURE__ */ U({
|
|
6
|
-
name: "ResizableSplit",
|
|
7
|
-
__name: "ResizableSplit",
|
|
8
|
-
props: {
|
|
9
|
-
initialLeftWidth: { default: 280 },
|
|
10
|
-
minLeftWidth: { default: 160 },
|
|
11
|
-
maxLeftWidth: { default: 640 },
|
|
12
|
-
minRightWidth: { default: 200 },
|
|
13
|
-
storageKey: {},
|
|
14
|
-
desktopMedia: { default: "(min-width: 768px)" }
|
|
15
|
-
},
|
|
16
|
-
setup(a) {
|
|
17
|
-
const r = a, f = u(null), i = u(
|
|
18
|
-
(() => {
|
|
19
|
-
if (r.storageKey && typeof window < "u") {
|
|
20
|
-
const t = Number(window.localStorage.getItem(r.storageKey));
|
|
21
|
-
if (!isNaN(t) && t > 0) return t;
|
|
22
|
-
}
|
|
23
|
-
return r.initialLeftWidth;
|
|
24
|
-
})()
|
|
25
|
-
), m = u(!1), b = u(!1);
|
|
26
|
-
let h = null;
|
|
27
|
-
const k = () => {
|
|
28
|
-
h && (b.value = h.matches);
|
|
29
|
-
}, w = S(
|
|
30
|
-
() => b.value ? { width: `${i.value}px` } : void 0
|
|
31
|
-
), y = (t) => {
|
|
32
|
-
if (!f.value) return;
|
|
33
|
-
const v = f.value.getBoundingClientRect(), d = t.clientX - v.left, x = v.width - r.minRightWidth - 6, M = Math.min(r.maxLeftWidth, x);
|
|
34
|
-
i.value = Math.max(
|
|
35
|
-
r.minLeftWidth,
|
|
36
|
-
Math.min(M, d)
|
|
37
|
-
);
|
|
38
|
-
}, o = () => {
|
|
39
|
-
if (m.value && (m.value = !1, window.removeEventListener("mousemove", y), window.removeEventListener("mouseup", o), document.body.style.cursor = "", document.body.style.userSelect = "", r.storageKey))
|
|
40
|
-
try {
|
|
41
|
-
window.localStorage.setItem(r.storageKey, String(i.value));
|
|
42
|
-
} catch {
|
|
43
|
-
}
|
|
44
|
-
}, n = (t) => {
|
|
45
|
-
t.preventDefault(), m.value = !0, window.addEventListener("mousemove", y), window.addEventListener("mouseup", o), document.body.style.cursor = "col-resize", document.body.style.userSelect = "none";
|
|
46
|
-
};
|
|
47
|
-
return Y(() => {
|
|
48
|
-
typeof window < "u" && (h = window.matchMedia(r.desktopMedia), k(), h.addEventListener("change", k));
|
|
49
|
-
}), _(() => {
|
|
50
|
-
h && h.removeEventListener("change", k), window.removeEventListener("mousemove", y), window.removeEventListener("mouseup", o), m.value && (document.body.style.cursor = "", document.body.style.userSelect = "");
|
|
51
|
-
}), F(
|
|
52
|
-
() => r.initialLeftWidth,
|
|
53
|
-
(t) => {
|
|
54
|
-
r.storageKey || (i.value = t);
|
|
55
|
-
}
|
|
56
|
-
), (t, v) => (s(), c("div", {
|
|
57
|
-
ref_key: "containerRef",
|
|
58
|
-
ref: f,
|
|
59
|
-
class: "vfp-w-full vfp-h-full vfp-flex vfp-flex-col md:vfp-flex-row vfp-min-h-0 vfp-min-w-0"
|
|
60
|
-
}, [
|
|
61
|
-
p("div", {
|
|
62
|
-
class: "vfp-min-h-0 vfp-min-w-0 vfp-flex-shrink-0 vfp-w-full vfp-max-h-60 md:vfp-h-full md:vfp-max-h-none",
|
|
63
|
-
style: E(w.value)
|
|
64
|
-
}, [
|
|
65
|
-
B(t.$slots, "left", {}, void 0, !0)
|
|
66
|
-
], 4),
|
|
67
|
-
p("div", {
|
|
68
|
-
role: "separator",
|
|
69
|
-
"aria-orientation": "vertical",
|
|
70
|
-
class: T(["split-divider vfp-hidden md:vfp-block vfp-relative vfp-w-1.5 vfp-flex-shrink-0 vfp-cursor-col-resize vfp-transition-colors", m.value ? "dragging" : ""]),
|
|
71
|
-
onMousedown: n
|
|
72
|
-
}, [...v[0] || (v[0] = [
|
|
73
|
-
p("span", { class: "vfp-absolute vfp-inset-y-0 hit-area" }, null, -1)
|
|
74
|
-
])], 34),
|
|
75
|
-
p("div", xe, [
|
|
76
|
-
B(t.$slots, "right", {}, void 0, !0)
|
|
77
|
-
])
|
|
78
|
-
], 512));
|
|
79
|
-
}
|
|
80
|
-
}), be = /* @__PURE__ */ A(ge, [["__scopeId", "data-v-790c366f"]]), ke = { key: 0 }, Le = { class: "vfp-truncate vfp-flex-1 vfp-min-w-0" }, ze = { class: "vfp-flex-1 vfp-truncate vfp-min-w-0" }, Se = { class: "vfp-text-xs vfp-text-fg-disabled vfp-flex-shrink-0 vfp-ml-2" }, Ce = { name: "ZipTreeItem" }, Re = /* @__PURE__ */ U({
|
|
81
|
-
...Ce,
|
|
82
|
-
props: {
|
|
83
|
-
node: {},
|
|
84
|
-
depth: {},
|
|
85
|
-
selectedPath: {},
|
|
86
|
-
expanded: {}
|
|
87
|
-
},
|
|
88
|
-
emits: ["toggle", "select", "hover", "leave"],
|
|
89
|
-
setup(a, { emit: r }) {
|
|
90
|
-
const f = a, i = r, m = S(() => ({ paddingLeft: `${f.depth * 14 + 10}px` })), b = S(() => f.expanded.has(f.node.path)), h = S(() => f.selectedPath === f.node.path), k = S(() => {
|
|
91
|
-
const o = le({ name: f.node.name, type: "" });
|
|
92
|
-
return o === "image" ? de : o === "text" || o === "markdown" || o === "json" || o === "csv" || o === "xml" || o === "subtitle" ? f.node.name.endsWith(".md") || f.node.name.endsWith(".markdown") ? ue : pe : ce;
|
|
93
|
-
}), w = (o) => {
|
|
94
|
-
const n = o.currentTarget.getBoundingClientRect();
|
|
95
|
-
i("hover", f.node.name || "/", n);
|
|
96
|
-
}, y = () => i("leave");
|
|
97
|
-
return (o, n) => {
|
|
98
|
-
const t = ee("ZipTreeItem");
|
|
99
|
-
return a.node.isDir ? (s(), c("div", ke, [
|
|
100
|
-
p("button", {
|
|
101
|
-
type: "button",
|
|
102
|
-
class: "tree-row dir-row",
|
|
103
|
-
style: E(m.value),
|
|
104
|
-
onClick: n[0] || (n[0] = (v) => i("toggle", a.node.path)),
|
|
105
|
-
onMouseenter: w,
|
|
106
|
-
onMouseleave: y
|
|
107
|
-
}, [
|
|
108
|
-
W(C(me), {
|
|
109
|
-
class: T(["vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0 vfp-transition-transform", { "vfp-rotate-90": b.value }])
|
|
110
|
-
}, null, 8, ["class"]),
|
|
111
|
-
(s(), R(K(b.value ? C(he) : C(we)), { class: "vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-amber-300/80" })),
|
|
112
|
-
p("span", Le, D(a.node.name || "/"), 1)
|
|
113
|
-
], 36),
|
|
114
|
-
b.value && a.node.children ? (s(!0), c(I, { key: 0 }, O(a.node.children, (v) => (s(), R(t, {
|
|
115
|
-
key: v.path,
|
|
116
|
-
node: v,
|
|
117
|
-
depth: a.depth + 1,
|
|
118
|
-
"selected-path": a.selectedPath,
|
|
119
|
-
expanded: a.expanded,
|
|
120
|
-
onToggle: n[1] || (n[1] = (d) => i("toggle", d)),
|
|
121
|
-
onSelect: n[2] || (n[2] = (d) => i("select", d)),
|
|
122
|
-
onHover: n[3] || (n[3] = (d, x) => i("hover", d, x)),
|
|
123
|
-
onLeave: n[4] || (n[4] = (d) => i("leave"))
|
|
124
|
-
}, null, 8, ["node", "depth", "selected-path", "expanded"]))), 128)) : P("", !0)
|
|
125
|
-
])) : (s(), c("button", {
|
|
126
|
-
key: 1,
|
|
127
|
-
type: "button",
|
|
128
|
-
class: T(["tree-row file-row", { selected: h.value }]),
|
|
129
|
-
style: E(m.value),
|
|
130
|
-
onClick: n[5] || (n[5] = (v) => i("select", a.node)),
|
|
131
|
-
onMouseenter: w,
|
|
132
|
-
onMouseleave: y
|
|
133
|
-
}, [
|
|
134
|
-
n[6] || (n[6] = p("span", { class: "vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0" }, null, -1)),
|
|
135
|
-
(s(), R(K(k.value), { class: "vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-fg-tertiary" })),
|
|
136
|
-
p("span", ze, D(a.node.name), 1),
|
|
137
|
-
p("span", Se, D(C(oe)(a.node.size)), 1)
|
|
138
|
-
], 38));
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
}), Me = /* @__PURE__ */ A(Re, [["__scopeId", "data-v-c8c0f0ee"]]), $e = {
|
|
142
|
-
key: 0,
|
|
143
|
-
class: "vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full"
|
|
144
|
-
}, De = { class: "vfp-w-full vfp-h-full vfp-overflow-auto" }, Ee = { class: "vfp-w-full vfp-h-full vfp-flex vfp-flex-col" }, _e = {
|
|
145
|
-
key: 0,
|
|
146
|
-
class: "vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-muted vfp-text-sm vfp-p-6"
|
|
147
|
-
}, Fe = {
|
|
148
|
-
key: 1,
|
|
149
|
-
class: "vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center"
|
|
150
|
-
}, Te = {
|
|
151
|
-
key: 2,
|
|
152
|
-
class: "vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-secondary"
|
|
153
|
-
}, We = {
|
|
154
|
-
key: 3,
|
|
155
|
-
class: "vfp-flex-1 vfp-min-h-0 vfp-overflow-hidden vfp-flex vfp-relative vfp-z-0"
|
|
156
|
-
}, Ke = /* @__PURE__ */ U({
|
|
157
|
-
__name: "index",
|
|
158
|
-
props: {
|
|
159
|
-
url: {},
|
|
160
|
-
nestingDepth: { default: 0 }
|
|
161
|
-
},
|
|
162
|
-
emits: ["statsChange"],
|
|
163
|
-
setup(a, { emit: r }) {
|
|
164
|
-
const f = te(
|
|
165
|
-
() => import("./index-CQFN4h-t.mjs").then((e) => e.i)
|
|
166
|
-
), i = a, m = r, { t: b } = se(), h = ae(), k = u(null), w = u(null), y = u(!0), o = u(null), n = u(/* @__PURE__ */ new Set([""])), t = u(null), v = u(!1), d = u(null), x = u(null), M = () => {
|
|
167
|
-
var e;
|
|
168
|
-
(e = t.value) != null && e.blobUrl && URL.revokeObjectURL(t.value.blobUrl);
|
|
169
|
-
}, V = async () => {
|
|
170
|
-
M(), t.value = null, y.value = !0, o.value = null;
|
|
171
|
-
try {
|
|
172
|
-
const e = await h.value(i.url);
|
|
173
|
-
if (!e.ok) throw new Error("加载失败");
|
|
174
|
-
const l = await e.arrayBuffer(), g = await ie(l), L = re(g), z = fe(L);
|
|
175
|
-
k.value = g, w.value = z;
|
|
176
|
-
const $ = /* @__PURE__ */ new Set([""]);
|
|
177
|
-
if (z.children)
|
|
178
|
-
for (const j of z.children) j.isDir && $.add(j.path);
|
|
179
|
-
n.value = $;
|
|
180
|
-
} catch (e) {
|
|
181
|
-
console.error(e), o.value = b.value("zip.load_failed");
|
|
182
|
-
} finally {
|
|
183
|
-
y.value = !1;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
F(() => i.url, (e) => {
|
|
187
|
-
e && V();
|
|
188
|
-
}, { immediate: !0 }), _(() => {
|
|
189
|
-
M();
|
|
190
|
-
});
|
|
191
|
-
const Z = S(() => {
|
|
192
|
-
if (!w.value) return null;
|
|
193
|
-
let e = 0, l = 0, g = 0;
|
|
194
|
-
const L = (z) => {
|
|
195
|
-
var $;
|
|
196
|
-
z.isDir ? (z.path && l++, ($ = z.children) == null || $.forEach(L)) : (e++, g += z.size);
|
|
197
|
-
};
|
|
198
|
-
return L(w.value), { files: e, dirs: l, size: g };
|
|
199
|
-
});
|
|
200
|
-
F(Z, (e) => m("statsChange", e), { immediate: !0 }), _(() => m("statsChange", null));
|
|
201
|
-
const q = (e) => {
|
|
202
|
-
const l = new Set(n.value);
|
|
203
|
-
l.has(e) ? l.delete(e) : l.add(e), n.value = l;
|
|
204
|
-
}, X = (e, l) => {
|
|
205
|
-
x.value = { text: e, x: l.right + 8, y: l.top + l.height / 2 };
|
|
206
|
-
}, G = () => {
|
|
207
|
-
x.value = null;
|
|
208
|
-
}, J = async (e) => {
|
|
209
|
-
if (!(!k.value || e.isDir)) {
|
|
210
|
-
M(), v.value = !0, d.value = null;
|
|
211
|
-
try {
|
|
212
|
-
const l = H(e.name), g = await ve(k.value, e.path, l !== "application/octet-stream" ? l : void 0), L = URL.createObjectURL(g);
|
|
213
|
-
t.value = { path: e.path, name: e.name, size: e.size, blobUrl: L };
|
|
214
|
-
} catch (l) {
|
|
215
|
-
console.error(l), d.value = "条目读取失败";
|
|
216
|
-
} finally {
|
|
217
|
-
v.value = !1;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}, Q = S(() => t.value ? [{ name: t.value.name, url: t.value.blobUrl, type: H(t.value.name) }] : []);
|
|
221
|
-
return (e, l) => y.value ? (s(), c("div", $e, [...l[0] || (l[0] = [
|
|
222
|
-
p("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
|
|
223
|
-
])])) : o.value || !w.value ? (s(), R(ye, {
|
|
224
|
-
key: 1,
|
|
225
|
-
message: o.value || C(b)("zip.parse_failed")
|
|
226
|
-
}, null, 8, ["message"])) : (s(), c(I, { key: 2 }, [
|
|
227
|
-
W(be, {
|
|
228
|
-
"initial-left-width": 280,
|
|
229
|
-
"min-left-width": 180,
|
|
230
|
-
"max-left-width": 560,
|
|
231
|
-
"storage-key": "vfp-zip-split-left"
|
|
232
|
-
}, {
|
|
233
|
-
left: N(() => [
|
|
234
|
-
p("div", De, [
|
|
235
|
-
(s(!0), c(I, null, O(w.value.children || [], (g) => {
|
|
236
|
-
var L;
|
|
237
|
-
return s(), R(Me, {
|
|
238
|
-
key: g.path,
|
|
239
|
-
node: g,
|
|
240
|
-
depth: 0,
|
|
241
|
-
"selected-path": ((L = t.value) == null ? void 0 : L.path) ?? null,
|
|
242
|
-
expanded: n.value,
|
|
243
|
-
onToggle: q,
|
|
244
|
-
onSelect: J,
|
|
245
|
-
onHover: X,
|
|
246
|
-
onLeave: G
|
|
247
|
-
}, null, 8, ["node", "selected-path", "expanded"]);
|
|
248
|
-
}), 128))
|
|
249
|
-
])
|
|
250
|
-
]),
|
|
251
|
-
right: N(() => [
|
|
252
|
-
p("div", Ee, [
|
|
253
|
-
t.value ? v.value ? (s(), c("div", Fe, [...l[1] || (l[1] = [
|
|
254
|
-
p("div", { class: "vfp-w-8 vfp-h-8 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
|
|
255
|
-
])])) : d.value ? (s(), c("div", Te, D(d.value), 1)) : (s(), c("div", We, [
|
|
256
|
-
W(C(f), {
|
|
257
|
-
mode: "embed",
|
|
258
|
-
files: Q.value,
|
|
259
|
-
"current-index": 0,
|
|
260
|
-
"zip-nesting-depth": a.nestingDepth + 1
|
|
261
|
-
}, null, 8, ["files", "zip-nesting-depth"])
|
|
262
|
-
])) : (s(), c("div", _e, " 从左侧选择一个文件以预览 "))
|
|
263
|
-
])
|
|
264
|
-
]),
|
|
265
|
-
_: 1
|
|
266
|
-
}),
|
|
267
|
-
(s(), R(ne, { to: "body" }, [
|
|
268
|
-
x.value ? (s(), c("div", {
|
|
269
|
-
key: 0,
|
|
270
|
-
class: "vfp-zip-tip",
|
|
271
|
-
style: E({ left: x.value.x + "px", top: x.value.y + "px" })
|
|
272
|
-
}, D(x.value.text), 5)) : P("", !0)
|
|
273
|
-
]))
|
|
274
|
-
], 64));
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
export {
|
|
278
|
-
Ke as default
|
|
279
|
-
};
|
|
280
|
-
//# sourceMappingURL=index-ijv9F2cZ.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-ijv9F2cZ.mjs","sources":["../../src/components/ResizableSplit.vue","../../src/renderers/Zip/TreeItem.vue","../../src/renderers/Zip/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onBeforeUnmount, onMounted, watch } from 'vue';\n\ninterface Props {\n /** 左侧初始宽度(px);传入 storageKey 时会从 localStorage 读取 */\n initialLeftWidth?: number;\n /** 左侧最小宽度(px) */\n minLeftWidth?: number;\n /** 左侧最大宽度(px) */\n maxLeftWidth?: number;\n /** 右侧至少保留的宽度(px) */\n minRightWidth?: number;\n /** localStorage 持久化 key */\n storageKey?: string;\n /** 启用横向拖动的媒体查询 */\n desktopMedia?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n initialLeftWidth: 280,\n minLeftWidth: 160,\n maxLeftWidth: 640,\n minRightWidth: 200,\n desktopMedia: '(min-width: 768px)',\n});\n\ndefineOptions({ name: 'ResizableSplit' });\n\nconst containerRef = ref<HTMLDivElement | null>(null);\nconst leftWidth = ref<number>(\n (() => {\n if (props.storageKey && typeof window !== 'undefined') {\n const saved = Number(window.localStorage.getItem(props.storageKey));\n if (!isNaN(saved) && saved > 0) return saved;\n }\n return props.initialLeftWidth;\n })()\n);\nconst dragging = ref(false);\nconst isDesktop = ref(false);\n\nlet mq: MediaQueryList | null = null;\nconst mqHandler = () => {\n if (mq) isDesktop.value = mq.matches;\n};\n\nconst leftStyle = computed(() =>\n isDesktop.value ? { width: `${leftWidth.value}px` } : undefined\n);\n\nconst onMove = (e: MouseEvent) => {\n if (!containerRef.value) return;\n const rect = containerRef.value.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const cap = rect.width - props.minRightWidth - 6;\n const effectiveMax = Math.min(props.maxLeftWidth, cap);\n leftWidth.value = Math.max(\n props.minLeftWidth,\n Math.min(effectiveMax, x)\n );\n};\n\nconst onUp = () => {\n if (!dragging.value) return;\n dragging.value = false;\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n if (props.storageKey) {\n try {\n window.localStorage.setItem(props.storageKey, String(leftWidth.value));\n } catch {\n // ignore\n }\n }\n};\n\nconst onDividerDown = (e: MouseEvent) => {\n e.preventDefault();\n dragging.value = true;\n window.addEventListener('mousemove', onMove);\n window.addEventListener('mouseup', onUp);\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n};\n\nonMounted(() => {\n if (typeof window !== 'undefined') {\n mq = window.matchMedia(props.desktopMedia);\n mqHandler();\n mq.addEventListener('change', mqHandler);\n }\n});\n\nonBeforeUnmount(() => {\n if (mq) mq.removeEventListener('change', mqHandler);\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n if (dragging.value) {\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n});\n\nwatch(\n () => props.initialLeftWidth,\n (w) => {\n if (!props.storageKey) leftWidth.value = w;\n }\n);\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-w-full vfp-h-full vfp-flex vfp-flex-col md:vfp-flex-row vfp-min-h-0 vfp-min-w-0\"\n >\n <div\n class=\"vfp-min-h-0 vfp-min-w-0 vfp-flex-shrink-0 vfp-w-full vfp-max-h-60 md:vfp-h-full md:vfp-max-h-none\"\n :style=\"leftStyle\"\n >\n <slot name=\"left\" />\n </div>\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n class=\"split-divider vfp-hidden md:vfp-block vfp-relative vfp-w-1.5 vfp-flex-shrink-0 vfp-cursor-col-resize vfp-transition-colors\"\n :class=\"dragging ? 'dragging' : ''\"\n @mousedown=\"onDividerDown\"\n >\n <span class=\"vfp-absolute vfp-inset-y-0 hit-area\" />\n </div>\n <div class=\"vfp-flex-1 vfp-min-w-0 vfp-min-h-0 vfp-overflow-hidden\">\n <slot name=\"right\" />\n </div>\n </div>\n</template>\n\n<style scoped>\n.split-divider {\n background: rgba(255, 255, 255, 0.1);\n}\n.split-divider:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n.split-divider.dragging {\n background: rgba(255, 255, 255, 0.4);\n}\n.hit-area {\n left: -4px;\n right: -4px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport {\n Folder,\n FolderOpen,\n FileText,\n FileImage,\n FileCode,\n File as FileIcon,\n ChevronRight,\n} from 'lucide-vue-next';\nimport { formatFileSize, getFileType, type ZipTreeNode } from '@eternalheart/file-preview-core';\n\nconst props = defineProps<{\n node: ZipTreeNode;\n depth: number;\n selectedPath: string | null;\n expanded: Set<string>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'toggle', path: string): void;\n (e: 'select', node: ZipTreeNode): void;\n (e: 'hover', text: string, rect: DOMRect): void;\n (e: 'leave'): void;\n}>();\n\nconst padStyle = computed(() => ({ paddingLeft: `${props.depth * 14 + 10}px` }));\nconst isOpen = computed(() => props.expanded.has(props.node.path));\nconst isSelected = computed(() => props.selectedPath === props.node.path);\n\nconst fileIcon = computed(() => {\n const ft = getFileType({ id: '', name: props.node.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 (props.node.name.endsWith('.md') || props.node.name.endsWith('.markdown')) ? FileText : FileCode;\n }\n return FileIcon;\n});\n\nconst handleEnter = (e: MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n emit('hover', props.node.name || '/', rect);\n};\n\nconst handleLeave = () => emit('leave');\n</script>\n\n<template>\n <div v-if=\"node.isDir\">\n <button\n type=\"button\"\n class=\"tree-row dir-row\"\n :style=\"padStyle\"\n @click=\"emit('toggle', node.path)\"\n @mouseenter=\"handleEnter\"\n @mouseleave=\"handleLeave\"\n >\n <ChevronRight\n class=\"vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0 vfp-transition-transform\"\n :class=\"{ 'vfp-rotate-90': isOpen }\"\n />\n <component\n :is=\"isOpen ? FolderOpen : Folder\"\n class=\"vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-amber-300/80\"\n />\n <span class=\"vfp-truncate vfp-flex-1 vfp-min-w-0\">{{ node.name || '/' }}</span>\n </button>\n <template v-if=\"isOpen && node.children\">\n <ZipTreeItem\n v-for=\"child in node.children\"\n :key=\"child.path\"\n :node=\"child\"\n :depth=\"depth + 1\"\n :selected-path=\"selectedPath\"\n :expanded=\"expanded\"\n @toggle=\"(p) => emit('toggle', p)\"\n @select=\"(n) => emit('select', n)\"\n @hover=\"(t, r) => emit('hover', t, r)\"\n @leave=\"emit('leave')\"\n />\n </template>\n </div>\n <button\n v-else\n type=\"button\"\n class=\"tree-row file-row\"\n :class=\"{ selected: isSelected }\"\n :style=\"padStyle\"\n @click=\"emit('select', node)\"\n @mouseenter=\"handleEnter\"\n @mouseleave=\"handleLeave\"\n >\n <span class=\"vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0\" />\n <component :is=\"fileIcon\" class=\"vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-fg-tertiary\" />\n <span class=\"vfp-flex-1 vfp-truncate vfp-min-w-0\">{{ node.name }}</span>\n <span class=\"vfp-text-xs vfp-text-fg-disabled vfp-flex-shrink-0 vfp-ml-2\">{{ formatFileSize(node.size) }}</span>\n </button>\n</template>\n\n<script lang=\"ts\">\nexport default { name: 'ZipTreeItem' };\n</script>\n\n<style scoped>\n.tree-row {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n padding-right: 0.5rem;\n text-align: left;\n font-size: 0.875rem;\n background: transparent;\n border: 0;\n cursor: pointer;\n}\n.dir-row {\n color: var(--fp-fg-secondary);\n}\n.file-row {\n color: var(--fp-fg-secondary);\n}\n.tree-row:hover {\n background: var(--fp-surface-1);\n}\n.file-row.selected {\n background: var(--fp-line);\n color: #fff;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onBeforeUnmount, defineAsyncComponent } from 'vue';\nimport type JSZip from 'jszip';\nimport {\n loadZip,\n listZipEntries,\n buildZipTree,\n readZipEntryBlob,\n inferMimeType,\n type ZipTreeNode,\n} from '@eternalheart/file-preview-core';\nimport ResizableSplit from '../../components/ResizableSplit.vue';\nimport TreeItem from './TreeItem.vue';\nimport type { ZipToolbarStats } from './toolbar';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\nimport RendererError from '../RendererError.vue';\n\n// 懒加载 FilePreviewContent 以打破循环依赖\nconst LazyFilePreviewContent = defineAsyncComponent(\n () => import('../../FilePreviewContent.vue')\n);\n\nconst props = withDefaults(defineProps<{\n url: string;\n /** ZIP 嵌套深度(由 FilePreviewContent 传入) */\n nestingDepth?: number;\n}>(), {\n nestingDepth: 0,\n});\n\nconst emit = defineEmits<{\n (e: 'statsChange', stats: ZipToolbarStats | null): void;\n}>();\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\n\ninterface SelectedPreview {\n path: string;\n name: string;\n size: number;\n blobUrl: string;\n}\n\ninterface HoverTipState {\n text: string;\n x: number;\n y: number;\n}\n\nconst zip = ref<JSZip | null>(null);\nconst tree = ref<ZipTreeNode | null>(null);\nconst loading = ref(true);\nconst error = ref<string | null>(null);\nconst expanded = ref<Set<string>>(new Set(['']));\nconst selected = ref<SelectedPreview | null>(null);\nconst previewLoading = ref(false);\nconst previewError = ref<string | null>(null);\nconst hoverTip = ref<HoverTipState | null>(null);\n\nconst revokeCurrent = () => {\n if (selected.value?.blobUrl) URL.revokeObjectURL(selected.value.blobUrl);\n};\n\nconst load = async () => {\n revokeCurrent();\n selected.value = null;\n loading.value = true;\n error.value = null;\n try {\n const res = await fetcher.value(props.url);\n if (!res.ok) throw new Error('加载失败');\n const buf = await res.arrayBuffer();\n const z = await loadZip(buf);\n const entries = listZipEntries(z);\n const root = buildZipTree(entries);\n zip.value = z;\n tree.value = root;\n const init = new Set<string>(['']);\n if (root.children) for (const c of root.children) if (c.isDir) init.add(c.path);\n expanded.value = init;\n } catch (err) {\n console.error(err);\n error.value = t.value('zip.load_failed');\n } finally {\n loading.value = false;\n }\n};\n\nwatch(() => props.url, (newUrl) => {\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (newUrl) load();\n}, { immediate: true });\nonBeforeUnmount(() => { revokeCurrent(); });\n\nconst totalStats = computed<ZipToolbarStats | null>(() => {\n if (!tree.value) return null;\n let files = 0, dirs = 0, size = 0;\n const walk = (n: ZipTreeNode) => {\n if (n.isDir) { if (n.path) dirs++; n.children?.forEach(walk); }\n else { files++; size += n.size; }\n };\n walk(tree.value);\n return { files, dirs, size };\n});\n\nwatch(totalStats, (s) => emit('statsChange', s), { immediate: true });\nonBeforeUnmount(() => emit('statsChange', null));\n\nconst handleToggle = (path: string) => {\n const next = new Set(expanded.value);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n expanded.value = next;\n};\n\nconst handleHover = (text: string, rect: DOMRect) => {\n hoverTip.value = { text, x: rect.right + 8, y: rect.top + rect.height / 2 };\n};\nconst handleLeave = () => { hoverTip.value = null; };\n\nconst handleSelect = async (node: ZipTreeNode) => {\n if (!zip.value || node.isDir) return;\n revokeCurrent();\n previewLoading.value = true;\n previewError.value = null;\n\n try {\n const mime = inferMimeType(node.name);\n const blob = await readZipEntryBlob(zip.value, node.path, mime !== 'application/octet-stream' ? mime : undefined);\n const blobUrl = URL.createObjectURL(blob);\n selected.value = { path: node.path, name: node.name, size: node.size, blobUrl };\n } catch (err) {\n console.error(err);\n previewError.value = '条目读取失败';\n } finally {\n previewLoading.value = false;\n }\n};\n\n/** 为嵌入的 FilePreviewContent 构建 files 数组 */\nconst previewFiles = computed(() => {\n if (!selected.value) return [];\n return [{ name: selected.value.name, url: selected.value.blobUrl, type: inferMimeType(selected.value.name) }];\n});\n</script>\n\n<template>\n <div v-if=\"loading\" class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full\">\n <div class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\" />\n </div>\n\n <RendererError v-else-if=\"error || !tree\" :message=\"error || t('zip.parse_failed')\" />\n\n <template v-else>\n <ResizableSplit\n :initial-left-width=\"280\"\n :min-left-width=\"180\"\n :max-left-width=\"560\"\n storage-key=\"vfp-zip-split-left\"\n >\n <template #left>\n <div class=\"vfp-w-full vfp-h-full vfp-overflow-auto\">\n <TreeItem\n v-for=\"child in tree.children || []\"\n :key=\"child.path\"\n :node=\"child\"\n :depth=\"0\"\n :selected-path=\"selected?.path ?? null\"\n :expanded=\"expanded\"\n @toggle=\"handleToggle\"\n @select=\"handleSelect\"\n @hover=\"handleHover\"\n @leave=\"handleLeave\"\n />\n </div>\n </template>\n\n <template #right>\n <div class=\"vfp-w-full vfp-h-full vfp-flex vfp-flex-col\">\n <div v-if=\"!selected\" class=\"vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-muted vfp-text-sm vfp-p-6\">\n 从左侧选择一个文件以预览\n </div>\n <div v-else-if=\"previewLoading\" class=\"vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center\">\n <div class=\"vfp-w-8 vfp-h-8 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\" />\n </div>\n <div v-else-if=\"previewError\" class=\"vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-secondary\">{{ previewError }}</div>\n <template v-else>\n <div class=\"vfp-flex-1 vfp-min-h-0 vfp-overflow-hidden vfp-flex vfp-relative vfp-z-0\">\n <LazyFilePreviewContent\n mode=\"embed\"\n :files=\"previewFiles\"\n :current-index=\"0\"\n :zip-nesting-depth=\"nestingDepth + 1\"\n />\n </div>\n </template>\n </div>\n </template>\n </ResizableSplit>\n\n <!-- 文件名 hover tooltip (teleport 到 body 避免被滚动区裁剪) -->\n <Teleport to=\"body\">\n <div\n v-if=\"hoverTip\"\n class=\"vfp-zip-tip\"\n :style=\"{ left: hoverTip.x + 'px', top: hoverTip.y + 'px' }\"\n >\n {{ hoverTip.text }}\n </div>\n </Teleport>\n </template>\n</template>\n\n<style>\n/* 全局 tooltip(不能 scoped,因 Teleport 到 body) */\n.vfp-zip-tip {\n position: fixed;\n z-index: 9999;\n pointer-events: none;\n transform: translateY(-50%);\n padding: 4px 8px;\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 4px;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n}\n</style>\n"],"names":["props","__props","containerRef","ref","leftWidth","saved","dragging","isDesktop","mq","mqHandler","leftStyle","computed","onMove","e","rect","x","cap","effectiveMax","onUp","onDividerDown","onMounted","onBeforeUnmount","watch","w","_createElementBlock","_createElementVNode","_renderSlot","_ctx","_normalizeClass","_hoisted_1","__default__","emit","__emit","padStyle","isOpen","isSelected","fileIcon","ft","getFileType","FileImage","FileText","FileCode","FileIcon","handleEnter","handleLeave","_cache","$event","_createVNode","_unref","ChevronRight","_createBlock","_resolveDynamicComponent","FolderOpen","Folder","_hoisted_2","_toDisplayString","_openBlock","_Fragment","_renderList","child","_component_ZipTreeItem","p","n","t","r","_hoisted_3","_hoisted_4","LazyFilePreviewContent","defineAsyncComponent","useTranslator","fetcher","useFetcher","zip","tree","loading","error","expanded","selected","previewLoading","previewError","hoverTip","revokeCurrent","_a","load","res","buf","z","loadZip","entries","listZipEntries","root","buildZipTree","init","c","err","newUrl","totalStats","files","dirs","size","walk","s","handleToggle","path","next","handleHover","text","handleSelect","node","mime","inferMimeType","blob","readZipEntryBlob","blobUrl","previewFiles","RendererError","ResizableSplit","TreeItem","_hoisted_5","_hoisted_6","_hoisted_7","_Teleport"],"mappings":"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"}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { defineComponent as oe, ref as l, watch as $, onBeforeUnmount as X, onMounted as se, computed as V, openBlock as c, createElementBlock as _, normalizeStyle as K, createVNode as re, unref as q, createElementVNode as z, createTextVNode as ue, toDisplayString as M, createCommentVNode as g, createBlock as G, normalizeClass as ie } from "vue";
|
|
2
|
-
import { Loader2 as ve } from "lucide-vue-next";
|
|
3
|
-
import { u as fe, G as ce, q as de, C as pe } from "./index-CQFN4h-t.mjs";
|
|
4
|
-
import { _ as F } from "./RendererError.vue_vue_type_script_setup_true_lang-CbgZBSDr.mjs";
|
|
5
|
-
const he = {
|
|
6
|
-
key: 0,
|
|
7
|
-
class: "vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10"
|
|
8
|
-
}, me = { class: "vfp-mt-4 vfp-text-fg-secondary" }, ge = { key: 0 }, ye = {
|
|
9
|
-
key: 2,
|
|
10
|
-
class: "vfp-flex vfp-items-center vfp-justify-center"
|
|
11
|
-
}, be = ["src"], xe = {
|
|
12
|
-
key: 5,
|
|
13
|
-
class: "vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default"
|
|
14
|
-
}, we = {
|
|
15
|
-
key: 6,
|
|
16
|
-
class: "vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md"
|
|
17
|
-
}, _e = ["disabled"], ke = { class: "vfp-text-fg-secondary vfp-tabular-nums" }, Ce = ["disabled"], ze = /* @__PURE__ */ oe({
|
|
18
|
-
__name: "index",
|
|
19
|
-
props: {
|
|
20
|
-
url: {},
|
|
21
|
-
zoom: {},
|
|
22
|
-
rotation: {},
|
|
23
|
-
resetKey: {},
|
|
24
|
-
fileSize: {},
|
|
25
|
-
file: {}
|
|
26
|
-
},
|
|
27
|
-
emits: ["zoomChange", "naturalWidthChange", "naturalHeightChange"],
|
|
28
|
-
setup(Q, { emit: Z }) {
|
|
29
|
-
const n = Q, E = Z, { t: D } = fe(), y = l(!1), d = l(null), r = l(!1), j = l(0), p = l(null), h = l(""), m = l(1), k = l(1), H = l(!1), u = l({ x: 0, y: 0 }), U = l(!1);
|
|
30
|
-
let W = { x: 0, y: 0 };
|
|
31
|
-
const b = l(1), x = l({ width: 0, height: 0 }), A = l(null), C = l(null);
|
|
32
|
-
let R = null, B = null, S = null;
|
|
33
|
-
const i = /* @__PURE__ */ new Map();
|
|
34
|
-
$(
|
|
35
|
-
() => [n.url, n.file],
|
|
36
|
-
async () => {
|
|
37
|
-
if (h.value = "", y.value = !1, d.value = null, r.value = !1, p.value = null, j.value = 0, u.value = { x: 0, y: 0 }, b.value = 1, m.value = 1, k.value = 1, H.value = !1, R && (URL.revokeObjectURL(R), R = null), i.forEach((e) => URL.revokeObjectURL(e)), i.clear(), B = null, S = null, !n.file) {
|
|
38
|
-
h.value = n.url;
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
const e = await ce(n.file), t = await de(e);
|
|
43
|
-
if (!t || !await t.needsDecode(e)) {
|
|
44
|
-
h.value = n.url;
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
r.value = !0;
|
|
48
|
-
let a;
|
|
49
|
-
if (n.file instanceof Blob)
|
|
50
|
-
a = n.file;
|
|
51
|
-
else {
|
|
52
|
-
const s = await fetch(n.url);
|
|
53
|
-
if (!s.ok) throw new Error("Failed to fetch file");
|
|
54
|
-
a = await s.blob();
|
|
55
|
-
}
|
|
56
|
-
if (B = a, S = t, e.startsWith("image/x-") && (H.value = !0), t.getMetadata)
|
|
57
|
-
try {
|
|
58
|
-
const s = await t.getMetadata(a);
|
|
59
|
-
s.pageCount && s.pageCount > 1 && (k.value = s.pageCount);
|
|
60
|
-
} catch {
|
|
61
|
-
}
|
|
62
|
-
const o = await t.decode(a, {
|
|
63
|
-
page: 1,
|
|
64
|
-
fullQuality: !1,
|
|
65
|
-
onProgress: (s) => {
|
|
66
|
-
j.value = s;
|
|
67
|
-
}
|
|
68
|
-
}), v = typeof o == "string" ? o : URL.createObjectURL(o);
|
|
69
|
-
R = v, i.set(1, v), h.value = v, r.value = !1;
|
|
70
|
-
} catch (e) {
|
|
71
|
-
p.value = (e == null ? void 0 : e.message) || "解码失败", r.value = !1;
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
{ immediate: !0 }
|
|
75
|
-
);
|
|
76
|
-
const T = async (e) => {
|
|
77
|
-
if (!B || !S || e < 1 || e > k.value) return;
|
|
78
|
-
const t = i.get(e);
|
|
79
|
-
if (t) {
|
|
80
|
-
m.value = e, h.value = t;
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
r.value = !0;
|
|
84
|
-
try {
|
|
85
|
-
const a = await S.decode(B, { page: e }), f = typeof a == "string" ? a : URL.createObjectURL(a);
|
|
86
|
-
if (i.size >= 10) {
|
|
87
|
-
const o = i.keys().next().value;
|
|
88
|
-
if (o !== void 0) {
|
|
89
|
-
const v = i.get(o);
|
|
90
|
-
v && URL.revokeObjectURL(v), i.delete(o);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
i.set(e, f), m.value = e, h.value = f, r.value = !1;
|
|
94
|
-
} catch (a) {
|
|
95
|
-
p.value = (a == null ? void 0 : a.message) || "翻页解码失败", r.value = !1;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
X(() => {
|
|
99
|
-
R && URL.revokeObjectURL(R), i.forEach((t) => URL.revokeObjectURL(t)), i.clear();
|
|
100
|
-
const e = C.value;
|
|
101
|
-
e && e.removeEventListener("wheel", O);
|
|
102
|
-
}), $(
|
|
103
|
-
() => n.zoom,
|
|
104
|
-
(e) => {
|
|
105
|
-
b.value = e;
|
|
106
|
-
}
|
|
107
|
-
), $(
|
|
108
|
-
() => n.resetKey,
|
|
109
|
-
() => {
|
|
110
|
-
u.value = { x: 0, y: 0 };
|
|
111
|
-
}
|
|
112
|
-
);
|
|
113
|
-
const Y = (e, t) => {
|
|
114
|
-
const a = C.value;
|
|
115
|
-
if (!a || x.value.width === 0) return e;
|
|
116
|
-
const f = a.clientWidth, o = a.clientHeight, v = x.value.width * t, s = x.value.height * t, w = Math.min(80, f * 0.15, o * 0.15), L = (f + v) / 2 - w, P = (o + s) / 2 - w;
|
|
117
|
-
return {
|
|
118
|
-
x: L > 0 ? Math.max(-L, Math.min(L, e.x)) : 0,
|
|
119
|
-
y: P > 0 ? Math.max(-P, Math.min(P, e.y)) : 0
|
|
120
|
-
};
|
|
121
|
-
}, I = (e) => {
|
|
122
|
-
y.value = !0;
|
|
123
|
-
const t = e.currentTarget;
|
|
124
|
-
x.value = { width: t.naturalWidth, height: t.naturalHeight }, E("naturalWidthChange", t.naturalWidth), E("naturalHeightChange", t.naturalHeight);
|
|
125
|
-
}, J = () => {
|
|
126
|
-
d.value = D.value("image.load_failed"), y.value = !0;
|
|
127
|
-
}, ee = () => {
|
|
128
|
-
u.value = { x: 0, y: 0 }, b.value = 1, E("zoomChange", 1);
|
|
129
|
-
}, O = (e) => {
|
|
130
|
-
e.preventDefault(), e.stopPropagation();
|
|
131
|
-
const t = C.value;
|
|
132
|
-
if (!t) return;
|
|
133
|
-
const a = t.getBoundingClientRect(), f = e.clientX - a.left - a.width / 2, o = e.clientY - a.top - a.height / 2, v = e.deltaY > 0 ? -0.05 : 0.05, s = b.value, w = Math.max(0.01, Math.min(10, s + v)), L = w / s;
|
|
134
|
-
u.value = Y(
|
|
135
|
-
{
|
|
136
|
-
x: f - L * (f - u.value.x),
|
|
137
|
-
y: o - L * (o - u.value.y)
|
|
138
|
-
},
|
|
139
|
-
w
|
|
140
|
-
), b.value = w, E("zoomChange", w);
|
|
141
|
-
};
|
|
142
|
-
se(() => {
|
|
143
|
-
const e = C.value;
|
|
144
|
-
e && e.addEventListener("wheel", O, { passive: !1 });
|
|
145
|
-
}), X(() => {
|
|
146
|
-
const e = C.value;
|
|
147
|
-
e && e.removeEventListener("wheel", O);
|
|
148
|
-
});
|
|
149
|
-
const te = (e) => {
|
|
150
|
-
e.button === 0 && (U.value = !0, W = {
|
|
151
|
-
x: e.clientX - u.value.x,
|
|
152
|
-
y: e.clientY - u.value.y
|
|
153
|
-
});
|
|
154
|
-
}, ae = (e) => {
|
|
155
|
-
U.value && (u.value = Y(
|
|
156
|
-
{
|
|
157
|
-
x: e.clientX - W.x,
|
|
158
|
-
y: e.clientY - W.y
|
|
159
|
-
},
|
|
160
|
-
b.value
|
|
161
|
-
));
|
|
162
|
-
}, N = () => {
|
|
163
|
-
U.value = !1;
|
|
164
|
-
}, le = V(() => ({
|
|
165
|
-
transform: `translate(${u.value.x}px, ${u.value.y}px) scale(${b.value}) rotate(${n.rotation}deg)`,
|
|
166
|
-
transformOrigin: "center",
|
|
167
|
-
transition: U.value ? "none" : "transform 0.3s ease-out",
|
|
168
|
-
opacity: y.value && !d.value && !p.value ? 1 : 0
|
|
169
|
-
})), ne = V(() => n.fileSize == null ? "" : ` · ${pe(n.fileSize)}`);
|
|
170
|
-
return (e, t) => (c(), _("div", {
|
|
171
|
-
ref_key: "containerRef",
|
|
172
|
-
ref: C,
|
|
173
|
-
class: "vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden",
|
|
174
|
-
style: K({ cursor: U.value ? "grabbing" : "grab" }),
|
|
175
|
-
onMousedown: te,
|
|
176
|
-
onMousemove: ae,
|
|
177
|
-
onMouseup: N,
|
|
178
|
-
onMouseleave: N
|
|
179
|
-
}, [
|
|
180
|
-
r.value ? (c(), _("div", he, [
|
|
181
|
-
re(q(ve), { class: "vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin" }),
|
|
182
|
-
z("p", me, [
|
|
183
|
-
t[2] || (t[2] = ue(" 正在解码... ", -1)),
|
|
184
|
-
j.value > 0 ? (c(), _("span", ge, M(Math.round(j.value)) + "%", 1)) : g("", !0)
|
|
185
|
-
])
|
|
186
|
-
])) : g("", !0),
|
|
187
|
-
p.value ? (c(), G(F, {
|
|
188
|
-
key: 1,
|
|
189
|
-
message: q(D)("image.decode_failed"),
|
|
190
|
-
detail: p.value
|
|
191
|
-
}, null, 8, ["message", "detail"])) : g("", !0),
|
|
192
|
-
!y.value && !d.value && !r.value && !p.value ? (c(), _("div", ye, [...t[3] || (t[3] = [
|
|
193
|
-
z("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
|
|
194
|
-
])])) : g("", !0),
|
|
195
|
-
d.value ? (c(), G(F, {
|
|
196
|
-
key: 3,
|
|
197
|
-
message: d.value
|
|
198
|
-
}, null, 8, ["message"])) : g("", !0),
|
|
199
|
-
h.value ? (c(), _("img", {
|
|
200
|
-
key: 4,
|
|
201
|
-
ref_key: "imgRef",
|
|
202
|
-
ref: A,
|
|
203
|
-
src: h.value,
|
|
204
|
-
alt: "Preview",
|
|
205
|
-
class: ie(["vfp-max-w-none vfp-select-none", (!y.value || d.value || p.value) && "vfp-hidden"]),
|
|
206
|
-
style: K(le.value),
|
|
207
|
-
draggable: !1,
|
|
208
|
-
onLoad: I,
|
|
209
|
-
onError: J,
|
|
210
|
-
onDblclick: ee
|
|
211
|
-
}, null, 46, be)) : g("", !0),
|
|
212
|
-
y.value && !d.value && x.value.width > 0 ? (c(), _("div", xe, M(x.value.width) + " × " + M(x.value.height) + M(ne.value), 1)) : g("", !0),
|
|
213
|
-
k.value > 1 ? (c(), _("div", we, [
|
|
214
|
-
z("button", {
|
|
215
|
-
type: "button",
|
|
216
|
-
disabled: m.value <= 1 || r.value,
|
|
217
|
-
class: "vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed",
|
|
218
|
-
onClick: t[0] || (t[0] = (a) => T(m.value - 1))
|
|
219
|
-
}, " 上一页 ", 8, _e),
|
|
220
|
-
z("span", ke, M(m.value) + " / " + M(k.value), 1),
|
|
221
|
-
z("button", {
|
|
222
|
-
type: "button",
|
|
223
|
-
disabled: m.value >= k.value || r.value,
|
|
224
|
-
class: "vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed",
|
|
225
|
-
onClick: t[1] || (t[1] = (a) => T(m.value + 1))
|
|
226
|
-
}, " 下一页 ", 8, Ce)
|
|
227
|
-
])) : g("", !0)
|
|
228
|
-
], 36));
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
export {
|
|
232
|
-
ze as default
|
|
233
|
-
};
|
|
234
|
-
//# sourceMappingURL=index-y7gaKu36.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-y7gaKu36.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { Loader2 } from 'lucide-vue-next';\nimport { formatFileSize, detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n file?: PreviewFile | File;\n}>();\n\nconst emit = defineEmits<{\n (e: 'zoomChange', zoom: number): void;\n (e: 'naturalWidthChange', width: number): void;\n (e: 'naturalHeightChange', height: number): void;\n}>();\n\nconst { t } = useTranslator();\n\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst decoding = ref(false);\nconst decodeProgress = ref(0);\nconst decodeError = ref<string | null>(null);\nconst imageSrc = ref<string>('');\nconst currentPage = ref(1);\nconst totalPages = ref(1);\nconst isRawThumbnail = ref(false);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet blobUrl: string | null = null;\nlet fileBlobCache: Blob | null = null;\nlet loaderCache: any = null;\nconst pageCache = new Map<number, string>();\n\n// 解码逻辑\nwatch(\n () => [props.url, props.file] as const,\n async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n imageSrc.value = '';\n loaded.value = false;\n error.value = null;\n decoding.value = false;\n decodeError.value = null;\n decodeProgress.value = 0;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n currentPage.value = 1;\n totalPages.value = 1;\n isRawThumbnail.value = false;\n\n // 清理旧的 blob URL 与缓存\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n fileBlobCache = null;\n loaderCache = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!props.file) {\n imageSrc.value = props.url;\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(props.file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n imageSrc.value = props.url;\n return;\n }\n\n // 需要解码\n decoding.value = true;\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (props.file instanceof Blob) {\n fileBlob = props.file;\n } else {\n const response = await fetch(props.url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n // 缓存 Blob 与 loader\n fileBlobCache = fileBlob;\n loaderCache = loader;\n\n // 标记 RAW 缩略图模式\n const isRaw = mimeType.startsWith('image/x-');\n if (isRaw) {\n isRawThumbnail.value = true;\n }\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (metadata.pageCount && metadata.pageCount > 1) {\n totalPages.value = metadata.pageCount;\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n decodeProgress.value = percent;\n },\n });\n\n // 生成 blob URL\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrl = url;\n pageCache.set(1, url);\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '解码失败';\n decoding.value = false;\n }\n },\n { immediate: true }\n);\n\n// 多页 TIFF 翻页\nconst handlePageChange = async (page: number) => {\n if (!fileBlobCache || !loaderCache) return;\n if (page < 1 || page > totalPages.value) return;\n\n // 命中缓存:直接切换\n const cached = pageCache.get(page);\n if (cached) {\n currentPage.value = page;\n imageSrc.value = cached;\n return;\n }\n\n // 解码新页面\n decoding.value = true;\n try {\n const decodedBlob = await loaderCache.decode(fileBlobCache, { page });\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCache.size >= 10) {\n const firstKey = pageCache.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCache.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCache.delete(firstKey);\n }\n }\n\n pageCache.set(page, url);\n currentPage.value = page;\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '翻页解码失败';\n decoding.value = false;\n }\n};\n\n// Cleanup on unmount\nonBeforeUnmount(() => {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nwatch(\n () => props.zoom,\n (z) => {\n internalZoom.value = z;\n }\n);\n\nwatch(\n () => props.resetKey,\n () => {\n position.value = { x: 0, y: 0 };\n }\n);\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\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};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n emit('naturalWidthChange', img.naturalWidth);\n emit('naturalHeightChange', img.naturalHeight);\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\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 const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n isDragging.value = false;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${props.rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value && !error.value && !decodeError.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <!-- 解码中 -->\n <div\n v-if=\"decoding\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10\"\n >\n <Loader2 class=\"vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin\" />\n <p class=\"vfp-mt-4 vfp-text-fg-secondary\">\n 正在解码... <span v-if=\"decodeProgress > 0\">{{ Math.round(decodeProgress) }}%</span>\n </p>\n </div>\n\n <!-- 解码错误 -->\n <RendererError v-if=\"decodeError\" :message=\"t('image.decode_failed')\" :detail=\"decodeError\" />\n\n <div v-if=\"!loaded && !error && !decoding && !decodeError\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <img\n v-if=\"imageSrc\"\n ref=\"imgRef\"\n :src=\"imageSrc\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', (!loaded || error || decodeError) && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n\n <!-- 多页 TIFF 翻页器 -->\n <div\n v-if=\"totalPages > 1\"\n class=\"vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md\"\n >\n <button\n type=\"button\"\n :disabled=\"currentPage <= 1 || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage - 1)\"\n >\n 上一页\n </button>\n <span class=\"vfp-text-fg-secondary vfp-tabular-nums\">\n {{ currentPage }} / {{ totalPages }}\n </span>\n <button\n type=\"button\"\n :disabled=\"currentPage >= totalPages || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage + 1)\"\n >\n 下一页\n </button>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","t","useTranslator","loaded","ref","error","decoding","decodeProgress","decodeError","imageSrc","currentPage","totalPages","isRawThumbnail","position","isDragging","dragStart","internalZoom","naturalSize","imgRef","containerRef","blobUrl","fileBlobCache","loaderCache","pageCache","watch","url","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","err","handlePageChange","page","cached","firstKey","oldUrl","onBeforeUnmount","container","handleWheelNative","z","clampPosition","pos","currentZoom","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","handleError","handleDoubleClick","rect","mouseX","mouseY","delta","prev","newZoom","scale","onMounted","handleMouseDown","handleMouseMove","handleMouseUp","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_createVNode","_unref","Loader2","_createElementVNode","_hoisted_2","_createBlock","RendererError","_hoisted_4","_cache","_normalizeClass","_hoisted_6","_toDisplayString","_hoisted_7","$event","_hoisted_8","_hoisted_9","_hoisted_10"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,UAAMA,IAAQC,GASRC,IAAOC,GAMP,EAAE,GAAAC,EAAA,IAAMC,GAAA,GAERC,IAASC,EAAI,EAAK,GAClBC,IAAQD,EAAmB,IAAI,GAC/BE,IAAWF,EAAI,EAAK,GACpBG,IAAiBH,EAAI,CAAC,GACtBI,IAAcJ,EAAmB,IAAI,GACrCK,IAAWL,EAAY,EAAE,GACzBM,IAAcN,EAAI,CAAC,GACnBO,IAAaP,EAAI,CAAC,GAClBQ,IAAiBR,EAAI,EAAK,GAC1BS,IAAWT,EAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAC7BU,IAAaV,EAAI,EAAK;AAC5B,QAAIW,IAAY,EAAE,GAAG,GAAG,GAAG,EAAA;AAC3B,UAAMC,IAAeZ,EAAI,CAAC,GACpBa,IAAcb,EAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,GAEzCc,IAASd,EAA6B,IAAI,GAC1Ce,IAAef,EAA2B,IAAI;AACpD,QAAIgB,IAAyB,MACzBC,IAA6B,MAC7BC,IAAmB;AACvB,UAAMC,wBAAgB,IAAA;AAGtB,IAAAC;AAAA,MACE,MAAM,CAAC3B,EAAM,KAAKA,EAAM,IAAI;AAAA,MAC5B,YAAY;AAyBV,YAvBAY,EAAS,QAAQ,IACjBN,EAAO,QAAQ,IACfE,EAAM,QAAQ,MACdC,EAAS,QAAQ,IACjBE,EAAY,QAAQ,MACpBD,EAAe,QAAQ,GACvBM,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA,GAC5BG,EAAa,QAAQ,GACrBN,EAAY,QAAQ,GACpBC,EAAW,QAAQ,GACnBC,EAAe,QAAQ,IAGnBQ,MACF,IAAI,gBAAgBA,CAAO,GAC3BA,IAAU,OAEZG,EAAU,QAAQ,CAACE,MAAQ,IAAI,gBAAgBA,CAAG,CAAC,GACnDF,EAAU,MAAA,GACVF,IAAgB,MAChBC,IAAc,MAGV,CAACzB,EAAM,MAAM;AACf,UAAAY,EAAS,QAAQZ,EAAM;AACvB;AAAA,QACF;AAEA,YAAI;AAEF,gBAAM6B,IAAW,MAAMC,GAAkB9B,EAAM,IAAI,GAC7C+B,IAAS,MAAMC,GAAqBH,CAAQ;AAGlD,cAAI,CAACE,KAAU,CAAE,MAAMA,EAAO,YAAYF,CAAQ,GAAI;AACpD,YAAAjB,EAAS,QAAQZ,EAAM;AACvB;AAAA,UACF;AAGA,UAAAS,EAAS,QAAQ;AAGjB,cAAIwB;AACJ,cAAIjC,EAAM,gBAAgB;AACxB,YAAAiC,IAAWjC,EAAM;AAAA,eACZ;AACL,kBAAMkC,IAAW,MAAM,MAAMlC,EAAM,GAAG;AACtC,gBAAI,CAACkC,EAAS,GAAI,OAAM,IAAI,MAAM,sBAAsB;AACxD,YAAAD,IAAW,MAAMC,EAAS,KAAA;AAAA,UAC5B;AAaA,cAVAV,IAAgBS,GAChBR,IAAcM,GAGAF,EAAS,WAAW,UAAU,MAE1Cd,EAAe,QAAQ,KAIrBgB,EAAO;AACT,gBAAI;AACF,oBAAMI,IAAW,MAAMJ,EAAO,YAAYE,CAAQ;AAClD,cAAIE,EAAS,aAAaA,EAAS,YAAY,MAC7CrB,EAAW,QAAQqB,EAAS;AAAA,YAEhC,QAAQ;AAAA,YAER;AAIF,gBAAMC,IAAc,MAAML,EAAO,OAAOE,GAAU;AAAA,YAChD,MAAM;AAAA,YACN,aAAa;AAAA,YACb,YAAY,CAACI,MAAoB;AAC/B,cAAA3B,EAAe,QAAQ2B;AAAA,YACzB;AAAA,UAAA,CACD,GAGKT,IAAM,OAAOQ,KAAgB,WAC/BA,IACA,IAAI,gBAAgBA,CAAW;AAEnC,UAAAb,IAAUK,GACVF,EAAU,IAAI,GAAGE,CAAG,GACpBhB,EAAS,QAAQgB,GACjBnB,EAAS,QAAQ;AAAA,QACnB,SAAS6B,GAAU;AACjB,UAAA3B,EAAY,SAAQ2B,KAAA,gBAAAA,EAAK,YAAW,QACpC7B,EAAS,QAAQ;AAAA,QACnB;AAAA,MACF;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK;AAIpB,UAAM8B,IAAmB,OAAOC,MAAiB;AAE/C,UADI,CAAChB,KAAiB,CAACC,KACnBe,IAAO,KAAKA,IAAO1B,EAAW,MAAO;AAGzC,YAAM2B,IAASf,EAAU,IAAIc,CAAI;AACjC,UAAIC,GAAQ;AACV,QAAA5B,EAAY,QAAQ2B,GACpB5B,EAAS,QAAQ6B;AACjB;AAAA,MACF;AAGA,MAAAhC,EAAS,QAAQ;AACjB,UAAI;AACF,cAAM2B,IAAc,MAAMX,EAAY,OAAOD,GAAe,EAAE,MAAAgB,GAAM,GAC9DZ,IAAM,OAAOQ,KAAgB,WAC/BA,IACA,IAAI,gBAAgBA,CAAW;AAGnC,YAAIV,EAAU,QAAQ,IAAI;AACxB,gBAAMgB,IAAWhB,EAAU,KAAA,EAAO,OAAO;AACzC,cAAIgB,MAAa,QAAW;AAC1B,kBAAMC,IAASjB,EAAU,IAAIgB,CAAQ;AACrC,YAAIC,KAAQ,IAAI,gBAAgBA,CAAM,GACtCjB,EAAU,OAAOgB,CAAQ;AAAA,UAC3B;AAAA,QACF;AAEA,QAAAhB,EAAU,IAAIc,GAAMZ,CAAG,GACvBf,EAAY,QAAQ2B,GACpB5B,EAAS,QAAQgB,GACjBnB,EAAS,QAAQ;AAAA,MACnB,SAAS6B,GAAU;AACjB,QAAA3B,EAAY,SAAQ2B,KAAA,gBAAAA,EAAK,YAAW,UACpC7B,EAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAGA,IAAAmC,EAAgB,MAAM;AACpB,MAAIrB,KACF,IAAI,gBAAgBA,CAAO,GAE7BG,EAAU,QAAQ,CAACE,MAAQ,IAAI,gBAAgBA,CAAG,CAAC,GACnDF,EAAU,MAAA;AACV,YAAMmB,IAAYvB,EAAa;AAC/B,MAAIuB,KACFA,EAAU,oBAAoB,SAASC,CAAiB;AAAA,IAE5D,CAAC,GAEDnB;AAAA,MACE,MAAM3B,EAAM;AAAA,MACZ,CAAC+C,MAAM;AACL,QAAA5B,EAAa,QAAQ4B;AAAA,MACvB;AAAA,IAAA,GAGFpB;AAAA,MACE,MAAM3B,EAAM;AAAA,MACZ,MAAM;AACJ,QAAAgB,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,MAC9B;AAAA,IAAA;AAGF,UAAMgC,IAAgB,CAACC,GAA+BC,MAAwB;AAC5E,YAAML,IAAYvB,EAAa;AAC/B,UAAI,CAACuB,KAAazB,EAAY,MAAM,UAAU,EAAG,QAAO6B;AAExD,YAAME,IAAaN,EAAU,aACvBO,IAAaP,EAAU,cACvBQ,IAAOjC,EAAY,MAAM,QAAQ8B,GACjCI,IAAOlC,EAAY,MAAM,SAAS8B,GAElCK,IAAS,KAAK,IAAI,IAAIJ,IAAa,MAAMC,IAAa,IAAI,GAC1DI,KAAUL,IAAaE,KAAQ,IAAIE,GACnCE,KAAUL,IAAaE,KAAQ,IAAIC;AAEzC,aAAO;AAAA,QACL,GAAGC,IAAS,IAAI,KAAK,IAAI,CAACA,GAAQ,KAAK,IAAIA,GAAQP,EAAI,CAAC,CAAC,IAAI;AAAA,QAC7D,GAAGQ,IAAS,IAAI,KAAK,IAAI,CAACA,GAAQ,KAAK,IAAIA,GAAQR,EAAI,CAAC,CAAC,IAAI;AAAA,MAAA;AAAA,IAEjE,GAEMS,IAAa,CAAC,MAAa;AAC/B,MAAApD,EAAO,QAAQ;AACf,YAAMqD,IAAM,EAAE;AACd,MAAAvC,EAAY,QAAQ,EAAE,OAAOuC,EAAI,cAAc,QAAQA,EAAI,cAAA,GAC3DzD,EAAK,sBAAsByD,EAAI,YAAY,GAC3CzD,EAAK,uBAAuByD,EAAI,aAAa;AAAA,IAC/C,GAEMC,IAAc,MAAM;AACxB,MAAApD,EAAM,QAAQJ,EAAE,MAAM,mBAAmB,GACzCE,EAAO,QAAQ;AAAA,IACjB,GAEMuD,KAAoB,MAAM;AAC9B,MAAA7C,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA,GAC5BG,EAAa,QAAQ,GACrBjB,EAAK,cAAc,CAAC;AAAA,IACtB,GAGM4C,IAAoB,CAAC,MAAkB;AAC3C,QAAE,eAAA,GACF,EAAE,gBAAA;AAEF,YAAMD,IAAYvB,EAAa;AAC/B,UAAI,CAACuB,EAAW;AAEhB,YAAMiB,IAAOjB,EAAU,sBAAA,GACjBkB,IAAS,EAAE,UAAUD,EAAK,OAAOA,EAAK,QAAQ,GAC9CE,IAAS,EAAE,UAAUF,EAAK,MAAMA,EAAK,SAAS,GAE9CG,IAAQ,EAAE,SAAS,IAAI,QAAQ,MAC/BC,IAAO/C,EAAa,OACpBgD,IAAU,KAAK,IAAI,MAAM,KAAK,IAAI,IAAID,IAAOD,CAAK,CAAC,GACnDG,IAAQD,IAAUD;AAExB,MAAAlD,EAAS,QAAQgC;AAAA,QACf;AAAA,UACE,GAAGe,IAASK,KAASL,IAAS/C,EAAS,MAAM;AAAA,UAC7C,GAAGgD,IAASI,KAASJ,IAAShD,EAAS,MAAM;AAAA,QAAA;AAAA,QAE/CmD;AAAA,MAAA,GAGFhD,EAAa,QAAQgD,GACrBjE,EAAK,cAAciE,CAAO;AAAA,IAC5B;AAEA,IAAAE,GAAU,MAAM;AACd,YAAMxB,IAAYvB,EAAa;AAC/B,MAAIuB,KACFA,EAAU,iBAAiB,SAASC,GAAmB,EAAE,SAAS,IAAO;AAAA,IAE7E,CAAC,GAEDF,EAAgB,MAAM;AACpB,YAAMC,IAAYvB,EAAa;AAC/B,MAAIuB,KACFA,EAAU,oBAAoB,SAASC,CAAiB;AAAA,IAE5D,CAAC;AAED,UAAMwB,KAAkB,CAAC,MAAkB;AACzC,MAAI,EAAE,WAAW,MACjBrD,EAAW,QAAQ,IACnBC,IAAY;AAAA,QACV,GAAG,EAAE,UAAUF,EAAS,MAAM;AAAA,QAC9B,GAAG,EAAE,UAAUA,EAAS,MAAM;AAAA,MAAA;AAAA,IAElC,GAEMuD,KAAkB,CAAC,MAAkB;AACzC,MAAKtD,EAAW,UAChBD,EAAS,QAAQgC;AAAA,QACf;AAAA,UACE,GAAG,EAAE,UAAU9B,EAAU;AAAA,UACzB,GAAG,EAAE,UAAUA,EAAU;AAAA,QAAA;AAAA,QAE3BC,EAAa;AAAA,MAAA;AAAA,IAEjB,GAEMqD,IAAgB,MAAM;AAC1B,MAAAvD,EAAW,QAAQ;AAAA,IACrB,GAEMwD,KAAiBC,EAAS,OAAO;AAAA,MACrC,WAAW,aAAa1D,EAAS,MAAM,CAAC,OAAOA,EAAS,MAAM,CAAC,aAAaG,EAAa,KAAK,YAAYnB,EAAM,QAAQ;AAAA,MACxH,iBAAiB;AAAA,MACjB,YAAYiB,EAAW,QAAQ,SAAS;AAAA,MACxC,SAASX,EAAO,SAAS,CAACE,EAAM,SAAS,CAACG,EAAY,QAAQ,IAAI;AAAA,IAAA,EAClE,GAEIgE,KAAWD,EAAS,MACpB1E,EAAM,YAAY,OAAa,KAC5B,MAAM4E,GAAe5E,EAAM,QAAQ,CAAC,EAC5C;2BAIC6E,EA4EM,OAAA;AAAA,eA3EA;AAAA,MAAJ,KAAIvD;AAAA,MACJ,OAAM;AAAA,MACL,mBAAiBL,EAAA,QAAU,aAAA,QAAA;AAAA,MAC3B,aAAWqD;AAAA,MACX,aAAWC;AAAA,MACX,WAASC;AAAA,MACT,cAAYA;AAAA,IAAA;MAIL/D,EAAA,SADRqE,EAAA,GAAAD,EAQM,OARNE,IAQM;AAAA,QAJJC,GAA0EC,EAAAC,EAAA,GAAA,EAAjE,OAAM,0DAAwD;AAAA,QACvEC,EAEI,KAFJC,IAEI;AAAA,6BAFsC,aAChC,EAAA;AAAA,UAAY1E,EAAA,QAAc,KAA1BoE,EAAA,GAAAD,EAAwE,cAArC,KAAK,MAAMnE,EAAA,KAAc,KAAI,KAAC,CAAA;;;MAKxDC,EAAA,cAArB0E,EAA8FC,GAAA;AAAA;QAA3D,SAASL,EAAA7E,CAAA,EAAC,qBAAA;AAAA,QAA0B,QAAQO,EAAA;AAAA,MAAA;MAEnE,CAAAL,EAAA,SAAM,CAAKE,EAAA,SAAK,CAAKC,EAAA,UAAaE,EAAA,SAA9CmE,KAAAD,EAIM,OAJNU,IAIM,CAAA,GAAAC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA;AAAA,QAHJL,EAEE,OAAA,EADA,OAAM,oHAAA,GAAmH,MAAA,EAAA;AAAA,MAAA;MAIxG3E,EAAA,cAArB6E,EAA+CC,GAAA;AAAA;QAAlB,SAAS9E,EAAA;AAAA,MAAA;MAG9BI,EAAA,cADRiE,EAWE,OAAA;AAAA;iBATI;AAAA,QAAJ,KAAIxD;AAAA,QACH,KAAKT,EAAA;AAAA,QACN,KAAI;AAAA,QACH,OAAK6E,GAAA,CAAA,mCAAA,CAAuCnF,EAAA,SAAUE,EAAA,SAASG,EAAA,UAAW,YAAA,CAAA;AAAA,QAC1E,SAAO8D,GAAA,KAAc;AAAA,QACrB,WAAW;AAAA,QACX,QAAMf;AAAA,QACN,SAAOE;AAAA,QACP,YAAUC;AAAA,MAAA;MAILvD,EAAA,SAAM,CAAKE,EAAA,SAASY,EAAA,MAAY,QAAK,KAD7C0D,EAAA,GAAAD,EAKM,OALNa,IAKMC,EADDvE,EAAA,MAAY,KAAK,IAAG,QAAGuE,EAAGvE,EAAA,MAAY,MAAM,MAAMuD,GAAA,KAAQ,GAAA,CAAA;MAKvD7D,EAAA,QAAU,KADlBgE,KAAAD,EAuBM,OAvBNe,IAuBM;AAAA,QAnBJT,EAOS,UAAA;AAAA,UANP,MAAK;AAAA,UACJ,UAAUtE,EAAA,SAAW,KAASJ,EAAA;AAAA,UAC/B,OAAM;AAAA,UACL,SAAK+E,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAK,MAAEtD,EAAiB1B,EAAA,QAAW,CAAA;AAAA,QAAA,GACrC,SAED,GAAAiF,EAAA;AAAA,QACAX,EAEO,QAFPY,IAEOJ,EADF9E,OAAW,IAAG,UAAMC,EAAA,KAAU,GAAA,CAAA;AAAA,QAEnCqE,EAOS,UAAA;AAAA,UANP,MAAK;AAAA,UACJ,UAAUtE,EAAA,SAAeC,EAAA,SAAcL,EAAA;AAAA,UACxC,OAAM;AAAA,UACL,SAAK+E,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAK,MAAEtD,EAAiB1B,EAAA,QAAW,CAAA;AAAA,QAAA,GACrC,SAED,GAAAmF,EAAA;AAAA,MAAA;;;;"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|