@brftech/filex 0.1.56
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/LICENSE +21 -0
- package/README.md +93 -0
- package/dist/ArchiveViewer-CMaBM4yZ.js +98 -0
- package/dist/ArchiveViewer-CMaBM4yZ.js.map +1 -0
- package/dist/CsvViewer-D5_c7bkP.js +131 -0
- package/dist/CsvViewer-D5_c7bkP.js.map +1 -0
- package/dist/DrawioViewer-CBOqWzaj.js +140 -0
- package/dist/DrawioViewer-CBOqWzaj.js.map +1 -0
- package/dist/EpubViewer-Cs6yZIP2.js +143 -0
- package/dist/EpubViewer-Cs6yZIP2.js.map +1 -0
- package/dist/IpynbViewer-wJhbhUla.js +171 -0
- package/dist/IpynbViewer-wJhbhUla.js.map +1 -0
- package/dist/MermaidViewer-k_XVXoc5.js +127 -0
- package/dist/MermaidViewer-k_XVXoc5.js.map +1 -0
- package/dist/PsdViewer-Bo4imBCF.js +109 -0
- package/dist/PsdViewer-Bo4imBCF.js.map +1 -0
- package/dist/TiffViewer-D73-Gyt-.js +130 -0
- package/dist/TiffViewer-D73-Gyt-.js.map +1 -0
- package/dist/UTIF-DSbsvqXu.js +3104 -0
- package/dist/UTIF-DSbsvqXu.js.map +1 -0
- package/dist/Viewer3D-Ba-RPIRz.js +60 -0
- package/dist/Viewer3D-Ba-RPIRz.js.map +1 -0
- package/dist/_commonjsHelpers-DaMA6jEr.js +9 -0
- package/dist/_commonjsHelpers-DaMA6jEr.js.map +1 -0
- package/dist/filex.js +5 -0
- package/dist/filex.js.map +1 -0
- package/dist/filex.umd.cjs +304 -0
- package/dist/filex.umd.cjs.map +1 -0
- package/dist/index-UFULWo35.js +10736 -0
- package/dist/index-UFULWo35.js.map +1 -0
- package/dist/index-idz8Cz5t.js +10623 -0
- package/dist/index-idz8Cz5t.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/katex-yuB6V-q6.js +11616 -0
- package/dist/katex-yuB6V-q6.js.map +1 -0
- package/dist/papaparse.min-VB1HBwYX.js +441 -0
- package/dist/papaparse.min-VB1HBwYX.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/useViewerFetch-czqbd2Lj.js +25 -0
- package/dist/useViewerFetch-czqbd2Lj.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PsdViewer-Bo4imBCF.js","sources":["../../core/src/viewers/PsdViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * PsdViewer — Photoshop document preview via `ag-psd`.\r\n *\r\n * Lazy-imports `ag-psd` (~150 KB). Renders the flattened composite to\r\n * a canvas via `psd.canvas`. A simple layer panel toggles the rendered\r\n * preview (V1: just lists names + visibility; full composite swap on\r\n * toggle requires re-rendering with `applyOpacity`/`composite` logic\r\n * — left as TODO for V2 since `ag-psd` doesn't ship a composite\r\n * pipeline of its own).\r\n */\r\nimport { onBeforeUnmount, onMounted, ref, watch } from 'vue';\r\nimport { fetchViewerArrayBuffer } from '../composables/useViewerFetch';\r\n\r\nconst props = defineProps<{\r\n url: string;\r\n mime?: string;\r\n ext: string;\r\n t?: (key: string) => string;\r\n authHeaders?: () => Record<string, string>;\r\n authCredentials?: RequestCredentials;\r\n}>();\r\n\r\ninterface FlatLayer {\r\n index: number;\r\n name: string;\r\n hidden: boolean;\r\n}\r\n\r\nconst canvasEl = ref<HTMLCanvasElement | null>(null);\r\nconst layers = ref<FlatLayer[]>([]);\r\nconst error = ref<string | null>(null);\r\nconst loading = ref(true);\r\nconst showLayerPanel = ref(false);\r\nconst dims = ref<{ width: number; height: number }>({ width: 0, height: 0 });\r\nconst scale = ref(1);\r\n\r\nlet renderToken = 0;\r\n\r\nlet agPsd: any = null;\r\nasync function ensureAgPsd(): Promise<any | null> {\r\n if (agPsd) return agPsd;\r\n try {\r\n const mod = await import(/* @vite-ignore */ 'ag-psd');\r\n agPsd = mod;\r\n return agPsd;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction flattenLayers(node: any, list: FlatLayer[]): void {\r\n if (!node) return;\r\n if (Array.isArray(node.children)) {\r\n for (const child of node.children) {\r\n list.push({\r\n index: list.length,\r\n name: child.name ?? '(unnamed)',\r\n hidden: !!child.hidden,\r\n });\r\n if (child.children) flattenLayers(child, list);\r\n }\r\n }\r\n}\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n error.value = null;\r\n layers.value = [];\r\n const myToken = ++renderToken;\r\n\r\n const lib = await ensureAgPsd();\r\n if (myToken !== renderToken) return;\r\n if (!lib) {\r\n error.value = props.t\r\n ? props.t('viewer.peer_not_installed')\r\n : 'PSD viewer requires `ag-psd` — install or use download.';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n try {\r\n const buf = await fetchViewerArrayBuffer({\r\n url: props.url,\r\n headers: props.authHeaders?.() ?? {},\r\n credentials: props.authCredentials,\r\n });\r\n if (myToken !== renderToken) return;\r\n const psd = lib.readPsd(buf, {\r\n skipLayerImageData: false,\r\n skipCompositeImageData: false,\r\n skipThumbnail: true,\r\n });\r\n dims.value = { width: psd.width, height: psd.height };\r\n\r\n const composite = psd.canvas;\r\n if (composite && canvasEl.value) {\r\n const target = canvasEl.value;\r\n target.width = psd.width;\r\n target.height = psd.height;\r\n const ctx = target.getContext('2d');\r\n ctx?.drawImage(composite, 0, 0);\r\n } else {\r\n throw new Error('PSD has no composite image (skipCompositeImageData?)');\r\n }\r\n\r\n const flat: FlatLayer[] = [];\r\n flattenLayers(psd, flat);\r\n layers.value = flat;\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'PSD decode failed';\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\nfunction zoomIn(): void {\r\n scale.value = Math.min(8, scale.value * 1.25);\r\n}\r\nfunction zoomOut(): void {\r\n scale.value = Math.max(0.1, scale.value / 1.25);\r\n}\r\nfunction reset(): void {\r\n scale.value = 1;\r\n}\r\n\r\nonMounted(load);\r\nonBeforeUnmount(() => {\r\n renderToken++;\r\n});\r\nwatch(() => props.url, load);\r\n\r\nfunction tt(key: string, fallback: string): string {\r\n return props.t ? props.t(key) : fallback;\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"filex-viewer-psd\">\r\n <div class=\"filex-viewer-psd__pane\">\r\n <div v-if=\"error\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">🎨</span>\r\n <p>{{ error }}</p>\r\n </div>\r\n <div v-else-if=\"loading\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">⏳</span>\r\n <p>{{ tt('viewer.loading', 'Loading…') }}</p>\r\n </div>\r\n <canvas\r\n v-show=\"!loading && !error\"\r\n ref=\"canvasEl\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-psd {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 70vh;\r\n background: var(--fe-bg, #fff);\r\n}\r\n.filex-viewer-psd__bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 8px 12px;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n border-bottom: 1px solid var(--fe-border, #e2e6ed);\r\n font-size: 13px;\r\n}\r\n.filex-viewer-spacer { flex: 1; }\r\n.filex-viewer-psd__dim {\r\n font-size: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-psd__zoom {\r\n min-width: 50px;\r\n text-align: center;\r\n font-variant-numeric: tabular-nums;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-psd__main {\r\n flex: 1;\r\n display: flex;\r\n min-height: 0;\r\n}\r\n.filex-viewer-psd__layers {\r\n width: 240px;\r\n border-right: 1px solid var(--fe-border, #e2e6ed);\r\n overflow-y: auto;\r\n padding: 8px 0;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n}\r\n.filex-viewer-psd__layers ul {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n.filex-viewer-psd__layers li {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 4px 12px;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-psd__layer-vis {\r\n width: 14px;\r\n text-align: center;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-psd__layer-vis[data-hidden=\"1\"] { color: var(--fe-border-strong, #c7ced9); }\r\n.filex-viewer-psd__layer-name {\r\n flex: 1;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n.filex-viewer-psd__pane {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 16px;\r\n background: #2a2d33;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: flex-start;\r\n}\r\n.filex-viewer-psd__pane canvas {\r\n background: #fff\r\n repeating-conic-gradient(#e0e0e0 0% 25%, transparent 0% 50%) 50% / 16px 16px;\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: #c8cdd6;\r\n margin: auto;\r\n}\r\n.filex-viewer-fallback__icon {\r\n font-size: 48px;\r\n display: block;\r\n margin-bottom: 12px;\r\n}\r\n.filex-viewer-btn {\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n padding: 4px 10px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font: inherit;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-btn:hover:not(:disabled) {\r\n background: var(--fe-bg-hover, #edf0f5);\r\n}\r\n.filex-viewer-btn.is-active {\r\n background: var(--fe-bg-selected, #dfe8ff);\r\n border-color: var(--fe-primary, #3b82f6);\r\n}\r\n</style>\r\n"],"names":["props","__props","canvasEl","ref","layers","error","loading","dims","renderToken","agPsd","ensureAgPsd","flattenLayers","node","list","child","load","myToken","lib","buf","fetchViewerArrayBuffer","_a","psd","composite","target","ctx","flat","err","onMounted","onBeforeUnmount","watch","tt","key","fallback","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_cache","_hoisted_4","_vShow"],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { d as S, o as U, h as M, w as N, a as _, c as h, e as i, t as b, i as C, j as A, v as H, f as d, g as L, _ as R } from "./index-idz8Cz5t.js";
|
|
2
|
+
import { a as j } from "./useViewerFetch-czqbd2Lj.js";
|
|
3
|
+
const q = { class: "filex-viewer-tiff" }, G = { class: "filex-viewer-tiff__pane" }, P = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "filex-viewer-fallback"
|
|
6
|
+
}, z = {
|
|
7
|
+
key: 1,
|
|
8
|
+
class: "filex-viewer-fallback"
|
|
9
|
+
}, J = {
|
|
10
|
+
key: 2,
|
|
11
|
+
class: "filex-viewer-tiff__pager"
|
|
12
|
+
}, K = ["disabled"], O = { class: "filex-viewer-tiff__pages" }, Q = ["disabled"], W = /* @__PURE__ */ S({
|
|
13
|
+
__name: "TiffViewer",
|
|
14
|
+
props: {
|
|
15
|
+
url: {},
|
|
16
|
+
mime: {},
|
|
17
|
+
ext: {},
|
|
18
|
+
t: { type: Function },
|
|
19
|
+
authHeaders: { type: Function },
|
|
20
|
+
authCredentials: {}
|
|
21
|
+
},
|
|
22
|
+
setup(I) {
|
|
23
|
+
const t = I, p = d(null), o = d(null), c = d(!0), n = d(0), r = d(0), F = d({ width: 0, height: 0 });
|
|
24
|
+
let u = null, l = null, f = 0;
|
|
25
|
+
async function T() {
|
|
26
|
+
if (u) return u;
|
|
27
|
+
try {
|
|
28
|
+
const a = await import(
|
|
29
|
+
/* @vite-ignore */
|
|
30
|
+
"./UTIF-DSbsvqXu.js"
|
|
31
|
+
).then((e) => e.U);
|
|
32
|
+
return u = a.default ?? a, u;
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function y() {
|
|
38
|
+
var v;
|
|
39
|
+
c.value = !0, o.value = null, l = null, n.value = 0, r.value = 0;
|
|
40
|
+
const a = ++f, e = await T();
|
|
41
|
+
if (a === f) {
|
|
42
|
+
if (!e) {
|
|
43
|
+
o.value = t.t ? t.t("viewer.peer_not_installed") : "TIFF viewer requires `utif` — install or use download.", c.value = !1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const s = await j({
|
|
48
|
+
url: t.url,
|
|
49
|
+
headers: ((v = t.authHeaders) == null ? void 0 : v.call(t)) ?? {},
|
|
50
|
+
credentials: t.authCredentials
|
|
51
|
+
});
|
|
52
|
+
if (a !== f) return;
|
|
53
|
+
if (l = e.decode(s), r.value = (l == null ? void 0 : l.length) ?? 0, r.value === 0)
|
|
54
|
+
throw new Error("No pages decoded");
|
|
55
|
+
w();
|
|
56
|
+
} catch (s) {
|
|
57
|
+
o.value = s instanceof Error ? s.message : "TIFF decode failed";
|
|
58
|
+
} finally {
|
|
59
|
+
c.value = !1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function w() {
|
|
64
|
+
if (!u || !l || !p.value) return;
|
|
65
|
+
const a = Math.max(0, Math.min(n.value, l.length - 1)), e = l[a];
|
|
66
|
+
try {
|
|
67
|
+
u.decodeImage(void 0, e);
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
const v = u.toRGBA8(e), s = e.width, g = e.height;
|
|
71
|
+
F.value = { width: s, height: g };
|
|
72
|
+
const m = p.value;
|
|
73
|
+
m.width = s, m.height = g;
|
|
74
|
+
const x = m.getContext("2d");
|
|
75
|
+
if (!x) return;
|
|
76
|
+
const k = x.createImageData(s, g);
|
|
77
|
+
k.data.set(v), x.putImageData(k, 0, 0);
|
|
78
|
+
}
|
|
79
|
+
function B() {
|
|
80
|
+
n.value < r.value - 1 && (n.value++, w());
|
|
81
|
+
}
|
|
82
|
+
function D() {
|
|
83
|
+
n.value > 0 && (n.value--, w());
|
|
84
|
+
}
|
|
85
|
+
U(y), M(() => {
|
|
86
|
+
f++, l = null;
|
|
87
|
+
}), N(() => t.url, y);
|
|
88
|
+
const E = L(() => (t.t && t.t("viewer.page_n_of_m") || "Page {n} of {m}").replace("{n}", String(n.value + 1)).replace("{m}", String(r.value)));
|
|
89
|
+
function V(a, e) {
|
|
90
|
+
return t.t ? t.t(a) : e;
|
|
91
|
+
}
|
|
92
|
+
return (a, e) => (_(), h("div", q, [
|
|
93
|
+
i("div", G, [
|
|
94
|
+
o.value ? (_(), h("div", P, [
|
|
95
|
+
e[0] || (e[0] = i("span", { class: "filex-viewer-fallback__icon" }, "🖼️", -1)),
|
|
96
|
+
i("p", null, b(o.value), 1)
|
|
97
|
+
])) : c.value ? (_(), h("div", z, [
|
|
98
|
+
e[1] || (e[1] = i("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
|
|
99
|
+
i("p", null, b(V("viewer.loading", "Loading…")), 1)
|
|
100
|
+
])) : C("", !0),
|
|
101
|
+
A(i("canvas", {
|
|
102
|
+
ref_key: "canvasEl",
|
|
103
|
+
ref: p,
|
|
104
|
+
style: { imageRendering: "pixelated" }
|
|
105
|
+
}, null, 512), [
|
|
106
|
+
[H, !c.value && !o.value]
|
|
107
|
+
]),
|
|
108
|
+
!c.value && !o.value && r.value > 1 ? (_(), h("div", J, [
|
|
109
|
+
i("button", {
|
|
110
|
+
type: "button",
|
|
111
|
+
class: "filex-viewer-btn",
|
|
112
|
+
disabled: n.value === 0,
|
|
113
|
+
onClick: D
|
|
114
|
+
}, "‹", 8, K),
|
|
115
|
+
i("span", O, b(E.value), 1),
|
|
116
|
+
i("button", {
|
|
117
|
+
type: "button",
|
|
118
|
+
class: "filex-viewer-btn",
|
|
119
|
+
disabled: n.value >= r.value - 1,
|
|
120
|
+
onClick: B
|
|
121
|
+
}, "›", 8, Q)
|
|
122
|
+
])) : C("", !0)
|
|
123
|
+
])
|
|
124
|
+
]));
|
|
125
|
+
}
|
|
126
|
+
}), Z = /* @__PURE__ */ R(W, [["__scopeId", "data-v-9c711133"]]);
|
|
127
|
+
export {
|
|
128
|
+
Z as default
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=TiffViewer-D73-Gyt-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TiffViewer-D73-Gyt-.js","sources":["../../core/src/viewers/TiffViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * TiffViewer — multi-page TIFF preview via `utif`.\r\n *\r\n * Lazy-imports `utif` (~50 KB). Decodes IFDs once, paints the active\r\n * page to a `<canvas>` via `UTIF.toRGBA8`. Page navigation (1/N) +\r\n * zoom in/out controls. Browser <img> can't render TIFF natively, so\r\n * the canvas pipeline is the only option short of server-side\r\n * conversion.\r\n */\r\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';\r\nimport { fetchViewerArrayBuffer } from '../composables/useViewerFetch';\r\n\r\nconst props = defineProps<{\r\n url: string;\r\n mime?: string;\r\n ext: string;\r\n t?: (key: string) => string;\r\n authHeaders?: () => Record<string, string>;\r\n authCredentials?: RequestCredentials;\r\n}>();\r\n\r\nconst canvasEl = ref<HTMLCanvasElement | null>(null);\r\nconst error = ref<string | null>(null);\r\nconst loading = ref(true);\r\nconst scale = ref(1);\r\nconst pageIndex = ref(0);\r\nconst pageCount = ref(0);\r\nconst pageDims = ref<{ width: number; height: number }>({ width: 0, height: 0 });\r\n\r\nlet UTIF: any = null;\r\nlet ifds: any[] | null = null;\r\nlet renderToken = 0;\r\n\r\nasync function ensureUtif(): Promise<any | null> {\r\n if (UTIF) return UTIF;\r\n try {\r\n const mod = await import(/* @vite-ignore */ 'utif');\r\n UTIF = mod.default ?? mod;\r\n return UTIF;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n error.value = null;\r\n ifds = null;\r\n pageIndex.value = 0;\r\n pageCount.value = 0;\r\n const myToken = ++renderToken;\r\n\r\n const lib = await ensureUtif();\r\n if (myToken !== renderToken) return;\r\n if (!lib) {\r\n error.value = props.t\r\n ? props.t('viewer.peer_not_installed')\r\n : 'TIFF viewer requires `utif` — install or use download.';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n try {\r\n const buf = await fetchViewerArrayBuffer({\r\n url: props.url,\r\n headers: props.authHeaders?.() ?? {},\r\n credentials: props.authCredentials,\r\n });\r\n if (myToken !== renderToken) return;\r\n ifds = lib.decode(buf);\r\n pageCount.value = ifds?.length ?? 0;\r\n if (pageCount.value === 0) {\r\n throw new Error('No pages decoded');\r\n }\r\n paint();\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'TIFF decode failed';\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\nfunction paint(): void {\r\n if (!UTIF || !ifds || !canvasEl.value) return;\r\n const idx = Math.max(0, Math.min(pageIndex.value, ifds.length - 1));\r\n const ifd = ifds[idx];\r\n try {\r\n UTIF.decodeImage(undefined, ifd);\r\n } catch {\r\n // some images already decoded — UTIF.decodeImage is idempotent on\r\n // older versions.\r\n }\r\n const rgba = UTIF.toRGBA8(ifd);\r\n const w = ifd.width;\r\n const h = ifd.height;\r\n pageDims.value = { width: w, height: h };\r\n const canvas = canvasEl.value;\r\n canvas.width = w;\r\n canvas.height = h;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n const imageData = ctx.createImageData(w, h);\r\n imageData.data.set(rgba);\r\n ctx.putImageData(imageData, 0, 0);\r\n}\r\n\r\nfunction next(): void {\r\n if (pageIndex.value < pageCount.value - 1) {\r\n pageIndex.value++;\r\n paint();\r\n }\r\n}\r\nfunction prev(): void {\r\n if (pageIndex.value > 0) {\r\n pageIndex.value--;\r\n paint();\r\n }\r\n}\r\nfunction zoomIn(): void {\r\n scale.value = Math.min(8, scale.value * 1.25);\r\n}\r\nfunction zoomOut(): void {\r\n scale.value = Math.max(0.1, scale.value / 1.25);\r\n}\r\nfunction reset(): void {\r\n scale.value = 1;\r\n}\r\n\r\nonMounted(load);\r\nonBeforeUnmount(() => {\r\n renderToken++;\r\n ifds = null;\r\n});\r\n\r\nwatch(() => props.url, load);\r\n\r\nconst pageLabel = computed(() => {\r\n const m = (props.t && props.t('viewer.page_n_of_m')) || 'Page {n} of {m}';\r\n return m.replace('{n}', String(pageIndex.value + 1)).replace('{m}', String(pageCount.value));\r\n});\r\n\r\nfunction tt(key: string, fallback: string): string {\r\n return props.t ? props.t(key) : fallback;\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"filex-viewer-tiff\">\r\n <div class=\"filex-viewer-tiff__pane\">\r\n <div v-if=\"error\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">🖼️</span>\r\n <p>{{ error }}</p>\r\n </div>\r\n <div v-else-if=\"loading\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">⏳</span>\r\n <p>{{ tt('viewer.loading', 'Loading…') }}</p>\r\n </div>\r\n <canvas\r\n v-show=\"!loading && !error\"\r\n ref=\"canvasEl\"\r\n :style=\"{ imageRendering: 'pixelated' }\"\r\n />\r\n <div v-if=\"!loading && !error && pageCount > 1\" class=\"filex-viewer-tiff__pager\">\r\n <button\r\n type=\"button\"\r\n class=\"filex-viewer-btn\"\r\n :disabled=\"pageIndex === 0\"\r\n @click=\"prev\"\r\n >‹</button>\r\n <span class=\"filex-viewer-tiff__pages\">{{ pageLabel }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"filex-viewer-btn\"\r\n :disabled=\"pageIndex >= pageCount - 1\"\r\n @click=\"next\"\r\n >›</button>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-tiff__pager {\r\n position: absolute;\r\n bottom: 12px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 4px 8px;\r\n background: var(--fe-bg-elev, rgba(255, 255, 255, 0.9));\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n border-radius: 6px;\r\n backdrop-filter: blur(4px);\r\n}\r\n.filex-viewer-tiff__pages {\r\n font-size: 12px;\r\n font-variant-numeric: tabular-nums;\r\n}\r\n.filex-viewer-tiff {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 70vh;\r\n background: var(--fe-bg, #fff);\r\n}\r\n.filex-viewer-tiff__bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 8px 12px;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n border-bottom: 1px solid var(--fe-border, #e2e6ed);\r\n font-size: 13px;\r\n}\r\n.filex-viewer-tiff__pages {\r\n min-width: 110px;\r\n text-align: center;\r\n font-variant-numeric: tabular-nums;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-tiff__zoom {\r\n min-width: 50px;\r\n text-align: center;\r\n font-variant-numeric: tabular-nums;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-spacer { flex: 1; }\r\n.filex-viewer-tiff__pane {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 16px;\r\n background: #2a2d33;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: flex-start;\r\n}\r\n.filex-viewer-tiff__pane canvas {\r\n background: #fff;\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: #c8cdd6;\r\n margin: auto;\r\n}\r\n.filex-viewer-fallback__icon {\r\n font-size: 48px;\r\n display: block;\r\n margin-bottom: 12px;\r\n}\r\n.filex-viewer-btn {\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n padding: 4px 10px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font: inherit;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-btn:hover:not(:disabled) {\r\n background: var(--fe-bg-hover, #edf0f5);\r\n}\r\n.filex-viewer-btn:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n}\r\n</style>\r\n"],"names":["props","__props","canvasEl","ref","error","loading","pageIndex","pageCount","pageDims","UTIF","ifds","renderToken","ensureUtif","mod","n","load","myToken","lib","buf","fetchViewerArrayBuffer","_a","paint","err","idx","ifd","rgba","w","h","canvas","ctx","imageData","next","prev","onMounted","onBeforeUnmount","watch","pageLabel","computed","tt","key","fallback","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_cache","_hoisted_4","_vShow","_hoisted_5","_hoisted_6","_hoisted_7","_toDisplayString","_hoisted_8"],"mappings":"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"}
|