@brftech/filex-core 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 +108 -0
- package/dist/ArchiveViewer-CJdaw5x3.js +99 -0
- package/dist/ArchiveViewer-CJdaw5x3.js.map +1 -0
- package/dist/CsvViewer-QYx_tePQ.js +132 -0
- package/dist/CsvViewer-QYx_tePQ.js.map +1 -0
- package/dist/DrawioViewer-GWt0TyB7.js +141 -0
- package/dist/DrawioViewer-GWt0TyB7.js.map +1 -0
- package/dist/EpubViewer-Je0ywklQ.js +146 -0
- package/dist/EpubViewer-Je0ywklQ.js.map +1 -0
- package/dist/IpynbViewer-TsB4gqP-.js +175 -0
- package/dist/IpynbViewer-TsB4gqP-.js.map +1 -0
- package/dist/MermaidViewer-CXfeDS-7.js +128 -0
- package/dist/MermaidViewer-CXfeDS-7.js.map +1 -0
- package/dist/PsdViewer-VtPpxKVe.js +113 -0
- package/dist/PsdViewer-VtPpxKVe.js.map +1 -0
- package/dist/TiffViewer-OINn9bbb.js +133 -0
- package/dist/TiffViewer-OINn9bbb.js.map +1 -0
- package/dist/UTIF-Cjsrlm0l.js +3104 -0
- package/dist/UTIF-Cjsrlm0l.js.map +1 -0
- package/dist/Viewer3D-xvvyiWHd.js +61 -0
- package/dist/Viewer3D-xvvyiWHd.js.map +1 -0
- package/dist/_commonjsHelpers-DaMA6jEr.js +9 -0
- package/dist/_commonjsHelpers-DaMA6jEr.js.map +1 -0
- package/dist/filex-core.js +26 -0
- package/dist/filex-core.js.map +1 -0
- package/dist/filex-core.umd.cjs +285 -0
- package/dist/filex-core.umd.cjs.map +1 -0
- package/dist/index-CmSYzt6L.js +5404 -0
- package/dist/index-CmSYzt6L.js.map +1 -0
- package/dist/index-UFULWo35.js +10736 -0
- package/dist/index-UFULWo35.js.map +1 -0
- package/dist/index.d.ts +1089 -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 +113 -0
- package/src/FileExplorer.vue +1872 -0
- package/src/components/Breadcrumb.vue +282 -0
- package/src/components/ContextMenu.vue +152 -0
- package/src/components/GridView.vue +166 -0
- package/src/components/ListView.vue +212 -0
- package/src/components/PendingOpsTray.vue +91 -0
- package/src/components/RecentlyOpened.vue +155 -0
- package/src/components/StarButton.vue +101 -0
- package/src/components/TagPicker.vue +184 -0
- package/src/components/Toolbar.vue +220 -0
- package/src/components/UploadProgress.vue +78 -0
- package/src/composables/useFileApi.ts +692 -0
- package/src/composables/useKeyboardShortcuts.ts +144 -0
- package/src/composables/useLocale.ts +60 -0
- package/src/composables/useMonacoLoader.ts +98 -0
- package/src/composables/usePendingOps.ts +200 -0
- package/src/composables/useSelection.ts +81 -0
- package/src/composables/useUploadChunked.ts +250 -0
- package/src/composables/useViewerFetch.ts +58 -0
- package/src/index.ts +80 -0
- package/src/locales/en.ts +122 -0
- package/src/locales/index.ts +12 -0
- package/src/locales/tr.ts +122 -0
- package/src/modals/ConvertModal.vue +254 -0
- package/src/modals/DeleteConfirmModal.vue +32 -0
- package/src/modals/Modal.vue +104 -0
- package/src/modals/NewFolderModal.vue +64 -0
- package/src/modals/PermissionsModal.vue +815 -0
- package/src/modals/PreviewModal.vue +1070 -0
- package/src/modals/RenameModal.vue +58 -0
- package/src/modals/ShareModal.vue +135 -0
- package/src/styles/base.css +1224 -0
- package/src/styles/variables.css +90 -0
- package/src/types/ExplorerConfig.ts +282 -0
- package/src/types/FileNode.ts +136 -0
- package/src/types/index.ts +27 -0
- package/src/types/peers.d.ts +45 -0
- package/src/viewers/ArchiveViewer.vue +186 -0
- package/src/viewers/CsvViewer.vue +319 -0
- package/src/viewers/DrawioViewer.vue +243 -0
- package/src/viewers/EpubViewer.vue +307 -0
- package/src/viewers/IpynbViewer.vue +365 -0
- package/src/viewers/MermaidViewer.vue +259 -0
- package/src/viewers/PdfViewer.vue +562 -0
- package/src/viewers/PsdViewer.vue +264 -0
- package/src/viewers/TiffViewer.vue +273 -0
- package/src/viewers/Viewer3D.vue +120 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { defineComponent as U, ref as n, onMounted as L, onBeforeUnmount as V, watch as F, openBlock as u, createElementBlock as i, createElementVNode as c, toDisplayString as b, Fragment as H, createCommentVNode as g } from "vue";
|
|
2
|
+
import { _ as R } from "./index-CmSYzt6L.js";
|
|
3
|
+
const S = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "filex-viewer-fallback"
|
|
6
|
+
}, z = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "filex-viewer-epub__nav"
|
|
9
|
+
}, A = ["disabled"], D = ["disabled"], N = {
|
|
10
|
+
key: 1,
|
|
11
|
+
class: "filex-viewer-epub__loading"
|
|
12
|
+
}, T = /* @__PURE__ */ U({
|
|
13
|
+
__name: "EpubViewer",
|
|
14
|
+
props: {
|
|
15
|
+
url: {},
|
|
16
|
+
mime: {},
|
|
17
|
+
ext: {},
|
|
18
|
+
t: { type: Function },
|
|
19
|
+
authHeaders: { type: Function },
|
|
20
|
+
authCredentials: {}
|
|
21
|
+
},
|
|
22
|
+
setup(k) {
|
|
23
|
+
const r = k, x = n(null), v = n(null), o = n(null), E = n([]);
|
|
24
|
+
n(!1);
|
|
25
|
+
const B = n(100), s = n(!1), f = n(!0);
|
|
26
|
+
let a = null, e = null;
|
|
27
|
+
async function p() {
|
|
28
|
+
f.value = !0, s.value = !1, o.value = null;
|
|
29
|
+
let t = null;
|
|
30
|
+
try {
|
|
31
|
+
t = await import(
|
|
32
|
+
/* @vite-ignore */
|
|
33
|
+
"epubjs"
|
|
34
|
+
);
|
|
35
|
+
} catch {
|
|
36
|
+
o.value = r.t ? r.t("viewer.peer_not_installed") : "EPUB viewer requires `epubjs` — install or use download.", f.value = !1;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const l = t.default ?? t;
|
|
41
|
+
let m = r.url;
|
|
42
|
+
if (r.authHeaders) {
|
|
43
|
+
const P = r.authHeaders(), d = await fetch(r.url, {
|
|
44
|
+
headers: P,
|
|
45
|
+
credentials: r.authCredentials || "same-origin"
|
|
46
|
+
});
|
|
47
|
+
if (!d.ok) throw new Error(`${d.status} ${d.statusText}`);
|
|
48
|
+
m = await d.arrayBuffer();
|
|
49
|
+
}
|
|
50
|
+
if (a = l(m), !v.value)
|
|
51
|
+
throw new Error("EPUB mount target missing");
|
|
52
|
+
e = a.renderTo(v.value, {
|
|
53
|
+
width: "100%",
|
|
54
|
+
height: "100%",
|
|
55
|
+
flow: "paginated",
|
|
56
|
+
manager: "default"
|
|
57
|
+
}), await e.display(), e.themes.fontSize(B.value + "%");
|
|
58
|
+
const w = await a.loaded.navigation;
|
|
59
|
+
E.value = (w == null ? void 0 : w.toc) ?? [], s.value = !0;
|
|
60
|
+
} catch (l) {
|
|
61
|
+
o.value = l instanceof Error ? l.message : "EPUB load failed";
|
|
62
|
+
} finally {
|
|
63
|
+
f.value = !1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function y() {
|
|
67
|
+
var t;
|
|
68
|
+
(t = e == null ? void 0 : e.next) == null || t.call(e);
|
|
69
|
+
}
|
|
70
|
+
function _() {
|
|
71
|
+
var t;
|
|
72
|
+
(t = e == null ? void 0 : e.prev) == null || t.call(e);
|
|
73
|
+
}
|
|
74
|
+
function h(t) {
|
|
75
|
+
t.key === "ArrowRight" || t.key === "PageDown" ? y() : (t.key === "ArrowLeft" || t.key === "PageUp") && _();
|
|
76
|
+
}
|
|
77
|
+
L(() => {
|
|
78
|
+
p(), window.addEventListener("keydown", h);
|
|
79
|
+
}), V(() => {
|
|
80
|
+
var t, l;
|
|
81
|
+
window.removeEventListener("keydown", h);
|
|
82
|
+
try {
|
|
83
|
+
(t = e == null ? void 0 : e.destroy) == null || t.call(e);
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
(l = a == null ? void 0 : a.destroy) == null || l.call(a);
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
e = null, a = null;
|
|
91
|
+
}), F(
|
|
92
|
+
() => r.url,
|
|
93
|
+
() => {
|
|
94
|
+
if (e)
|
|
95
|
+
try {
|
|
96
|
+
e.destroy();
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
if (a)
|
|
100
|
+
try {
|
|
101
|
+
a.destroy();
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
a = null, e = null, p();
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
function C(t, l) {
|
|
108
|
+
return r.t ? r.t(t) : l;
|
|
109
|
+
}
|
|
110
|
+
return (t, l) => (u(), i("div", {
|
|
111
|
+
ref_key: "root",
|
|
112
|
+
ref: x,
|
|
113
|
+
class: "filex-viewer-epub"
|
|
114
|
+
}, [
|
|
115
|
+
o.value ? (u(), i("div", S, [
|
|
116
|
+
l[0] || (l[0] = c("span", { class: "filex-viewer-fallback__icon" }, "📖", -1)),
|
|
117
|
+
c("p", null, b(o.value), 1)
|
|
118
|
+
])) : (u(), i(H, { key: 1 }, [
|
|
119
|
+
c("div", {
|
|
120
|
+
ref_key: "containerRef",
|
|
121
|
+
ref: v,
|
|
122
|
+
class: "filex-viewer-epub__rendition"
|
|
123
|
+
}, null, 512),
|
|
124
|
+
s.value ? (u(), i("div", z, [
|
|
125
|
+
c("button", {
|
|
126
|
+
type: "button",
|
|
127
|
+
class: "filex-viewer-btn",
|
|
128
|
+
onClick: _,
|
|
129
|
+
disabled: !s.value
|
|
130
|
+
}, "‹", 8, A),
|
|
131
|
+
c("button", {
|
|
132
|
+
type: "button",
|
|
133
|
+
class: "filex-viewer-btn",
|
|
134
|
+
onClick: y,
|
|
135
|
+
disabled: !s.value
|
|
136
|
+
}, "›", 8, D)
|
|
137
|
+
])) : g("", !0),
|
|
138
|
+
f.value ? (u(), i("div", N, b(C("viewer.loading", "Loading…")), 1)) : g("", !0)
|
|
139
|
+
], 64))
|
|
140
|
+
], 512));
|
|
141
|
+
}
|
|
142
|
+
}), q = /* @__PURE__ */ R(T, [["__scopeId", "data-v-f9b72a2c"]]);
|
|
143
|
+
export {
|
|
144
|
+
q as default
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=EpubViewer-Je0ywklQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EpubViewer-Je0ywklQ.js","sources":["../src/viewers/EpubViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * EpubViewer — flowable EPUB reader via `epubjs`.\r\n *\r\n * Lazy-imports `epubjs` (~80 KB gzipped). epub.js renders the publication\r\n * inside an iframe (default `flow: 'paginated'`), but we use it in\r\n * scrolled-doc mode only when the user toggles the \"fit-width\" flag — by\r\n * default we keep paginated since that matches reader-app expectations.\r\n *\r\n * UX:\r\n * - prev/next page buttons (also keyboard arrow keys via composable)\r\n * - collapsible TOC sidebar (built from `book.loaded.navigation`)\r\n * - font size +/- (Themes API)\r\n * - graceful fallback if peer not installed\r\n */\r\nimport { onBeforeUnmount, onMounted, ref, watch } from 'vue';\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 TocNode {\r\n href: string;\r\n label: string;\r\n subitems?: TocNode[];\r\n}\r\n\r\nconst root = ref<HTMLDivElement | null>(null);\r\nconst containerRef = ref<HTMLDivElement | null>(null);\r\nconst error = ref<string | null>(null);\r\nconst toc = ref<TocNode[]>([]);\r\nconst tocOpen = ref(false);\r\nconst fontSize = ref(100);\r\nconst ready = ref(false);\r\nconst loading = ref(true);\r\n\r\nlet book: any = null;\r\nlet rendition: any = null;\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n ready.value = false;\r\n error.value = null;\r\n let mod: any = null;\r\n try {\r\n mod = await import(/* @vite-ignore */ 'epubjs');\r\n } catch {\r\n error.value = props.t\r\n ? props.t('viewer.peer_not_installed')\r\n : 'EPUB viewer requires `epubjs` — install or use download.';\r\n loading.value = false;\r\n return;\r\n }\r\n try {\r\n const Epub = mod.default ?? mod;\r\n // epub.js wants a URL (it then fetches with XHR). When the host\r\n // site requires auth headers we have to load the file ourselves\r\n // and pass an ArrayBuffer instead.\r\n let source: string | ArrayBuffer = props.url;\r\n if (props.authHeaders) {\r\n const headers = props.authHeaders();\r\n const res = await fetch(props.url, {\r\n headers,\r\n credentials: props.authCredentials || 'same-origin',\r\n });\r\n if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);\r\n source = await res.arrayBuffer();\r\n }\r\n book = Epub(source);\r\n if (!containerRef.value) {\r\n throw new Error('EPUB mount target missing');\r\n }\r\n rendition = book.renderTo(containerRef.value, {\r\n width: '100%',\r\n height: '100%',\r\n flow: 'paginated',\r\n manager: 'default',\r\n });\r\n await rendition.display();\r\n rendition.themes.fontSize(fontSize.value + '%');\r\n const nav = await book.loaded.navigation;\r\n toc.value = (nav?.toc ?? []) as TocNode[];\r\n ready.value = true;\r\n } catch (err) {\r\n error.value =\r\n err instanceof Error ? err.message : 'EPUB load failed';\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\nfunction next(): void {\r\n rendition?.next?.();\r\n}\r\nfunction prev(): void {\r\n rendition?.prev?.();\r\n}\r\nfunction gotoHref(href: string): void {\r\n rendition?.display?.(href);\r\n tocOpen.value = false;\r\n}\r\nfunction bigger(): void {\r\n fontSize.value = Math.min(200, fontSize.value + 10);\r\n rendition?.themes?.fontSize(fontSize.value + '%');\r\n}\r\nfunction smaller(): void {\r\n fontSize.value = Math.max(60, fontSize.value - 10);\r\n rendition?.themes?.fontSize(fontSize.value + '%');\r\n}\r\n\r\nfunction onKey(ev: KeyboardEvent): void {\r\n if (ev.key === 'ArrowRight' || ev.key === 'PageDown') next();\r\n else if (ev.key === 'ArrowLeft' || ev.key === 'PageUp') prev();\r\n}\r\n\r\nonMounted(() => {\r\n load();\r\n window.addEventListener('keydown', onKey);\r\n});\r\n\r\nonBeforeUnmount(() => {\r\n window.removeEventListener('keydown', onKey);\r\n try {\r\n rendition?.destroy?.();\r\n } catch {\r\n /* ignore */\r\n }\r\n try {\r\n book?.destroy?.();\r\n } catch {\r\n /* ignore */\r\n }\r\n rendition = null;\r\n book = null;\r\n});\r\n\r\nwatch(\r\n () => props.url,\r\n () => {\r\n if (rendition) {\r\n try {\r\n rendition.destroy();\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n if (book) {\r\n try {\r\n book.destroy();\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n book = null;\r\n rendition = null;\r\n load();\r\n },\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 ref=\"root\" class=\"filex-viewer-epub\">\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 <template v-else>\r\n <div ref=\"containerRef\" class=\"filex-viewer-epub__rendition\" />\r\n <div v-if=\"ready\" class=\"filex-viewer-epub__nav\">\r\n <button type=\"button\" class=\"filex-viewer-btn\" @click=\"prev\" :disabled=\"!ready\">‹</button>\r\n <button type=\"button\" class=\"filex-viewer-btn\" @click=\"next\" :disabled=\"!ready\">›</button>\r\n </div>\r\n <div v-if=\"loading\" class=\"filex-viewer-epub__loading\">\r\n {{ tt('viewer.loading', 'Loading…') }}\r\n </div>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-epub__nav {\r\n position: absolute;\r\n bottom: 12px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n display: flex;\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-epub {\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 color: var(--fe-text, #1a1e27);\r\n position: relative;\r\n}\r\n.filex-viewer-epub__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-epub__fs {\r\n display: inline-block;\r\n min-width: 40px;\r\n text-align: center;\r\n font-variant-numeric: tabular-nums;\r\n font-size: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-epub__main {\r\n flex: 1;\r\n min-height: 0;\r\n display: flex;\r\n}\r\n.filex-viewer-epub__rendition {\r\n flex: 1;\r\n min-height: 0;\r\n}\r\n.filex-viewer-epub__toc {\r\n width: 260px;\r\n border-right: 1px solid var(--fe-border, #e2e6ed);\r\n overflow-y: auto;\r\n padding: 12px 0;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n}\r\n.filex-viewer-epub__toc ul {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n.filex-viewer-epub__toc-link {\r\n display: block;\r\n width: 100%;\r\n text-align: left;\r\n background: transparent;\r\n border: 0;\r\n padding: 6px 14px;\r\n font: inherit;\r\n color: inherit;\r\n cursor: pointer;\r\n}\r\n.filex-viewer-epub__toc-link:hover {\r\n background: var(--fe-bg-hover, #edf0f5);\r\n}\r\n.filex-viewer-epub__toc-link.is-child {\r\n padding-left: 28px;\r\n color: var(--fe-text-muted, #5a6475);\r\n font-size: 12px;\r\n}\r\n.filex-viewer-epub__loading {\r\n position: absolute;\r\n inset: auto 0 0 0;\r\n text-align: center;\r\n padding: 6px;\r\n background: rgba(0, 0, 0, 0.05);\r\n font-size: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: var(--fe-text-muted, #5a6475);\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.5;\r\n cursor: not-allowed;\r\n}\r\n</style>\r\n"],"names":["props","__props","root","ref","containerRef","error","toc","fontSize","ready","loading","book","rendition","load","mod","Epub","source","headers","res","nav","err","next","_a","prev","onKey","ev","onMounted","onBeforeUnmount","_b","watch","tt","key","fallback","_createElementBlock","_openBlock","_hoisted_1","_cache","_createElementVNode","_Fragment","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_toDisplayString"],"mappings":"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"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { defineComponent as J, ref as _, onMounted as R, onBeforeUnmount as U, watch as D, computed as q, openBlock as a, createElementBlock as r, createElementVNode as d, toDisplayString as p, Fragment as h, renderList as E, createCommentVNode as V } from "vue";
|
|
2
|
+
import { f as z } from "./useViewerFetch-czqbd2Lj.js";
|
|
3
|
+
import { e as G, _ as K } from "./index-CmSYzt6L.js";
|
|
4
|
+
const P = { class: "filex-viewer-ipynb" }, Q = { class: "filex-viewer-ipynb__pane" }, W = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "filex-viewer-fallback"
|
|
7
|
+
}, X = {
|
|
8
|
+
key: 1,
|
|
9
|
+
class: "filex-viewer-fallback"
|
|
10
|
+
}, Y = { key: 2 }, Z = ["data-type"], ee = { class: "filex-viewer-ipynb__exec" }, te = { class: "filex-viewer-ipynb__src hljs" }, ne = ["innerHTML"], ae = { key: 1 }, re = {
|
|
11
|
+
key: 0,
|
|
12
|
+
class: "filex-viewer-ipynb__outputs"
|
|
13
|
+
}, le = ["src", "alt"], ie = ["innerHTML"], se = ["data-type"], ue = ["innerHTML"], oe = {
|
|
14
|
+
key: 1,
|
|
15
|
+
class: "filex-viewer-ipynb__md-raw"
|
|
16
|
+
}, ce = {
|
|
17
|
+
key: 2,
|
|
18
|
+
class: "filex-viewer-ipynb__src"
|
|
19
|
+
}, de = /* @__PURE__ */ J({
|
|
20
|
+
__name: "IpynbViewer",
|
|
21
|
+
props: {
|
|
22
|
+
url: {},
|
|
23
|
+
ext: {},
|
|
24
|
+
t: { type: Function },
|
|
25
|
+
authHeaders: { type: Function },
|
|
26
|
+
authCredentials: {}
|
|
27
|
+
},
|
|
28
|
+
setup(B) {
|
|
29
|
+
const u = B, o = _([]), M = _("python"), f = _(null), y = _(!0), w = _(/* @__PURE__ */ new Map()), k = _(/* @__PURE__ */ new Map());
|
|
30
|
+
let v = 0, x = null, g = null;
|
|
31
|
+
async function N() {
|
|
32
|
+
if (g !== null) return g || null;
|
|
33
|
+
try {
|
|
34
|
+
const e = await import(
|
|
35
|
+
/* @vite-ignore */
|
|
36
|
+
"markdown-it"
|
|
37
|
+
), t = e.default ?? e;
|
|
38
|
+
return g = new t({ html: !1, linkify: !0, breaks: !0 }), g;
|
|
39
|
+
} catch {
|
|
40
|
+
return g = !1, null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function s(e) {
|
|
44
|
+
return Array.isArray(e) ? e.join("") : e ?? "";
|
|
45
|
+
}
|
|
46
|
+
async function H() {
|
|
47
|
+
var i, m, C, S;
|
|
48
|
+
y.value = !0, f.value = null, o.value = [], w.value = /* @__PURE__ */ new Map(), k.value = /* @__PURE__ */ new Map();
|
|
49
|
+
const e = ++v;
|
|
50
|
+
let t;
|
|
51
|
+
try {
|
|
52
|
+
t = await z({
|
|
53
|
+
url: u.url,
|
|
54
|
+
headers: ((i = u.authHeaders) == null ? void 0 : i.call(u)) ?? {},
|
|
55
|
+
credentials: u.authCredentials
|
|
56
|
+
});
|
|
57
|
+
} catch (l) {
|
|
58
|
+
f.value = l instanceof Error ? l.message : "fetch failed", y.value = !1;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (e !== v) return;
|
|
62
|
+
let n;
|
|
63
|
+
try {
|
|
64
|
+
n = JSON.parse(t);
|
|
65
|
+
} catch {
|
|
66
|
+
f.value = "Invalid notebook JSON", y.value = !1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (o.value = Array.isArray(n.cells) ? n.cells : [], M.value = ((C = (m = n.metadata) == null ? void 0 : m.kernelspec) == null ? void 0 : C.language) || "python", x = await G(), e !== v) return;
|
|
70
|
+
if (x) {
|
|
71
|
+
const l = x.default ?? x, b = (S = l.getLanguage) != null && S.call(l, M.value) ? M.value : null;
|
|
72
|
+
o.value.forEach((j, F) => {
|
|
73
|
+
if (j.cell_type === "code") {
|
|
74
|
+
const A = s(j.source);
|
|
75
|
+
try {
|
|
76
|
+
const O = b ? l.highlight(A, { language: b, ignoreIllegals: !0 }) : l.highlightAuto(A);
|
|
77
|
+
w.value.set(F, O.value);
|
|
78
|
+
} catch {
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const c = await N();
|
|
84
|
+
e === v && (c && o.value.forEach((l, b) => {
|
|
85
|
+
if (l.cell_type === "markdown")
|
|
86
|
+
try {
|
|
87
|
+
k.value.set(b, c.render(s(l.source)));
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
}), y.value = !1);
|
|
91
|
+
}
|
|
92
|
+
function T(e) {
|
|
93
|
+
var t;
|
|
94
|
+
return e ? e.output_type === "stream" ? s(e.text) : e.output_type === "error" ? [e.ename, e.evalue, ...e.traceback || []].filter(Boolean).join(`
|
|
95
|
+
`) : (e.output_type === "execute_result" || e.output_type === "display_data") && (t = e.data) != null && t["text/plain"] ? s(e.data["text/plain"]) : null : null;
|
|
96
|
+
}
|
|
97
|
+
function L(e) {
|
|
98
|
+
if (!(e != null && e.data)) return null;
|
|
99
|
+
if (e.data["image/png"]) return `data:image/png;base64,${e.data["image/png"]}`;
|
|
100
|
+
if (e.data["image/jpeg"]) return `data:image/jpeg;base64,${e.data["image/jpeg"]}`;
|
|
101
|
+
if (e.data["image/svg+xml"]) {
|
|
102
|
+
const t = s(e.data["image/svg+xml"]);
|
|
103
|
+
return `data:image/svg+xml;utf8,${encodeURIComponent(t)}`;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function I(e) {
|
|
108
|
+
return e != null && e.data && e.data["text/html"] ? s(e.data["text/html"]).replace(/<script[\s\S]*?<\/script>/gi, "") : null;
|
|
109
|
+
}
|
|
110
|
+
R(H), U(() => {
|
|
111
|
+
v++;
|
|
112
|
+
}), D(() => u.url, H), q(() => {
|
|
113
|
+
const e = o.value.filter((n) => n.cell_type === "code").length, t = o.value.filter((n) => n.cell_type === "markdown").length;
|
|
114
|
+
return { code: e, md: t, total: o.value.length };
|
|
115
|
+
});
|
|
116
|
+
function $(e, t) {
|
|
117
|
+
return u.t ? u.t(e) : t;
|
|
118
|
+
}
|
|
119
|
+
return (e, t) => (a(), r("div", P, [
|
|
120
|
+
d("div", Q, [
|
|
121
|
+
f.value ? (a(), r("div", W, [
|
|
122
|
+
t[0] || (t[0] = d("span", { class: "filex-viewer-fallback__icon" }, "📓", -1)),
|
|
123
|
+
d("p", null, p(f.value), 1)
|
|
124
|
+
])) : y.value ? (a(), r("div", X, [
|
|
125
|
+
t[1] || (t[1] = d("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
|
|
126
|
+
d("p", null, p($("viewer.loading", "Loading…")), 1)
|
|
127
|
+
])) : (a(), r("div", Y, [
|
|
128
|
+
(a(!0), r(h, null, E(o.value, (n, c) => (a(), r("div", {
|
|
129
|
+
key: c,
|
|
130
|
+
class: "filex-viewer-ipynb__cell",
|
|
131
|
+
"data-type": n.cell_type
|
|
132
|
+
}, [
|
|
133
|
+
n.cell_type === "code" ? (a(), r(h, { key: 0 }, [
|
|
134
|
+
d("div", ee, " In [" + p(n.execution_count ?? " ") + "]: ", 1),
|
|
135
|
+
d("pre", te, [
|
|
136
|
+
w.value.get(c) ? (a(), r("code", {
|
|
137
|
+
key: 0,
|
|
138
|
+
innerHTML: w.value.get(c)
|
|
139
|
+
}, null, 8, ne)) : (a(), r("code", ae, p(s(n.source)), 1))
|
|
140
|
+
]),
|
|
141
|
+
n.outputs && n.outputs.length ? (a(), r("div", re, [
|
|
142
|
+
(a(!0), r(h, null, E(n.outputs, (i, m) => (a(), r(h, { key: m }, [
|
|
143
|
+
L(i) ? (a(), r("img", {
|
|
144
|
+
key: 0,
|
|
145
|
+
src: L(i) || "",
|
|
146
|
+
class: "filex-viewer-ipynb__img",
|
|
147
|
+
alt: `output ${m}`
|
|
148
|
+
}, null, 8, le)) : I(i) ? (a(), r("div", {
|
|
149
|
+
key: 1,
|
|
150
|
+
class: "filex-viewer-ipynb__html",
|
|
151
|
+
innerHTML: I(i)
|
|
152
|
+
}, null, 8, ie)) : T(i) ? (a(), r("pre", {
|
|
153
|
+
key: 2,
|
|
154
|
+
class: "filex-viewer-ipynb__out",
|
|
155
|
+
"data-type": i.output_type
|
|
156
|
+
}, p(T(i)), 9, se)) : V("", !0)
|
|
157
|
+
], 64))), 128))
|
|
158
|
+
])) : V("", !0)
|
|
159
|
+
], 64)) : n.cell_type === "markdown" ? (a(), r(h, { key: 1 }, [
|
|
160
|
+
k.value.get(c) ? (a(), r("div", {
|
|
161
|
+
key: 0,
|
|
162
|
+
class: "filex-viewer-ipynb__md",
|
|
163
|
+
innerHTML: k.value.get(c)
|
|
164
|
+
}, null, 8, ue)) : (a(), r("pre", oe, p(s(n.source)), 1))
|
|
165
|
+
], 64)) : (a(), r("pre", ce, p(s(n.source)), 1))
|
|
166
|
+
], 8, Z))), 128))
|
|
167
|
+
]))
|
|
168
|
+
])
|
|
169
|
+
]));
|
|
170
|
+
}
|
|
171
|
+
}), ye = /* @__PURE__ */ K(de, [["__scopeId", "data-v-631b8223"]]);
|
|
172
|
+
export {
|
|
173
|
+
ye as default
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=IpynbViewer-TsB4gqP-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IpynbViewer-TsB4gqP-.js","sources":["../src/viewers/IpynbViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * IpynbViewer — Jupyter notebook (.ipynb JSON) renderer.\r\n *\r\n * Pure-JS render — no peer dependency required:\r\n * - code cells → `<pre><code>` (highlight.js when available)\r\n * - markdown cells → markdown-it when available, plain `<pre>` otherwise\r\n * - output cells → text (stream / display_data 'text/plain'),\r\n * images (display_data 'image/png' base64),\r\n * HTML (display_data 'text/html', sanitized via\r\n * element-only insertion — no script tags)\r\n *\r\n * Source list / output count counters at the top so a 200-cell\r\n * notebook doesn't surprise the user.\r\n */\r\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';\r\nimport { fetchViewerText } from '../composables/useViewerFetch';\r\nimport { ensureHighlight } from '../composables/useMonacoLoader';\r\n\r\nconst props = defineProps<{\r\n url: 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 Cell {\r\n cell_type: 'code' | 'markdown' | 'raw' | string;\r\n source: string | string[];\r\n outputs?: any[];\r\n execution_count?: number | null;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\ninterface Notebook {\r\n cells: Cell[];\r\n metadata?: { kernelspec?: { language?: string; name?: string } };\r\n}\r\n\r\nconst cells = ref<Cell[]>([]);\r\nconst language = ref<string>('python');\r\nconst error = ref<string | null>(null);\r\nconst loading = ref(true);\r\nconst renderedSources = ref<Map<number, string>>(new Map());\r\nconst renderedMarkdown = ref<Map<number, string>>(new Map());\r\n\r\nlet renderToken = 0;\r\nlet highlight: any = null;\r\nlet mdRenderer: any = null;\r\n\r\nasync function ensureMd(): Promise<any | null> {\r\n if (mdRenderer !== null) return mdRenderer || null;\r\n try {\r\n const mod = await import(/* @vite-ignore */ 'markdown-it');\r\n const Md = (mod as any).default ?? mod;\r\n mdRenderer = new Md({ html: false, linkify: true, breaks: true });\r\n return mdRenderer;\r\n } catch {\r\n mdRenderer = false;\r\n return null;\r\n }\r\n}\r\n\r\nfunction joinSource(source: string | string[]): string {\r\n return Array.isArray(source) ? source.join('') : (source ?? '');\r\n}\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n error.value = null;\r\n cells.value = [];\r\n renderedSources.value = new Map();\r\n renderedMarkdown.value = new Map();\r\n const myToken = ++renderToken;\r\n\r\n let raw: string;\r\n try {\r\n raw = await fetchViewerText({\r\n url: props.url,\r\n headers: props.authHeaders?.() ?? {},\r\n credentials: props.authCredentials,\r\n });\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'fetch failed';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n if (myToken !== renderToken) return;\r\n\r\n let nb: Notebook;\r\n try {\r\n nb = JSON.parse(raw);\r\n } catch (err) {\r\n error.value = 'Invalid notebook JSON';\r\n loading.value = false;\r\n return;\r\n }\r\n cells.value = Array.isArray(nb.cells) ? nb.cells : [];\r\n language.value = nb.metadata?.kernelspec?.language || 'python';\r\n\r\n // Best-effort hljs highlight per code cell.\r\n highlight = (await ensureHighlight()) as any;\r\n if (myToken !== renderToken) return;\r\n if (highlight) {\r\n const hljs = highlight.default ?? highlight;\r\n const langOk = hljs.getLanguage?.(language.value) ? language.value : null;\r\n cells.value.forEach((cell, idx) => {\r\n if (cell.cell_type === 'code') {\r\n const text = joinSource(cell.source);\r\n try {\r\n const result = langOk\r\n ? hljs.highlight(text, { language: langOk, ignoreIllegals: true })\r\n : hljs.highlightAuto(text);\r\n renderedSources.value.set(idx, result.value);\r\n } catch {\r\n /* leave unrendered */\r\n }\r\n }\r\n });\r\n }\r\n\r\n const md = await ensureMd();\r\n if (myToken !== renderToken) return;\r\n if (md) {\r\n cells.value.forEach((cell, idx) => {\r\n if (cell.cell_type === 'markdown') {\r\n try {\r\n renderedMarkdown.value.set(idx, md.render(joinSource(cell.source)));\r\n } catch {\r\n /* leave plain */\r\n }\r\n }\r\n });\r\n }\r\n\r\n loading.value = false;\r\n}\r\n\r\nfunction outputText(out: any): string | null {\r\n if (!out) return null;\r\n if (out.output_type === 'stream') {\r\n return joinSource(out.text);\r\n }\r\n if (out.output_type === 'error') {\r\n return [out.ename, out.evalue, ...(out.traceback || [])]\r\n .filter(Boolean)\r\n .join('\\n');\r\n }\r\n if (out.output_type === 'execute_result' || out.output_type === 'display_data') {\r\n if (out.data?.['text/plain']) {\r\n return joinSource(out.data['text/plain']);\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nfunction outputImage(out: any): string | null {\r\n if (!out?.data) return null;\r\n if (out.data['image/png']) return `data:image/png;base64,${out.data['image/png']}`;\r\n if (out.data['image/jpeg']) return `data:image/jpeg;base64,${out.data['image/jpeg']}`;\r\n if (out.data['image/svg+xml']) {\r\n const svg = joinSource(out.data['image/svg+xml']);\r\n return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;\r\n }\r\n return null;\r\n}\r\n\r\nfunction outputHtml(out: any): string | null {\r\n if (!out?.data) return null;\r\n if (out.data['text/html']) {\r\n const html = joinSource(out.data['text/html']);\r\n // Strip <script> for safety — outputs from arbitrary notebooks.\r\n return html.replace(/<script[\\s\\S]*?<\\/script>/gi, '');\r\n }\r\n return null;\r\n}\r\n\r\nonMounted(load);\r\nonBeforeUnmount(() => {\r\n renderToken++;\r\n});\r\nwatch(() => props.url, load);\r\n\r\nconst stats = computed(() => {\r\n const codeCount = cells.value.filter((c) => c.cell_type === 'code').length;\r\n const mdCount = cells.value.filter((c) => c.cell_type === 'markdown').length;\r\n return { code: codeCount, md: mdCount, total: cells.value.length };\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-ipynb\">\r\n <div class=\"filex-viewer-ipynb__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 <div v-else>\r\n <div\r\n v-for=\"(cell, idx) in cells\"\r\n :key=\"idx\"\r\n class=\"filex-viewer-ipynb__cell\"\r\n :data-type=\"cell.cell_type\"\r\n >\r\n <template v-if=\"cell.cell_type === 'code'\">\r\n <div class=\"filex-viewer-ipynb__exec\">\r\n In [{{ cell.execution_count ?? ' ' }}]:\r\n </div>\r\n <pre class=\"filex-viewer-ipynb__src hljs\"><code\r\n v-if=\"renderedSources.get(idx)\"\r\n v-html=\"renderedSources.get(idx)\"\r\n /><code v-else>{{ joinSource(cell.source) }}</code></pre>\r\n <div v-if=\"cell.outputs && cell.outputs.length\" class=\"filex-viewer-ipynb__outputs\">\r\n <template v-for=\"(out, j) in cell.outputs\" :key=\"j\">\r\n <img\r\n v-if=\"outputImage(out)\"\r\n :src=\"outputImage(out) || ''\"\r\n class=\"filex-viewer-ipynb__img\"\r\n :alt=\"`output ${j}`\"\r\n />\r\n <div\r\n v-else-if=\"outputHtml(out)\"\r\n class=\"filex-viewer-ipynb__html\"\r\n v-html=\"outputHtml(out)\"\r\n />\r\n <pre\r\n v-else-if=\"outputText(out)\"\r\n class=\"filex-viewer-ipynb__out\"\r\n :data-type=\"out.output_type\"\r\n >{{ outputText(out) }}</pre>\r\n </template>\r\n </div>\r\n </template>\r\n\r\n <template v-else-if=\"cell.cell_type === 'markdown'\">\r\n <div\r\n v-if=\"renderedMarkdown.get(idx)\"\r\n class=\"filex-viewer-ipynb__md\"\r\n v-html=\"renderedMarkdown.get(idx)\"\r\n />\r\n <pre v-else class=\"filex-viewer-ipynb__md-raw\">{{ joinSource(cell.source) }}</pre>\r\n </template>\r\n\r\n <template v-else>\r\n <pre class=\"filex-viewer-ipynb__src\">{{ joinSource(cell.source) }}</pre>\r\n </template>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-ipynb {\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 color: var(--fe-text, #1a1e27);\r\n}\r\n.filex-viewer-ipynb__bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\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: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-ipynb__lang {\r\n font-family: var(--fe-font-mono, monospace);\r\n text-transform: uppercase;\r\n letter-spacing: 0.04em;\r\n}\r\n.filex-viewer-ipynb__pane {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 16px 24px;\r\n}\r\n.filex-viewer-ipynb__cell {\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n border-radius: 6px;\r\n margin-bottom: 16px;\r\n overflow: hidden;\r\n}\r\n.filex-viewer-ipynb__cell[data-type=\"code\"] {\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n}\r\n.filex-viewer-ipynb__exec {\r\n padding: 4px 12px;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 11px;\r\n color: var(--fe-text-muted, #5a6475);\r\n background: rgba(0, 0, 0, 0.04);\r\n}\r\n.filex-viewer-ipynb__src {\r\n margin: 0;\r\n padding: 12px;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 12px;\r\n line-height: 1.5;\r\n white-space: pre;\r\n overflow-x: auto;\r\n}\r\n.filex-viewer-ipynb__outputs {\r\n border-top: 1px dashed var(--fe-border, #e2e6ed);\r\n background: var(--fe-bg, #fff);\r\n padding: 8px 12px;\r\n}\r\n.filex-viewer-ipynb__out {\r\n margin: 0;\r\n padding: 4px 0;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 12px;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n}\r\n.filex-viewer-ipynb__out[data-type=\"error\"] {\r\n color: var(--fe-danger, #dc2626);\r\n}\r\n.filex-viewer-ipynb__img {\r\n display: block;\r\n max-width: 100%;\r\n height: auto;\r\n margin: 8px 0;\r\n}\r\n.filex-viewer-ipynb__html {\r\n font-size: 13px;\r\n}\r\n.filex-viewer-ipynb__md {\r\n padding: 12px 16px;\r\n font-size: 14px;\r\n line-height: 1.6;\r\n}\r\n.filex-viewer-ipynb__md-raw {\r\n padding: 12px;\r\n margin: 0;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 12px;\r\n white-space: pre-wrap;\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: var(--fe-text-muted, #5a6475);\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</style>\r\n"],"names":["props","__props","cells","ref","language","error","loading","renderedSources","renderedMarkdown","renderToken","highlight","mdRenderer","ensureMd","mod","Md","joinSource","source","load","myToken","raw","fetchViewerText","_a","err","nb","_c","_b","ensureHighlight","hljs","langOk","_d","cell","idx","text","result","md","outputText","out","outputImage","svg","outputHtml","onMounted","onBeforeUnmount","watch","computed","codeCount","c","mdCount","tt","key","fallback","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_cache","_hoisted_4","_hoisted_5","_Fragment","_renderList","_hoisted_7","_hoisted_8","_hoisted_10","_toDisplayString","_hoisted_11","j","_hoisted_14","_hoisted_16","_hoisted_17"],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { defineComponent as L, ref as u, onMounted as T, onBeforeUnmount as $, openBlock as _, createElementBlock as x, createElementVNode as c, toDisplayString as k, createCommentVNode as B, withDirectives as H, normalizeStyle as Y, vShow as q } from "vue";
|
|
2
|
+
import { f as z } from "./useViewerFetch-czqbd2Lj.js";
|
|
3
|
+
import { _ as F } from "./index-CmSYzt6L.js";
|
|
4
|
+
const I = { class: "filex-viewer-mermaid" }, K = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "filex-viewer-fallback"
|
|
7
|
+
}, N = {
|
|
8
|
+
key: 1,
|
|
9
|
+
class: "filex-viewer-fallback"
|
|
10
|
+
}, U = /* @__PURE__ */ L({
|
|
11
|
+
__name: "MermaidViewer",
|
|
12
|
+
props: {
|
|
13
|
+
url: {},
|
|
14
|
+
mime: {},
|
|
15
|
+
ext: {},
|
|
16
|
+
t: { type: Function },
|
|
17
|
+
authHeaders: { type: Function },
|
|
18
|
+
authCredentials: {}
|
|
19
|
+
},
|
|
20
|
+
setup(M) {
|
|
21
|
+
const a = M, d = u(null), n = u(null), s = u(!0), m = u(1), v = u(0), p = u(0);
|
|
22
|
+
let y = !1, l = null, f = 0, i = null;
|
|
23
|
+
async function P() {
|
|
24
|
+
var e, t;
|
|
25
|
+
if (i) return i;
|
|
26
|
+
try {
|
|
27
|
+
const r = await import(
|
|
28
|
+
/* @vite-ignore */
|
|
29
|
+
"mermaid"
|
|
30
|
+
);
|
|
31
|
+
return i = r.default ?? r, (t = i.initialize) == null || t.call(i, {
|
|
32
|
+
startOnLoad: !1,
|
|
33
|
+
securityLevel: "strict",
|
|
34
|
+
theme: (e = window.matchMedia) != null && e.call(window, "(prefers-color-scheme: dark)").matches ? "dark" : "default"
|
|
35
|
+
}), i;
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function b() {
|
|
41
|
+
var g;
|
|
42
|
+
s.value = !0, n.value = null;
|
|
43
|
+
const e = ++f, t = await P();
|
|
44
|
+
if (e !== f) return;
|
|
45
|
+
if (!t) {
|
|
46
|
+
n.value = a.t ? a.t("viewer.peer_not_installed") : "Mermaid viewer requires `mermaid` — install or use download.", s.value = !1;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let r;
|
|
50
|
+
try {
|
|
51
|
+
r = await z({
|
|
52
|
+
url: a.url,
|
|
53
|
+
headers: ((g = a.authHeaders) == null ? void 0 : g.call(a)) ?? {},
|
|
54
|
+
credentials: a.authCredentials
|
|
55
|
+
});
|
|
56
|
+
} catch (o) {
|
|
57
|
+
n.value = o instanceof Error ? o.message : "fetch failed", s.value = !1;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (e === f)
|
|
61
|
+
try {
|
|
62
|
+
const o = `filex-mermaid-${Date.now()}`, { svg: V } = await t.render(o, r);
|
|
63
|
+
if (e !== f) return;
|
|
64
|
+
if (d.value) {
|
|
65
|
+
d.value.innerHTML = V;
|
|
66
|
+
const w = d.value.querySelector("svg");
|
|
67
|
+
w && (w.style.maxWidth = "100%", w.style.height = "auto");
|
|
68
|
+
}
|
|
69
|
+
} catch (o) {
|
|
70
|
+
n.value = o instanceof Error ? o.message : "render failed";
|
|
71
|
+
} finally {
|
|
72
|
+
s.value = !1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function C(e) {
|
|
76
|
+
if (!e.ctrlKey && !e.metaKey) return;
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
const r = -e.deltaY > 0 ? 1.1 : 1 / 1.1;
|
|
79
|
+
m.value = Math.max(0.2, Math.min(8, m.value * r));
|
|
80
|
+
}
|
|
81
|
+
function D(e) {
|
|
82
|
+
var t, r;
|
|
83
|
+
y = !0, l = { x: e.clientX, y: e.clientY, tx: v.value, ty: p.value }, (r = (t = e.target).setPointerCapture) == null || r.call(t, e.pointerId);
|
|
84
|
+
}
|
|
85
|
+
function E(e) {
|
|
86
|
+
!y || !l || (v.value = l.tx + (e.clientX - l.x), p.value = l.ty + (e.clientY - l.y));
|
|
87
|
+
}
|
|
88
|
+
function h() {
|
|
89
|
+
y = !1, l = null;
|
|
90
|
+
}
|
|
91
|
+
T(b), $(() => {
|
|
92
|
+
f++;
|
|
93
|
+
});
|
|
94
|
+
function S(e, t) {
|
|
95
|
+
return a.t ? a.t(e) : t;
|
|
96
|
+
}
|
|
97
|
+
return (e, t) => (_(), x("div", I, [
|
|
98
|
+
c("div", {
|
|
99
|
+
class: "filex-viewer-mermaid__pane",
|
|
100
|
+
onWheel: C,
|
|
101
|
+
onPointerdown: D,
|
|
102
|
+
onPointermove: E,
|
|
103
|
+
onPointerup: h,
|
|
104
|
+
onPointercancel: h
|
|
105
|
+
}, [
|
|
106
|
+
n.value ? (_(), x("div", K, [
|
|
107
|
+
t[0] || (t[0] = c("span", { class: "filex-viewer-fallback__icon" }, "📊", -1)),
|
|
108
|
+
c("p", null, k(n.value), 1)
|
|
109
|
+
])) : s.value ? (_(), x("div", N, [
|
|
110
|
+
t[1] || (t[1] = c("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
|
|
111
|
+
c("p", null, k(S("viewer.loading", "Loading…")), 1)
|
|
112
|
+
])) : B("", !0),
|
|
113
|
+
H(c("div", {
|
|
114
|
+
ref_key: "surface",
|
|
115
|
+
ref: d,
|
|
116
|
+
class: "filex-viewer-mermaid__surface",
|
|
117
|
+
style: Y({ transform: `translate(${v.value}px, ${p.value}px) scale(${m.value})` })
|
|
118
|
+
}, null, 4), [
|
|
119
|
+
[q, !s.value && !n.value]
|
|
120
|
+
])
|
|
121
|
+
], 32)
|
|
122
|
+
]));
|
|
123
|
+
}
|
|
124
|
+
}), j = /* @__PURE__ */ F(U, [["__scopeId", "data-v-fe0bf99e"]]);
|
|
125
|
+
export {
|
|
126
|
+
j as default
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=MermaidViewer-CXfeDS-7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MermaidViewer-CXfeDS-7.js","sources":["../src/viewers/MermaidViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * MermaidViewer — render a `.mmd` / `.mermaid` source file.\r\n *\r\n * Lazy-imports the `mermaid` library (~150 KB gzipped). Source text is\r\n * fetched from `props.url` (with the auth headers from PreviewModal),\r\n * then rendered to SVG via `mermaid.render('id', src)`. The resulting\r\n * SVG node is inserted into a wrapper that supports pan + scale via\r\n * pure CSS transforms (no extra panzoom dep).\r\n */\r\nimport { onBeforeUnmount, onMounted, ref } from 'vue';\r\nimport { fetchViewerText } 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 surface = ref<HTMLDivElement | null>(null);\r\nconst error = ref<string | null>(null);\r\nconst loading = ref(true);\r\nconst scale = ref(1);\r\nconst tx = ref(0);\r\nconst ty = ref(0);\r\n\r\nlet dragging = false;\r\nlet dragStart: { x: number; y: number; tx: number; ty: number } | null = null;\r\nlet renderToken = 0;\r\n\r\nlet cachedMermaid: any = null;\r\nasync function ensureMermaid(): Promise<any | null> {\r\n if (cachedMermaid) return cachedMermaid;\r\n try {\r\n const mod = await import(/* @vite-ignore */ 'mermaid');\r\n cachedMermaid = mod.default ?? mod;\r\n cachedMermaid.initialize?.({\r\n startOnLoad: false,\r\n securityLevel: 'strict',\r\n theme: window.matchMedia?.('(prefers-color-scheme: dark)').matches\r\n ? 'dark'\r\n : 'default',\r\n });\r\n return cachedMermaid;\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 const myToken = ++renderToken;\r\n\r\n const mermaid = await ensureMermaid();\r\n if (myToken !== renderToken) return;\r\n if (!mermaid) {\r\n error.value = props.t\r\n ? props.t('viewer.peer_not_installed')\r\n : 'Mermaid viewer requires `mermaid` — install or use download.';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n let src: string;\r\n try {\r\n src = await fetchViewerText({\r\n url: props.url,\r\n headers: props.authHeaders?.() ?? {},\r\n credentials: props.authCredentials,\r\n });\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'fetch failed';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n if (myToken !== renderToken) return;\r\n\r\n try {\r\n const id = `filex-mermaid-${Date.now()}`;\r\n const { svg } = await mermaid.render(id, src);\r\n if (myToken !== renderToken) return;\r\n if (surface.value) {\r\n surface.value.innerHTML = svg;\r\n const svgEl = surface.value.querySelector('svg');\r\n if (svgEl) {\r\n svgEl.style.maxWidth = '100%';\r\n svgEl.style.height = 'auto';\r\n }\r\n }\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'render 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.2, scale.value / 1.25);\r\n}\r\nfunction reset(): void {\r\n scale.value = 1;\r\n tx.value = 0;\r\n ty.value = 0;\r\n}\r\n\r\nfunction onWheel(ev: WheelEvent): void {\r\n if (!ev.ctrlKey && !ev.metaKey) return;\r\n ev.preventDefault();\r\n const delta = -ev.deltaY;\r\n const factor = delta > 0 ? 1.1 : 1 / 1.1;\r\n scale.value = Math.max(0.2, Math.min(8, scale.value * factor));\r\n}\r\n\r\nfunction onPointerDown(ev: PointerEvent): void {\r\n dragging = true;\r\n dragStart = { x: ev.clientX, y: ev.clientY, tx: tx.value, ty: ty.value };\r\n (ev.target as HTMLElement).setPointerCapture?.(ev.pointerId);\r\n}\r\nfunction onPointerMove(ev: PointerEvent): void {\r\n if (!dragging || !dragStart) return;\r\n tx.value = dragStart.tx + (ev.clientX - dragStart.x);\r\n ty.value = dragStart.ty + (ev.clientY - dragStart.y);\r\n}\r\nfunction onPointerUp(): void {\r\n dragging = false;\r\n dragStart = null;\r\n}\r\n\r\nonMounted(load);\r\nonBeforeUnmount(() => {\r\n renderToken++;\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-mermaid\">\r\n <div\r\n class=\"filex-viewer-mermaid__pane\"\r\n @wheel=\"onWheel\"\r\n @pointerdown=\"onPointerDown\"\r\n @pointermove=\"onPointerMove\"\r\n @pointerup=\"onPointerUp\"\r\n @pointercancel=\"onPointerUp\"\r\n >\r\n <div\r\n v-if=\"error\"\r\n class=\"filex-viewer-fallback\"\r\n >\r\n <span class=\"filex-viewer-fallback__icon\">📊</span>\r\n <p>{{ error }}</p>\r\n </div>\r\n <div\r\n v-else-if=\"loading\"\r\n class=\"filex-viewer-fallback\"\r\n >\r\n <span class=\"filex-viewer-fallback__icon\">⏳</span>\r\n <p>{{ tt('viewer.loading', 'Loading…') }}</p>\r\n </div>\r\n <div\r\n v-show=\"!loading && !error\"\r\n ref=\"surface\"\r\n class=\"filex-viewer-mermaid__surface\"\r\n :style=\"{ transform: `translate(${tx}px, ${ty}px) scale(${scale})` }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-mermaid {\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 color: var(--fe-text, #1a1e27);\r\n}\r\n.filex-viewer-mermaid__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-mermaid__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-mermaid__pane {\r\n flex: 1;\r\n overflow: hidden;\r\n position: relative;\r\n cursor: grab;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n touch-action: none;\r\n}\r\n.filex-viewer-mermaid__pane:active {\r\n cursor: grabbing;\r\n}\r\n.filex-viewer-mermaid__surface {\r\n position: absolute;\r\n inset: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transform-origin: center center;\r\n transition: transform 0.05s linear;\r\n user-select: none;\r\n}\r\n.filex-viewer-mermaid__surface :deep(svg) {\r\n max-width: 90%;\r\n max-height: 90%;\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: var(--fe-text-muted, #5a6475);\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\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</style>\r\n"],"names":["props","__props","surface","ref","error","loading","scale","tx","ty","dragging","dragStart","renderToken","cachedMermaid","ensureMermaid","mod","_b","_a","load","myToken","mermaid","src","fetchViewerText","err","id","svg","svgEl","onWheel","ev","factor","onPointerDown","onPointerMove","onPointerUp","onMounted","onBeforeUnmount","tt","key","fallback","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_cache","_hoisted_3","_normalizeStyle","_vShow"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { defineComponent as E, ref as r, onMounted as I, onBeforeUnmount as S, watch as V, openBlock as m, createElementBlock as p, createElementVNode as l, toDisplayString as x, createCommentVNode as A, withDirectives as B, vShow as L } from "vue";
|
|
2
|
+
import { a as T } from "./useViewerFetch-czqbd2Lj.js";
|
|
3
|
+
import { _ as F } from "./index-CmSYzt6L.js";
|
|
4
|
+
const H = { class: "filex-viewer-psd" }, N = { class: "filex-viewer-psd__pane" }, q = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "filex-viewer-fallback"
|
|
7
|
+
}, M = {
|
|
8
|
+
key: 1,
|
|
9
|
+
class: "filex-viewer-fallback"
|
|
10
|
+
}, U = /* @__PURE__ */ E({
|
|
11
|
+
__name: "PsdViewer",
|
|
12
|
+
props: {
|
|
13
|
+
url: {},
|
|
14
|
+
mime: {},
|
|
15
|
+
ext: {},
|
|
16
|
+
t: { type: Function },
|
|
17
|
+
authHeaders: { type: Function },
|
|
18
|
+
authCredentials: {}
|
|
19
|
+
},
|
|
20
|
+
setup(D) {
|
|
21
|
+
const t = D, f = r(null), w = r([]), i = r(null), o = r(!0);
|
|
22
|
+
r(!1);
|
|
23
|
+
const P = r({ width: 0, height: 0 });
|
|
24
|
+
r(1);
|
|
25
|
+
let c = 0, u = null;
|
|
26
|
+
async function b() {
|
|
27
|
+
if (u) return u;
|
|
28
|
+
try {
|
|
29
|
+
return u = await import(
|
|
30
|
+
/* @vite-ignore */
|
|
31
|
+
"./index-UFULWo35.js"
|
|
32
|
+
), u;
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function _(a, e) {
|
|
38
|
+
if (a && Array.isArray(a.children))
|
|
39
|
+
for (const n of a.children)
|
|
40
|
+
e.push({
|
|
41
|
+
index: e.length,
|
|
42
|
+
name: n.name ?? "(unnamed)",
|
|
43
|
+
hidden: !!n.hidden
|
|
44
|
+
}), n.children && _(n, e);
|
|
45
|
+
}
|
|
46
|
+
async function g() {
|
|
47
|
+
var n;
|
|
48
|
+
o.value = !0, i.value = null, w.value = [];
|
|
49
|
+
const a = ++c, e = await b();
|
|
50
|
+
if (a === c) {
|
|
51
|
+
if (!e) {
|
|
52
|
+
i.value = t.t ? t.t("viewer.peer_not_installed") : "PSD viewer requires `ag-psd` — install or use download.", o.value = !1;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const d = await T({
|
|
57
|
+
url: t.url,
|
|
58
|
+
headers: ((n = t.authHeaders) == null ? void 0 : n.call(t)) ?? {},
|
|
59
|
+
credentials: t.authCredentials
|
|
60
|
+
});
|
|
61
|
+
if (a !== c) return;
|
|
62
|
+
const s = e.readPsd(d, {
|
|
63
|
+
skipLayerImageData: !1,
|
|
64
|
+
skipCompositeImageData: !1,
|
|
65
|
+
skipThumbnail: !0
|
|
66
|
+
});
|
|
67
|
+
P.value = { width: s.width, height: s.height };
|
|
68
|
+
const y = s.canvas;
|
|
69
|
+
if (y && f.value) {
|
|
70
|
+
const h = f.value;
|
|
71
|
+
h.width = s.width, h.height = s.height;
|
|
72
|
+
const v = h.getContext("2d");
|
|
73
|
+
v == null || v.drawImage(y, 0, 0);
|
|
74
|
+
} else
|
|
75
|
+
throw new Error("PSD has no composite image (skipCompositeImageData?)");
|
|
76
|
+
const k = [];
|
|
77
|
+
_(s, k), w.value = k;
|
|
78
|
+
} catch (d) {
|
|
79
|
+
i.value = d instanceof Error ? d.message : "PSD decode failed";
|
|
80
|
+
} finally {
|
|
81
|
+
o.value = !1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
I(g), S(() => {
|
|
86
|
+
c++;
|
|
87
|
+
}), V(() => t.url, g);
|
|
88
|
+
function C(a, e) {
|
|
89
|
+
return t.t ? t.t(a) : e;
|
|
90
|
+
}
|
|
91
|
+
return (a, e) => (m(), p("div", H, [
|
|
92
|
+
l("div", N, [
|
|
93
|
+
i.value ? (m(), p("div", q, [
|
|
94
|
+
e[0] || (e[0] = l("span", { class: "filex-viewer-fallback__icon" }, "🎨", -1)),
|
|
95
|
+
l("p", null, x(i.value), 1)
|
|
96
|
+
])) : o.value ? (m(), p("div", M, [
|
|
97
|
+
e[1] || (e[1] = l("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
|
|
98
|
+
l("p", null, x(C("viewer.loading", "Loading…")), 1)
|
|
99
|
+
])) : A("", !0),
|
|
100
|
+
B(l("canvas", {
|
|
101
|
+
ref_key: "canvasEl",
|
|
102
|
+
ref: f
|
|
103
|
+
}, null, 512), [
|
|
104
|
+
[L, !o.value && !i.value]
|
|
105
|
+
])
|
|
106
|
+
])
|
|
107
|
+
]));
|
|
108
|
+
}
|
|
109
|
+
}), J = /* @__PURE__ */ F(U, [["__scopeId", "data-v-d23e4974"]]);
|
|
110
|
+
export {
|
|
111
|
+
J as default
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=PsdViewer-VtPpxKVe.js.map
|