@l1yp/file-viewer 0.1.4 → 0.1.6
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 +57 -6
- package/dist/assets/step.worker-CfDTYOf_.js.map +1 -0
- package/dist/components/AnsiText.d.ts +47 -0
- package/dist/components/AnsiText.js +41 -0
- package/dist/components/AnsiText.js.map +1 -0
- package/dist/components/CertViewer.js +1 -1
- package/dist/components/CertViewer.js.map +1 -1
- package/dist/components/CertViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/CodeView.js +1 -1
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js +80 -71
- package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DocxEmbeddedFiles.js +9 -0
- package/dist/components/DocxEmbeddedFiles.js.map +1 -0
- package/dist/components/DocxEmbeddedFiles.vue.d.ts +15 -0
- package/dist/components/DocxEmbeddedFiles.vue_vue_type_script_setup_true_lang.js +69 -0
- package/dist/components/DocxEmbeddedFiles.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/DocxNavigationPane.js +1 -1
- package/dist/components/DocxNavigationPane.js.map +1 -1
- package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DocxViewer.js +1 -1
- package/dist/components/DocxViewer.js.map +1 -1
- package/dist/components/DocxViewer.vue.d.ts +1 -1
- package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js +182 -50
- package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/EplViewer.js +1 -1
- package/dist/components/EplViewer.js.map +1 -1
- package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/FileViewerBody.js +1 -1
- package/dist/components/FileViewerBody.js.map +1 -1
- package/dist/components/FileViewerBody.vue.d.ts +1 -0
- package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js +292 -281
- package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/FileViewerPanel.js +1 -1
- package/dist/components/FileViewerPanel.js.map +1 -1
- package/dist/components/FileViewerPanel.vue.d.ts +6 -1
- package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js +53 -51
- package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/HarViewer.js +1 -1
- package/dist/components/HarViewer.js.map +1 -1
- package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/JksViewer.js +1 -1
- package/dist/components/JksViewer.js.map +1 -1
- package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/LogViewer.js +1 -1
- package/dist/components/LogViewer.js.map +1 -1
- package/dist/components/LogViewer.vue.d.ts +3 -1
- package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js +284 -280
- package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ModelViewModes.js +9 -0
- package/dist/components/ModelViewModes.js.map +1 -0
- package/dist/components/ModelViewModes.vue.d.ts +11 -0
- package/dist/components/ModelViewModes.vue_vue_type_script_setup_true_lang.js +49 -0
- package/dist/components/ModelViewModes.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/ModelViewer.js +1 -1
- package/dist/components/ModelViewer.js.map +1 -1
- package/dist/components/ModelViewer.vue.d.ts +2 -1
- package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js +183 -96
- package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PdfNavigationPane.js +1 -1
- package/dist/components/PdfNavigationPane.js.map +1 -1
- package/dist/components/PdfNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PdfViewer.js +1 -1
- package/dist/components/PdfViewer.js.map +1 -1
- package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PptxNavigationPane.js +1 -1
- package/dist/components/PptxNavigationPane.js.map +1 -1
- package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PsdViewer.js +1 -1
- package/dist/components/PsdViewer.js.map +1 -1
- package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SqliteViewer.js +1 -1
- package/dist/components/SqliteViewer.js.map +1 -1
- package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ViewerLoadError.js +9 -0
- package/dist/components/ViewerLoadError.js.map +1 -0
- package/dist/components/ViewerLoadError.vue.d.ts +17 -0
- package/dist/components/ViewerLoadError.vue_vue_type_script_setup_true_lang.js +58 -0
- package/dist/components/ViewerLoadError.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/XlsxChart.js +1 -1
- package/dist/components/XlsxChart.js.map +1 -1
- package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/XlsxImageLayer.js +9 -0
- package/dist/components/XlsxImageLayer.js.map +1 -0
- package/dist/components/XlsxImageLayer.vue.d.ts +9 -0
- package/dist/components/XlsxImageLayer.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/components/XlsxImageLayer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/XlsxViewer.js +1 -1
- package/dist/components/XlsxViewer.js.map +1 -1
- package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js +230 -216
- package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/epl/EplResource.js +1 -1
- package/dist/components/epl/EplResource.js.map +1 -1
- package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/optionalViewer.d.ts +3 -2
- package/dist/components/optionalViewer.js +6 -3
- package/dist/components/optionalViewer.js.map +1 -1
- package/dist/composables/useFileViewer.d.ts +11 -3
- package/dist/composables/useFileViewer.js.map +1 -1
- package/dist/composables/useTeleportTheme.d.ts +7 -0
- package/dist/composables/useTeleportTheme.js +42 -0
- package/dist/composables/useTeleportTheme.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +29 -28
- package/dist/lib/ansi.d.ts +44 -0
- package/dist/lib/ansi.js +224 -0
- package/dist/lib/ansi.js.map +1 -0
- package/dist/lib/cfb.d.ts +37 -0
- package/dist/lib/cfb.js +112 -0
- package/dist/lib/cfb.js.map +1 -0
- package/dist/lib/docxEmbeddedDom.d.ts +22 -0
- package/dist/lib/docxEmbeddedDom.js +128 -0
- package/dist/lib/docxEmbeddedDom.js.map +1 -0
- package/dist/lib/docxEmbeddings.d.ts +41 -0
- package/dist/lib/docxEmbeddings.js +226 -0
- package/dist/lib/docxEmbeddings.js.map +1 -0
- package/dist/lib/docxTheme.d.ts +6 -0
- package/dist/lib/docxTheme.js +64 -0
- package/dist/lib/docxTheme.js.map +1 -0
- package/dist/lib/epl/code/structures.js +82 -0
- package/dist/lib/epl/code/structures.js.map +1 -0
- package/dist/lib/epl/code/variable.js +16 -0
- package/dist/lib/epl/code/variable.js.map +1 -0
- package/dist/lib/epl/eplDocument.js +28 -22
- package/dist/lib/epl/eplDocument.js.map +1 -1
- package/dist/lib/epl/index.d.ts +2 -1
- package/dist/lib/epl/index.js.map +1 -1
- package/dist/lib/epl/sections/code.js +37 -0
- package/dist/lib/epl/sections/code.js.map +1 -0
- package/dist/lib/epl/sections/esystemInfo.js +29 -0
- package/dist/lib/epl/sections/esystemInfo.js.map +1 -0
- package/dist/lib/epl/sections/losable.js +33 -0
- package/dist/lib/epl/sections/losable.js.map +1 -0
- package/dist/lib/epl/sections/projectConfig.js +39 -0
- package/dist/lib/epl/sections/projectConfig.js.map +1 -0
- package/dist/lib/epl/sections/resource.js +84 -0
- package/dist/lib/epl/sections/resource.js.map +1 -0
- package/dist/lib/fileType.d.ts +3 -1
- package/dist/lib/fileType.js +150 -137
- package/dist/lib/fileType.js.map +1 -1
- package/dist/lib/modelAppearance.d.ts +7 -0
- package/dist/lib/modelAppearance.js +41 -0
- package/dist/lib/modelAppearance.js.map +1 -0
- package/dist/lib/msi.js +62 -154
- package/dist/lib/msi.js.map +1 -1
- package/dist/lib/olePackage.d.ts +8 -0
- package/dist/lib/olePackage.js +37 -0
- package/dist/lib/olePackage.js.map +1 -0
- package/dist/lib/pptxFirstSlide.d.ts +11 -0
- package/dist/lib/pptxFirstSlide.js +34 -0
- package/dist/lib/pptxFirstSlide.js.map +1 -0
- package/dist/lib/step.d.ts +10 -0
- package/dist/lib/step.js +35 -0
- package/dist/lib/step.js.map +1 -0
- package/dist/lib/step.worker.d.ts +1 -0
- package/dist/lib/step.worker.js +18 -0
- package/dist/lib/step.worker.js.map +1 -0
- package/dist/lib/stepObject.d.ts +4 -0
- package/dist/lib/stepObject.js +52 -0
- package/dist/lib/stepObject.js.map +1 -0
- package/dist/lib/stepTypes.d.ts +60 -0
- package/dist/lib/viewerKind.js +10 -5
- package/dist/lib/viewerKind.js.map +1 -1
- package/dist/lib/xlsx.d.ts +1 -1
- package/dist/lib/xlsx.js +106 -89
- package/dist/lib/xlsx.js.map +1 -1
- package/dist/lib/xlsxCharts.js +71 -119
- package/dist/lib/xlsxCharts.js.map +1 -1
- package/dist/lib/xlsxImages.d.ts +43 -0
- package/dist/lib/xlsxImages.js +114 -0
- package/dist/lib/xlsxImages.js.map +1 -0
- package/dist/lib/xlsxParts.d.ts +17 -0
- package/dist/lib/xlsxParts.js +86 -0
- package/dist/lib/xlsxParts.js.map +1 -0
- package/dist/style.css +1 -1
- package/package.json +8 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from "./
|
|
1
|
+
import e from "./ViewerLoadError.js";
|
|
2
2
|
import { defineAsyncComponent as t, defineComponent as n, h as r } from "vue";
|
|
3
3
|
//#region src/components/optionalViewer.ts
|
|
4
4
|
function i(i, a, o) {
|
|
@@ -6,8 +6,9 @@ function i(i, a, o) {
|
|
|
6
6
|
return t({
|
|
7
7
|
loader: i,
|
|
8
8
|
errorComponent: n({
|
|
9
|
-
name: "
|
|
9
|
+
name: "ViewerUnavailable",
|
|
10
10
|
props: {
|
|
11
|
+
error: { default: void 0 },
|
|
11
12
|
url: {
|
|
12
13
|
type: String,
|
|
13
14
|
default: ""
|
|
@@ -22,10 +23,12 @@ function i(i, a, o) {
|
|
|
22
23
|
}
|
|
23
24
|
},
|
|
24
25
|
setup: (t) => () => r(e, {
|
|
26
|
+
error: t.error,
|
|
25
27
|
pkg: s,
|
|
26
28
|
label: o,
|
|
27
29
|
downloadUrl: t.url,
|
|
28
|
-
downloadName: t.name
|
|
30
|
+
downloadName: t.name,
|
|
31
|
+
onRetry: () => window.location.reload()
|
|
29
32
|
})
|
|
30
33
|
}),
|
|
31
34
|
onError(e, t, n) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optionalViewer.js","names":[],"sources":["../../src/components/optionalViewer.ts"],"sourcesContent":["import { defineAsyncComponent, defineComponent, h, type Component } from 'vue'\nimport
|
|
1
|
+
{"version":3,"file":"optionalViewer.js","names":[],"sources":["../../src/components/optionalViewer.ts"],"sourcesContent":["import { defineAsyncComponent, defineComponent, h, type Component } from 'vue'\nimport ViewerLoadError from '@/components/ViewerLoadError.vue'\n\n/**\n * Wrap a heavy viewer's async loader so that, when its OPTIONAL peer dependency isn't installed in the\n * consumer's app, an explicit resolution error shows an installation card instead of a blank error.\n * Other failures (network/cache/runtime errors) retain their actual cause in {@link ViewerLoadError}.\n * The dep is `external` in the library build, so a\n * viewer that statically imports it fails to evaluate its chunk when the dep is absent — which lands here.\n *\n * The error component receives the SAME props the viewer was given (`url`/`name`/`size`), so the card can keep\n * the file downloadable. Only for viewers whose dep is imported STATICALLY (pdf/docx/xlsx/pptx/sqlite/model/\n * dicom); viewers that import their engine dynamically at runtime (geo/raster/ebook) handle absence themselves.\n */\nexport function optionalViewer(\n loader: () => Promise<Component | { default: Component }>,\n deps: string | string[],\n label: string,\n): Component {\n const pkg = Array.isArray(deps) ? deps : [deps]\n return defineAsyncComponent({\n loader: loader as () => Promise<Component>,\n errorComponent: defineComponent({\n name: 'ViewerUnavailable',\n props: {\n error: { default: undefined },\n url: { type: String, default: '' },\n name: { type: String, default: '' },\n size: { type: Number, default: undefined },\n },\n setup: (props) => () =>\n h(ViewerLoadError, {\n error: props.error,\n pkg,\n label,\n downloadUrl: props.url,\n downloadName: props.name,\n onRetry: () => window.location.reload(),\n }),\n }),\n // Don't retry a stale module URL automatically. The error card explains the failure and offers reload.\n onError(_error, _retry, fail) {\n fail()\n },\n })\n}\n"],"mappings":";;;AAcA,SAAgB,EACd,GACA,GACA,GACW;CACX,IAAM,IAAM,MAAM,QAAQ,CAAI,IAAI,IAAO,CAAC,CAAI;CAC9C,OAAO,EAAqB;EAClB;EACR,gBAAgB,EAAgB;GAC9B,MAAM;GACN,OAAO;IACL,OAAO,EAAE,SAAS,KAAA,EAAU;IAC5B,KAAK;KAAE,MAAM;KAAQ,SAAS;IAAG;IACjC,MAAM;KAAE,MAAM;KAAQ,SAAS;IAAG;IAClC,MAAM;KAAE,MAAM;KAAQ,SAAS,KAAA;IAAU;GAC3C;GACA,QAAQ,YACN,EAAE,GAAiB;IACjB,OAAO,EAAM;IACb;IACA;IACA,aAAa,EAAM;IACnB,cAAc,EAAM;IACpB,eAAe,OAAO,SAAS,OAAO;GACxC,CAAC;EACL,CAAC;EAED,QAAQ,GAAQ,GAAQ,GAAM;GAC5B,EAAK;EACP;CACF,CAAC;AACH"}
|
|
@@ -78,8 +78,10 @@ export interface ViewerFile {
|
|
|
78
78
|
lrc?: boolean;
|
|
79
79
|
/** Large text / `.log`: the panel hands the URL to the in-browser streaming log viewer (virtual-scrolled). */
|
|
80
80
|
log?: boolean;
|
|
81
|
-
/** 3D model (.stl/.obj/.ply/.glb/.gltf):
|
|
81
|
+
/** 3D model (.stl/.obj/.ply/.glb/.gltf/.stp/.step): rendered in-browser with three.js. */
|
|
82
82
|
model?: boolean;
|
|
83
|
+
/** STEP detected from MIME or a different detectName; independent of the display caption. */
|
|
84
|
+
modelFormat?: 'step';
|
|
83
85
|
/** Decoding image (TIFF/PSD/HEIC/RAW): the panel hands the URL + kind to the in-browser raster viewer. */
|
|
84
86
|
raster?: 'tiff' | 'psd' | 'heic' | 'raw';
|
|
85
87
|
/** E-book (EPUB/FB2/MOBI/DjVu): the panel hands the URL + kind to the in-browser e-book reader. */
|
|
@@ -224,9 +226,12 @@ export declare function useFileViewer(): {
|
|
|
224
226
|
/** Large text / `.log`: the panel hands the URL to the in-browser streaming log viewer (virtual-scrolled). */
|
|
225
227
|
| undefined;
|
|
226
228
|
log?: boolean
|
|
227
|
-
/** 3D model (.stl/.obj/.ply/.glb/.gltf):
|
|
229
|
+
/** 3D model (.stl/.obj/.ply/.glb/.gltf/.stp/.step): rendered in-browser with three.js. */
|
|
228
230
|
| undefined;
|
|
229
231
|
model?: boolean
|
|
232
|
+
/** STEP detected from MIME or a different detectName; independent of the display caption. */
|
|
233
|
+
| undefined;
|
|
234
|
+
modelFormat?: "step"
|
|
230
235
|
/** Decoding image (TIFF/PSD/HEIC/RAW): the panel hands the URL + kind to the in-browser raster viewer. */
|
|
231
236
|
| undefined;
|
|
232
237
|
raster?: "tiff" | "psd" | "heic" | "raw"
|
|
@@ -377,9 +382,12 @@ export declare function useFileViewer(): {
|
|
|
377
382
|
/** Large text / `.log`: the panel hands the URL to the in-browser streaming log viewer (virtual-scrolled). */
|
|
378
383
|
| undefined;
|
|
379
384
|
log?: boolean
|
|
380
|
-
/** 3D model (.stl/.obj/.ply/.glb/.gltf):
|
|
385
|
+
/** 3D model (.stl/.obj/.ply/.glb/.gltf/.stp/.step): rendered in-browser with three.js. */
|
|
381
386
|
| undefined;
|
|
382
387
|
model?: boolean
|
|
388
|
+
/** STEP detected from MIME or a different detectName; independent of the display caption. */
|
|
389
|
+
| undefined;
|
|
390
|
+
modelFormat?: "step"
|
|
383
391
|
/** Decoding image (TIFF/PSD/HEIC/RAW): the panel hands the URL + kind to the in-browser raster viewer. */
|
|
384
392
|
| undefined;
|
|
385
393
|
raster?: "tiff" | "psd" | "heic" | "raw"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFileViewer.js","names":[],"sources":["../../src/composables/useFileViewer.ts"],"sourcesContent":["import { computed, ref } from 'vue'\n\n/** A file opened in the side viewer: its display name, fetch/download URL, and highlight language. */\nexport interface ViewerFile {\n name: string\n /** Download endpoint URL — fetched as text and reused by the download button. Omit when `content` is set. */\n url?: string\n /** highlight.js language id, '' for plain text, or 'markdown' (the panel renders markdown instead of highlighting). */\n lang: string\n /** HTML document: the panel offers a render/source toggle, rendering the markup in a sandboxed iframe. */\n html?: boolean\n /** SVG document: the panel offers a render/source toggle — render shows the picture, source the XML. */\n svg?: boolean\n /** ZIP archive: the panel fetches the bytes and hands them to the in-browser archive browser. */\n zip?: boolean\n /** 7z archive: the panel fetches the bytes and hands them to the in-browser 7z browser. */\n sevenZip?: boolean\n /**\n * tar-family ('tar': tar/gz/tgz/xz/txz/bz2/tbz2) or rar ('rar') archive: the panel hands the URL + this\n * kind to the generic in-browser ArchiveBrowser, which decompresses the bytes and browses the entries.\n */\n archive?: 'tar' | 'rar'\n /** Native binary object (.so/.dll): the panel hands the URL to the in-browser symbol browser. */\n binobj?: boolean\n /** E-language (.e/.ec) project: the panel hands the URL to the in-browser EPL viewer (parse + decompile). */\n epl?: boolean\n /** DICOM (.dcm) medical image: the panel hands the URL to the in-browser DICOM viewer. */\n dicom?: boolean\n /** Word (.docx) document: the panel hands the URL to the in-browser Word viewer (docx-preview). */\n docx?: boolean\n /** Excel (.xlsx/.xlsm) workbook: the panel hands the URL to the in-browser spreadsheet viewer (exceljs). */\n xlsx?: boolean\n /** PowerPoint (.pptx/.pptm/.ppsx) deck: the panel hands the URL to the in-browser slide viewer (pptx-renderer). */\n pptx?: boolean\n /** Rich Text (.rtf) document: the panel hands the URL to the in-browser rich-text viewer (hand-rolled RTF parser). */\n rtf?: boolean\n /** PDF (.pdf) document: the panel hands the URL to the in-browser PDF viewer (pdfjs-dist). */\n pdf?: boolean\n /** OPML / FreeMind (.opml/.mm) outline: the panel fetches the text and renders it as an interactive mind map. */\n mindmap?: boolean\n /** XMind workbook (.xmind): the panel hands the URL to the in-browser XMind viewer (unzip → mind-map tree). */\n xmind?: boolean\n /** Email (.eml) message: the panel hands the URL to the in-browser email viewer (MIME parser). */\n eml?: boolean\n /** Web archive (.mht/.mhtml): the panel hands the URL to the in-browser web-archive viewer (MIME parser). */\n mht?: boolean\n /** HAR (.har) capture: the panel hands the URL to the in-browser HAR viewer (hand-rolled JSON parser). */\n har?: boolean\n /** SQLite database (.sqlite/.db/…): the panel hands the URL to the in-browser SQLite viewer (sql.js). */\n sqlite?: boolean\n /** Certificate / key (.pem/.crt/.der/.csr/.p12/…): the panel hands the URL to the in-browser cert viewer (ASN.1/X.509). */\n cert?: boolean\n /** Keystore (.jks/.keystore/.jceks + PKCS#12 .p12/.pfx): the panel hands the URL to the in-browser keystore viewer (sniffs format, parse + password decrypt). */\n jks?: boolean\n /** Subtitle (.srt/.vtt/.ass/.ssa): the panel renders the fetched text as a parsed cue list (render/source toggle). */\n subtitle?: boolean\n /** CSV / TSV (.csv/.tsv): the panel renders the fetched text as a parsed table (render/source toggle). */\n csv?: boolean\n /** JSON Lines (.jsonl/.ndjson): the panel renders the fetched text as a record list — truncated rows, click to expand (render/source toggle). */\n jsonl?: boolean\n /** Java bytecode (.class): the panel hands the URL to the in-browser class viewer (parse structure → fields/methods). */\n javaClass?: boolean\n /** JVM heap dump (.hprof): the panel hands the URL to the in-browser HPROF viewer (stream-parse → class histogram + per-class object drill-in). */\n hprof?: boolean\n /** Windows Installer (.msi/.msp/.msm): the panel hands the URL to the in-browser MSI viewer (OLE compound file → product identity + summary). */\n msi?: boolean\n /** Windows app package (.appx/.msix/.appxbundle/.msixbundle): the panel hands the URL to the in-browser APPX viewer (unzip manifest → identity/deps/capabilities). */\n appx?: boolean\n /** Font (.ttf/.otf/.woff/.woff2): the panel hands the URL to the in-browser font specimen (FontFace API). */\n font?: boolean\n /** Jupyter Notebook (.ipynb): the panel hands the URL to the in-browser notebook viewer (hand-rolled JSON parser). */\n ipynb?: boolean\n /** Geodata (.geojson/.kml/.gpx): the panel renders the fetched text as an offline SVG map (render/source toggle). */\n geo?: boolean\n /** Audio (mp3/wav/flac/ogg/m4a/aac/opus, or .mid): the panel hands the URL to the in-browser audio player. */\n audio?: boolean\n /** QQ Music encrypted audio (.mflac/.mgg/…): the panel hands the URL to the QMC player (decrypts in-browser, then plays). */\n qmc?: boolean\n /** LRC lyrics (.lrc): the panel hands the URL to the lyrics viewer (self-fetches + sniffs GBK, then renders synced lines). */\n lrc?: boolean\n /** Large text / `.log`: the panel hands the URL to the in-browser streaming log viewer (virtual-scrolled). */\n log?: boolean\n /** 3D model (.stl/.obj/.ply/.glb/.gltf):
|
|
1
|
+
{"version":3,"file":"useFileViewer.js","names":[],"sources":["../../src/composables/useFileViewer.ts"],"sourcesContent":["import { computed, ref } from 'vue'\n\n/** A file opened in the side viewer: its display name, fetch/download URL, and highlight language. */\nexport interface ViewerFile {\n name: string\n /** Download endpoint URL — fetched as text and reused by the download button. Omit when `content` is set. */\n url?: string\n /** highlight.js language id, '' for plain text, or 'markdown' (the panel renders markdown instead of highlighting). */\n lang: string\n /** HTML document: the panel offers a render/source toggle, rendering the markup in a sandboxed iframe. */\n html?: boolean\n /** SVG document: the panel offers a render/source toggle — render shows the picture, source the XML. */\n svg?: boolean\n /** ZIP archive: the panel fetches the bytes and hands them to the in-browser archive browser. */\n zip?: boolean\n /** 7z archive: the panel fetches the bytes and hands them to the in-browser 7z browser. */\n sevenZip?: boolean\n /**\n * tar-family ('tar': tar/gz/tgz/xz/txz/bz2/tbz2) or rar ('rar') archive: the panel hands the URL + this\n * kind to the generic in-browser ArchiveBrowser, which decompresses the bytes and browses the entries.\n */\n archive?: 'tar' | 'rar'\n /** Native binary object (.so/.dll): the panel hands the URL to the in-browser symbol browser. */\n binobj?: boolean\n /** E-language (.e/.ec) project: the panel hands the URL to the in-browser EPL viewer (parse + decompile). */\n epl?: boolean\n /** DICOM (.dcm) medical image: the panel hands the URL to the in-browser DICOM viewer. */\n dicom?: boolean\n /** Word (.docx) document: the panel hands the URL to the in-browser Word viewer (docx-preview). */\n docx?: boolean\n /** Excel (.xlsx/.xlsm) workbook: the panel hands the URL to the in-browser spreadsheet viewer (exceljs). */\n xlsx?: boolean\n /** PowerPoint (.pptx/.pptm/.ppsx) deck: the panel hands the URL to the in-browser slide viewer (pptx-renderer). */\n pptx?: boolean\n /** Rich Text (.rtf) document: the panel hands the URL to the in-browser rich-text viewer (hand-rolled RTF parser). */\n rtf?: boolean\n /** PDF (.pdf) document: the panel hands the URL to the in-browser PDF viewer (pdfjs-dist). */\n pdf?: boolean\n /** OPML / FreeMind (.opml/.mm) outline: the panel fetches the text and renders it as an interactive mind map. */\n mindmap?: boolean\n /** XMind workbook (.xmind): the panel hands the URL to the in-browser XMind viewer (unzip → mind-map tree). */\n xmind?: boolean\n /** Email (.eml) message: the panel hands the URL to the in-browser email viewer (MIME parser). */\n eml?: boolean\n /** Web archive (.mht/.mhtml): the panel hands the URL to the in-browser web-archive viewer (MIME parser). */\n mht?: boolean\n /** HAR (.har) capture: the panel hands the URL to the in-browser HAR viewer (hand-rolled JSON parser). */\n har?: boolean\n /** SQLite database (.sqlite/.db/…): the panel hands the URL to the in-browser SQLite viewer (sql.js). */\n sqlite?: boolean\n /** Certificate / key (.pem/.crt/.der/.csr/.p12/…): the panel hands the URL to the in-browser cert viewer (ASN.1/X.509). */\n cert?: boolean\n /** Keystore (.jks/.keystore/.jceks + PKCS#12 .p12/.pfx): the panel hands the URL to the in-browser keystore viewer (sniffs format, parse + password decrypt). */\n jks?: boolean\n /** Subtitle (.srt/.vtt/.ass/.ssa): the panel renders the fetched text as a parsed cue list (render/source toggle). */\n subtitle?: boolean\n /** CSV / TSV (.csv/.tsv): the panel renders the fetched text as a parsed table (render/source toggle). */\n csv?: boolean\n /** JSON Lines (.jsonl/.ndjson): the panel renders the fetched text as a record list — truncated rows, click to expand (render/source toggle). */\n jsonl?: boolean\n /** Java bytecode (.class): the panel hands the URL to the in-browser class viewer (parse structure → fields/methods). */\n javaClass?: boolean\n /** JVM heap dump (.hprof): the panel hands the URL to the in-browser HPROF viewer (stream-parse → class histogram + per-class object drill-in). */\n hprof?: boolean\n /** Windows Installer (.msi/.msp/.msm): the panel hands the URL to the in-browser MSI viewer (OLE compound file → product identity + summary). */\n msi?: boolean\n /** Windows app package (.appx/.msix/.appxbundle/.msixbundle): the panel hands the URL to the in-browser APPX viewer (unzip manifest → identity/deps/capabilities). */\n appx?: boolean\n /** Font (.ttf/.otf/.woff/.woff2): the panel hands the URL to the in-browser font specimen (FontFace API). */\n font?: boolean\n /** Jupyter Notebook (.ipynb): the panel hands the URL to the in-browser notebook viewer (hand-rolled JSON parser). */\n ipynb?: boolean\n /** Geodata (.geojson/.kml/.gpx): the panel renders the fetched text as an offline SVG map (render/source toggle). */\n geo?: boolean\n /** Audio (mp3/wav/flac/ogg/m4a/aac/opus, or .mid): the panel hands the URL to the in-browser audio player. */\n audio?: boolean\n /** QQ Music encrypted audio (.mflac/.mgg/…): the panel hands the URL to the QMC player (decrypts in-browser, then plays). */\n qmc?: boolean\n /** LRC lyrics (.lrc): the panel hands the URL to the lyrics viewer (self-fetches + sniffs GBK, then renders synced lines). */\n lrc?: boolean\n /** Large text / `.log`: the panel hands the URL to the in-browser streaming log viewer (virtual-scrolled). */\n log?: boolean\n /** 3D model (.stl/.obj/.ply/.glb/.gltf/.stp/.step): rendered in-browser with three.js. */\n model?: boolean\n /** STEP detected from MIME or a different detectName; independent of the display caption. */\n modelFormat?: 'step'\n /** Decoding image (TIFF/PSD/HEIC/RAW): the panel hands the URL + kind to the in-browser raster viewer. */\n raster?: 'tiff' | 'psd' | 'heic' | 'raw'\n /** E-book (EPUB/FB2/MOBI/DjVu): the panel hands the URL + kind to the in-browser e-book reader. */\n ebook?: 'epub' | 'fb2' | 'mobi' | 'djvu'\n /** Diagram (.drawio/.excalidraw): the panel renders the fetched text as an SVG (render/source toggle). */\n diagram?: 'drawio' | 'excalidraw'\n /** DXF (.dxf) CAD drawing: the panel hands the URL to the in-browser DXF viewer (parse → SVG, pan/zoom/layers). */\n dxf?: boolean\n /**\n * Raster image (png/jpg/…/svg-as-picture): rendered inline as a zoomable picture. The main FileChip flow\n * routes images to the LIGHTBOX, so this is set only for archive entries (browsed inside the side viewer,\n * where there is no lightbox) — see classifyViewerFile.\n */\n image?: boolean\n /** Video (mp4/webm/…): rendered inline with a native <video> player. Like {@link image}, set only for archive entries. */\n video?: boolean\n /** Unpreviewable binary: the body shows a \"can't preview — download\" card. Set only for archive entries with no matching viewer. */\n binary?: boolean\n /**\n * Hex dump: the panel hands the URL to the in-browser hex viewer (offset + raw bytes + ASCII gutter). Never\n * auto-detected — set only when the user picks \"十六进制\" from the unpreviewable-binary card's \"open with\"\n * chooser (any bytes can be inspected this way), see FileViewerBody.\n */\n hex?: boolean\n /** File size in bytes (from the manifest) when known — drives the symbol browser's large-file gate. */\n size?: number\n /** Inline text to render directly (e.g. a loaded skill's SKILL.md) — when set, the panel skips fetching. */\n content?: string\n}\n\n// Module-level singleton: a file chip (deep in the message tree) opens the viewer, and the panel\n// (mounted by DetailView) reads the same ref. The detail view closes it on navigation/unmount.\nconst current = ref<ViewerFile | null>(null)\n\n// Shared panel width (px), driven by the drag splitter. DetailView feeds it into `--fv-width` so the\n// conversation column reflows and the panel resizes together; the panel reads it for the drag baseline.\nconst MIN_WIDTH = 360\nconst MAX_WIDTH = 760\n\n// Open at the viewer's original responsive width — clamp(360, 42vw, 760) — so it starts wide; the\n// drag splitter adjusts from there. (No window under SSR: fall back to a sensible fixed default.)\nfunction defaultWidth(): number {\n if (typeof window === 'undefined') return 680\n return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, Math.round(window.innerWidth * 0.42)))\n}\nconst width = ref(defaultWidth())\n\n/** Clamp to a sane range: never narrower than MIN_WIDTH, and always leave ~320px for the conversation. */\nfunction setWidth(px: number): void {\n const max = typeof window !== 'undefined' ? Math.max(MIN_WIDTH, window.innerWidth - 320) : 900\n width.value = Math.min(max, Math.max(MIN_WIDTH, Math.round(px)))\n}\n\nexport function useFileViewer() {\n return {\n current,\n width,\n setWidth,\n isOpen: computed(() => current.value !== null),\n open(file: ViewerFile): void {\n current.value = file\n },\n close(): void {\n current.value = null\n },\n }\n}\n"],"mappings":";;AAsHA,IAAM,IAAU,EAAuB,IAAI,GAIrC,IAAY,KACZ,IAAY;AAIlB,SAAS,IAAuB;CAE9B,OADI,OAAO,SAAW,MAAoB,MACnC,KAAK,IAAI,GAAW,KAAK,IAAI,GAAW,KAAK,MAAM,OAAO,aAAa,GAAI,CAAC,CAAC;AACtF;AACA,IAAM,IAAQ,EAAI,EAAa,CAAC;AAGhC,SAAS,EAAS,GAAkB;CAClC,IAAM,IAAM,OAAO,SAAW,MAAc,KAAK,IAAI,GAAW,OAAO,aAAa,GAAG,IAAI;CAC3F,EAAM,QAAQ,KAAK,IAAI,GAAK,KAAK,IAAI,GAAW,KAAK,MAAM,CAAE,CAAC,CAAC;AACjE;AAEA,SAAgB,IAAgB;CAC9B,OAAO;EACL;EACA;EACA;EACA,QAAQ,QAAe,EAAQ,UAAU,IAAI;EAC7C,KAAK,GAAwB;GAC3B,EAAQ,QAAQ;EAClB;EACA,QAAc;GACZ,EAAQ,QAAQ;EAClB;CACF;AACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
/** Keep a body-mounted overlay in the originating viewer's theme, including host CSS overrides. */
|
|
3
|
+
export declare function useTeleportTheme(source: Readonly<Ref<HTMLElement | null>>, open: Ref<boolean>): Readonly<Ref<{
|
|
4
|
+
readonly [x: string]: string;
|
|
5
|
+
}, {
|
|
6
|
+
readonly [x: string]: string;
|
|
7
|
+
}>>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readonly as e, shallowRef as t, watch as n } from "vue";
|
|
2
|
+
//#region src/composables/useTeleportTheme.ts
|
|
3
|
+
var r = [
|
|
4
|
+
"--text",
|
|
5
|
+
"--muted",
|
|
6
|
+
"--surface",
|
|
7
|
+
"--border-2",
|
|
8
|
+
"--accent",
|
|
9
|
+
"--shadow",
|
|
10
|
+
"--font-sans"
|
|
11
|
+
];
|
|
12
|
+
function i(i, a) {
|
|
13
|
+
let o = t({});
|
|
14
|
+
return n([i, a], ([e, t], n, i) => {
|
|
15
|
+
if (!e || !t) return;
|
|
16
|
+
let a = () => {
|
|
17
|
+
let t = getComputedStyle(e);
|
|
18
|
+
o.value = Object.fromEntries([["color-scheme", t.colorScheme], ...r.map((e) => [e, t.getPropertyValue(e)])]);
|
|
19
|
+
};
|
|
20
|
+
a();
|
|
21
|
+
let s = new MutationObserver(a);
|
|
22
|
+
for (let t = e; t; t = t.parentElement) s.observe(t, {
|
|
23
|
+
attributes: !0,
|
|
24
|
+
attributeFilter: [
|
|
25
|
+
"class",
|
|
26
|
+
"style",
|
|
27
|
+
"data-theme"
|
|
28
|
+
]
|
|
29
|
+
});
|
|
30
|
+
let c = window.matchMedia("(prefers-color-scheme: dark)");
|
|
31
|
+
c.addEventListener("change", a), i(() => {
|
|
32
|
+
s.disconnect(), c.removeEventListener("change", a);
|
|
33
|
+
});
|
|
34
|
+
}, {
|
|
35
|
+
immediate: !0,
|
|
36
|
+
flush: "post"
|
|
37
|
+
}), e(o);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { i as useTeleportTheme };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=useTeleportTheme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTeleportTheme.js","names":[],"sources":["../../src/composables/useTeleportTheme.ts"],"sourcesContent":["import { readonly, shallowRef, watch, type Ref } from 'vue'\n\n// Only the fullscreen toolbar's presentation crosses the Teleport boundary. Document bytes stay untouched.\nconst TOKENS = [\n '--text',\n '--muted',\n '--surface',\n '--border-2',\n '--accent',\n '--shadow',\n '--font-sans',\n] as const\n\n/** Keep a body-mounted overlay in the originating viewer's theme, including host CSS overrides. */\nexport function useTeleportTheme(source: Readonly<Ref<HTMLElement | null>>, open: Ref<boolean>) {\n const style = shallowRef<Record<string, string>>({})\n\n watch(\n [source, open],\n ([element, active], _, onCleanup) => {\n if (!element || !active) return\n const sync = () => {\n const computed = getComputedStyle(element)\n style.value = Object.fromEntries([\n ['color-scheme', computed.colorScheme],\n ...TOKENS.map((token) => [token, computed.getPropertyValue(token)]),\n ])\n }\n sync()\n\n // Observe only this ancestor chain; unrelated page mutations do not trigger style reads.\n const observer = new MutationObserver(sync)\n for (\n let ancestor: HTMLElement | null = element;\n ancestor;\n ancestor = ancestor.parentElement\n ) {\n observer.observe(ancestor, {\n attributes: true,\n attributeFilter: ['class', 'style', 'data-theme'],\n })\n }\n const media = window.matchMedia('(prefers-color-scheme: dark)')\n media.addEventListener('change', sync)\n onCleanup(() => {\n observer.disconnect()\n media.removeEventListener('change', sync)\n })\n },\n { immediate: true, flush: 'post' },\n )\n\n return readonly(style)\n}\n"],"mappings":";;AAGA,IAAM,IAAS;CACb;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,SAAgB,EAAiB,GAA2C,GAAoB;CAC9F,IAAM,IAAQ,EAAmC,CAAC,CAAC;CAqCnD,OAnCA,EACE,CAAC,GAAQ,CAAI,IACZ,CAAC,GAAS,IAAS,GAAG,MAAc;EACnC,IAAI,CAAC,KAAW,CAAC,GAAQ;EACzB,IAAM,UAAa;GACjB,IAAM,IAAW,iBAAiB,CAAO;GACzC,EAAM,QAAQ,OAAO,YAAY,CAC/B,CAAC,gBAAgB,EAAS,WAAW,GACrC,GAAG,EAAO,KAAK,MAAU,CAAC,GAAO,EAAS,iBAAiB,CAAK,CAAC,CAAC,CACpE,CAAC;EACH;EACA,EAAK;EAGL,IAAM,IAAW,IAAI,iBAAiB,CAAI;EAC1C,KACE,IAAI,IAA+B,GACnC,GACA,IAAW,EAAS,eAEpB,EAAS,QAAQ,GAAU;GACzB,YAAY;GACZ,iBAAiB;IAAC;IAAS;IAAS;GAAY;EAClD,CAAC;EAEH,IAAM,IAAQ,OAAO,WAAW,8BAA8B;EAE9D,AADA,EAAM,iBAAiB,UAAU,CAAI,GACrC,QAAgB;GAEd,AADA,EAAS,WAAW,GACpB,EAAM,oBAAoB,UAAU,CAAI;EAC1C,CAAC;CACH,GACA;EAAE,WAAW;EAAM,OAAO;CAAO,CACnC,GAEO,EAAS,CAAK;AACvB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* shell consumes — so that shell imports them from here instead of keeping its own copies.
|
|
14
14
|
*/
|
|
15
15
|
import './styles/theme.css';
|
|
16
|
+
import './styles/highlight.css';
|
|
16
17
|
export { default as FileViewer } from './FileViewer.vue';
|
|
17
18
|
export { default as FileViewerPanel } from './components/FileViewerPanel.vue';
|
|
18
19
|
export { default as FileViewerBody } from './components/FileViewerBody.vue';
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
/* empty css */
|
|
2
|
+
/* empty css */
|
|
2
3
|
import { resolveInput as e } from "./lib/resolveInput.js";
|
|
3
|
-
import { LARGE_TEXT_BYTES as t, ebookKind as n, fileExt as r, hljsLang as i, isAppxFile as a, isAudioFile as o, isBinaryObjFile as s, isCertFile as c, isCsvFile as l, isDicomFile as u, isDocxFile as d, isDxfFile as f, isEmlFile as p, isEplFile as m, isFontFile as h, isGeoFile as g, isHarFile as _, isHprofFile as v, isHtmlFile as y, isImageFile as b, isJavaClassFile as x, isJksFile as S, isJsonlFile as C, isLogFile as w, isLrcFile as T, isMhtFile as E, isMindMapFile as D, isModelFile as O, isMsiFile as k, isNotebookFile as A, isPdfFile as j, isPptxFile as M, isQmcAudioFile as N, isRarFile as P, isRtfFile as F, isSevenZipFile as I, isSqliteFile as L,
|
|
4
|
-
import { isDiagramFile as
|
|
5
|
-
import { canToggleView as
|
|
6
|
-
import
|
|
7
|
-
import { formatBytes as
|
|
8
|
-
import { FILL_ICONS as
|
|
9
|
-
import
|
|
10
|
-
import { useFileViewer as
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import { useLightbox as
|
|
14
|
-
import { MONO as
|
|
15
|
-
import { inline as
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import { md as
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import { isMissingModule as
|
|
26
|
-
import { segmentize as
|
|
27
|
-
import { ZipEncryptedError as
|
|
28
|
-
import { QmcError as
|
|
29
|
-
import { Sha1 as
|
|
30
|
-
export {
|
|
4
|
+
import { LARGE_TEXT_BYTES as t, ebookKind as n, fileExt as r, hljsLang as i, isAppxFile as a, isAudioFile as o, isBinaryObjFile as s, isCertFile as c, isCsvFile as l, isDicomFile as u, isDocxFile as d, isDxfFile as f, isEmlFile as p, isEplFile as m, isFontFile as h, isGeoFile as g, isHarFile as _, isHprofFile as v, isHtmlFile as y, isImageFile as b, isJavaClassFile as x, isJksFile as S, isJsonlFile as C, isLogFile as w, isLrcFile as T, isMhtFile as E, isMindMapFile as D, isModelFile as O, isMsiFile as k, isNotebookFile as A, isPdfFile as j, isPptxFile as M, isQmcAudioFile as N, isRarFile as P, isRtfFile as F, isSevenZipFile as I, isSqliteFile as L, isStepFile as R, isSubtitleFile as z, isSvgFile as B, isTarballFile as V, isTextFile as H, isVideoFile as U, isXlsxFile as W, isXmindFile as G, isZipFile as K, rasterImageKind as q } from "./lib/fileType.js";
|
|
5
|
+
import { isDiagramFile as J, renderDiagram as Y } from "./lib/diagram.js";
|
|
6
|
+
import { canToggleView as X, classifyViewerFile as Z, mediaMimeForName as Q, skipsTextLoad as $ } from "./lib/viewerKind.js";
|
|
7
|
+
import ee from "./components/MissingDependency.js";
|
|
8
|
+
import { formatBytes as te, formatDateTime as ne, formatDuration as re, formatSizeCoarse as ie } from "./lib/format.js";
|
|
9
|
+
import { FILL_ICONS as ae, STROKE_ICONS as oe } from "./components/icons/iconPaths.js";
|
|
10
|
+
import se from "./components/icons/Icon.js";
|
|
11
|
+
import { useFileViewer as ce } from "./composables/useFileViewer.js";
|
|
12
|
+
import le from "./components/ui/ClampBlock.js";
|
|
13
|
+
import ue from "./components/CodeBlock.js";
|
|
14
|
+
import { useLightbox as de } from "./composables/useLightbox.js";
|
|
15
|
+
import { MONO as fe, SANS as pe, SERIF as me } from "./lib/fonts.js";
|
|
16
|
+
import { inline as he, renderInline as ge } from "./lib/markdown/inline.js";
|
|
17
|
+
import _e from "./components/InlineText.js";
|
|
18
|
+
import ve from "./components/MarkdownTable.js";
|
|
19
|
+
import { md as ye, mdNodes as be } from "./lib/markdown/blocks.js";
|
|
20
|
+
import xe from "./components/MarkdownText.js";
|
|
21
|
+
import Se from "./components/FileViewerBody.js";
|
|
22
|
+
import Ce from "./FileViewer.js";
|
|
23
|
+
import we from "./components/FileViewerPanel.js";
|
|
24
|
+
import Te from "./components/ImageLightbox.js";
|
|
25
|
+
import Ee from "./components/MindMapView.js";
|
|
26
|
+
import { isMissingModule as De, loadOptionalDep as Oe } from "./lib/optionalDep.js";
|
|
27
|
+
import { segmentize as ke } from "./lib/markdown/segmentize.js";
|
|
28
|
+
import { ZipEncryptedError as Ae, ZipPasswordError as je, extractZipEntry as Me, readZip as Ne, zipSupported as Pe } from "./lib/zip.js";
|
|
29
|
+
import { QmcError as Fe, decryptEKey as Ie, decryptQmc as Le, parseFooter as Re } from "./lib/qmc.js";
|
|
30
|
+
import { Sha1 as ze, sha1 as Be } from "./lib/sha1.js";
|
|
31
|
+
export { le as ClampBlock, ue as CodeBlock, ae as FILL_ICONS, Ce as FileViewer, Se as FileViewerBody, we as FileViewerPanel, se as Icon, Te as ImageLightbox, _e as InlineText, t as LARGE_TEXT_BYTES, fe as MONO, ve as MarkdownTable, xe as MarkdownText, Ee as MindMapView, ee as MissingDependency, Fe as QmcError, pe as SANS, me as SERIF, oe as STROKE_ICONS, ze as Sha1, Ae as ZipEncryptedError, je as ZipPasswordError, X as canToggleView, Z as classifyViewerFile, Ie as decryptEKey, Le as decryptQmc, n as ebookKind, Me as extractZipEntry, r as fileExt, te as formatBytes, ne as formatDateTime, re as formatDuration, ie as formatSizeCoarse, i as hljsLang, he as inline, a as isAppxFile, o as isAudioFile, s as isBinaryObjFile, c as isCertFile, l as isCsvFile, J as isDiagramFile, u as isDicomFile, d as isDocxFile, f as isDxfFile, p as isEmlFile, m as isEplFile, h as isFontFile, g as isGeoFile, _ as isHarFile, v as isHprofFile, y as isHtmlFile, b as isImageFile, x as isJavaClassFile, S as isJksFile, C as isJsonlFile, w as isLogFile, T as isLrcFile, E as isMhtFile, D as isMindMapFile, De as isMissingModule, O as isModelFile, k as isMsiFile, A as isNotebookFile, j as isPdfFile, M as isPptxFile, N as isQmcAudioFile, P as isRarFile, F as isRtfFile, I as isSevenZipFile, L as isSqliteFile, R as isStepFile, z as isSubtitleFile, B as isSvgFile, V as isTarballFile, H as isTextFile, U as isVideoFile, W as isXlsxFile, G as isXmindFile, K as isZipFile, Oe as loadOptionalDep, ye as md, be as mdNodes, Q as mediaMimeForName, Re as parseFooter, q as rasterImageKind, Ne as readZip, Y as renderDiagram, ge as renderInline, e as resolveInput, ke as segmentize, Be as sha1, $ as skipsTextLoad, ce as useFileViewer, de as useLightbox, Pe as zipSupported };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe, dependency-free ANSI/ECMA-48 text parser for static console transcripts.
|
|
3
|
+
*
|
|
4
|
+
* Only SGR (Select Graphic Rendition, CSI … m) changes presentation. Other terminal control sequences are
|
|
5
|
+
* consumed without being executed: cursor movement / erase commands have no useful meaning in a static file,
|
|
6
|
+
* while OSC hyperlinks and device-control strings must never become active page content. The result is plain
|
|
7
|
+
* text plus a small whitelist of CSS properties, so callers can render it with normal Vue text nodes.
|
|
8
|
+
*/
|
|
9
|
+
export interface AnsiTextStyle {
|
|
10
|
+
color?: string;
|
|
11
|
+
backgroundColor?: string;
|
|
12
|
+
fontWeight?: '700';
|
|
13
|
+
fontStyle?: 'italic';
|
|
14
|
+
opacity?: number;
|
|
15
|
+
textDecorationLine?: string;
|
|
16
|
+
textDecorationStyle?: 'double';
|
|
17
|
+
visibility?: 'hidden';
|
|
18
|
+
}
|
|
19
|
+
export interface AnsiSegment {
|
|
20
|
+
text: string;
|
|
21
|
+
style?: AnsiTextStyle;
|
|
22
|
+
}
|
|
23
|
+
export interface AnsiLine {
|
|
24
|
+
text: string;
|
|
25
|
+
segments: AnsiSegment[];
|
|
26
|
+
}
|
|
27
|
+
export interface AnsiDocument {
|
|
28
|
+
/** True when at least one ANSI/C1 control sequence was consumed. */
|
|
29
|
+
hasAnsi: boolean;
|
|
30
|
+
/** Control-free text, with CR/LF variants normalized to `\n`. */
|
|
31
|
+
text: string;
|
|
32
|
+
lines: AnsiLine[];
|
|
33
|
+
}
|
|
34
|
+
export interface AnsiRenderPiece extends AnsiSegment {
|
|
35
|
+
marked: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** Fast gate used by the viewers so ordinary large text does not allocate a segment tree. */
|
|
38
|
+
export declare function hasAnsiSequences(text: string): boolean;
|
|
39
|
+
/** Parse ANSI presentation and return only inert text + validated styles. */
|
|
40
|
+
export declare function parseAnsi(text: string): AnsiDocument;
|
|
41
|
+
/** Plain text for search/copy/folding; avoids parsing the overwhelmingly common no-ANSI path. */
|
|
42
|
+
export declare function ansiPlainText(text: string): string;
|
|
43
|
+
/** Split one parsed (or ordinary) line around a case-insensitive search query without losing ANSI styling. */
|
|
44
|
+
export declare function ansiRenderPieces(line: AnsiLine | string, query?: string): AnsiRenderPiece[];
|
package/dist/lib/ansi.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
//#region src/lib/ansi.ts
|
|
2
|
+
var e = "\x1B", t = "", n = "", r = "", i = [
|
|
3
|
+
"var(--ansi-black, #24292f)",
|
|
4
|
+
"var(--ansi-red, #cf222e)",
|
|
5
|
+
"var(--ansi-green, #116329)",
|
|
6
|
+
"var(--ansi-yellow, #9a6700)",
|
|
7
|
+
"var(--ansi-blue, #0969da)",
|
|
8
|
+
"var(--ansi-magenta, #8250df)",
|
|
9
|
+
"var(--ansi-cyan, #1b7c83)",
|
|
10
|
+
"var(--ansi-white, #57606a)",
|
|
11
|
+
"var(--ansi-bright-black, #57606a)",
|
|
12
|
+
"var(--ansi-bright-red, #a40e26)",
|
|
13
|
+
"var(--ansi-bright-green, #1a7f37)",
|
|
14
|
+
"var(--ansi-bright-yellow, #bf8700)",
|
|
15
|
+
"var(--ansi-bright-blue, #218bff)",
|
|
16
|
+
"var(--ansi-bright-magenta, #a475f9)",
|
|
17
|
+
"var(--ansi-bright-cyan, #3192aa)",
|
|
18
|
+
"var(--ansi-bright-white, #6e7781)"
|
|
19
|
+
];
|
|
20
|
+
function a() {
|
|
21
|
+
return {
|
|
22
|
+
foreground: void 0,
|
|
23
|
+
background: void 0,
|
|
24
|
+
bold: !1,
|
|
25
|
+
dim: !1,
|
|
26
|
+
italic: !1,
|
|
27
|
+
underline: !1,
|
|
28
|
+
doubleUnderline: !1,
|
|
29
|
+
strike: !1,
|
|
30
|
+
overline: !1,
|
|
31
|
+
inverse: !1,
|
|
32
|
+
conceal: !1
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function o(e) {
|
|
36
|
+
for (let t = 0; t < e.length; t++) {
|
|
37
|
+
let n = e.charCodeAt(t);
|
|
38
|
+
if (n === 27 || n >= 128 && n <= 159) return !0;
|
|
39
|
+
}
|
|
40
|
+
return !1;
|
|
41
|
+
}
|
|
42
|
+
function s(e) {
|
|
43
|
+
return e !== void 0 && Number.isInteger(e) && e >= 0 && e <= 255;
|
|
44
|
+
}
|
|
45
|
+
function c(e) {
|
|
46
|
+
if (!s(e)) return;
|
|
47
|
+
if (e < 16) return i[e];
|
|
48
|
+
if (e < 232) {
|
|
49
|
+
let t = e - 16, n = [
|
|
50
|
+
0,
|
|
51
|
+
95,
|
|
52
|
+
135,
|
|
53
|
+
175,
|
|
54
|
+
215,
|
|
55
|
+
255
|
|
56
|
+
];
|
|
57
|
+
return `rgb(${n[Math.floor(t / 36)]} ${n[Math.floor(t % 36 / 6)]} ${n[t % 6]})`;
|
|
58
|
+
}
|
|
59
|
+
let t = 8 + (e - 232) * 10;
|
|
60
|
+
return `rgb(${t} ${t} ${t})`;
|
|
61
|
+
}
|
|
62
|
+
function l(e, t, n) {
|
|
63
|
+
return s(e) && s(t) && s(n) ? `rgb(${e} ${t} ${n})` : void 0;
|
|
64
|
+
}
|
|
65
|
+
function u(e) {
|
|
66
|
+
let t = e.foreground, n = e.background;
|
|
67
|
+
if (e.inverse) {
|
|
68
|
+
let e = n ?? "var(--code-bg)";
|
|
69
|
+
n = t ?? "var(--text)", t = e;
|
|
70
|
+
}
|
|
71
|
+
let r = {};
|
|
72
|
+
t && (r.color = t), n && (r.backgroundColor = n), e.bold && (r.fontWeight = "700"), e.italic && (r.fontStyle = "italic"), e.dim && (r.opacity = .65);
|
|
73
|
+
let i = [];
|
|
74
|
+
return (e.underline || e.doubleUnderline) && i.push("underline"), e.strike && i.push("line-through"), e.overline && i.push("overline"), i.length && (r.textDecorationLine = i.join(" ")), e.doubleUnderline && (r.textDecorationStyle = "double"), e.conceal && (r.visibility = "hidden"), Object.keys(r).length ? r : void 0;
|
|
75
|
+
}
|
|
76
|
+
function d(e, t) {
|
|
77
|
+
return e === t ? !0 : !e || !t ? !1 : e.color === t.color && e.backgroundColor === t.backgroundColor && e.fontWeight === t.fontWeight && e.fontStyle === t.fontStyle && e.opacity === t.opacity && e.textDecorationLine === t.textDecorationLine && e.textDecorationStyle === t.textDecorationStyle && e.visibility === t.visibility;
|
|
78
|
+
}
|
|
79
|
+
function f(e, t) {
|
|
80
|
+
e === 0 ? Object.assign(t, a()) : e === 1 ? t.bold = !0 : e === 2 ? t.dim = !0 : e === 3 ? t.italic = !0 : e === 4 ? (t.underline = !0, t.doubleUnderline = !1) : e === 7 ? t.inverse = !0 : e === 8 ? t.conceal = !0 : e === 9 ? t.strike = !0 : e === 21 ? (t.underline = !0, t.doubleUnderline = !0) : e === 22 ? (t.bold = !1, t.dim = !1) : e === 23 ? t.italic = !1 : e === 24 ? (t.underline = !1, t.doubleUnderline = !1) : e === 27 ? t.inverse = !1 : e === 28 ? t.conceal = !1 : e === 29 ? t.strike = !1 : e >= 30 && e <= 37 ? t.foreground = i[e - 30] : e === 39 ? t.foreground = void 0 : e >= 40 && e <= 47 ? t.background = i[e - 40] : e === 49 ? t.background = void 0 : e === 53 ? t.overline = !0 : e === 55 ? t.overline = !1 : e >= 90 && e <= 97 ? t.foreground = i[e - 90 + 8] : e >= 100 && e <= 107 && (t.background = i[e - 100 + 8]);
|
|
81
|
+
}
|
|
82
|
+
function p(e, t) {
|
|
83
|
+
let n = e.split(":"), r = Number(n[0]);
|
|
84
|
+
if (r !== 38 && r !== 48) return !1;
|
|
85
|
+
let i = Number(n[1]), a;
|
|
86
|
+
if (i === 5) a = c(Number(n[n.length - 1]));
|
|
87
|
+
else if (i === 2 && n.length >= 5) {
|
|
88
|
+
let e = n.slice(-3).map(Number);
|
|
89
|
+
a = l(e[0], e[1], e[2]);
|
|
90
|
+
}
|
|
91
|
+
return a && (r === 38 ? t.foreground = a : t.background = a), !0;
|
|
92
|
+
}
|
|
93
|
+
function m(e) {
|
|
94
|
+
if (e === "") return 0;
|
|
95
|
+
if (/^\d+$/.test(e)) return Number(e);
|
|
96
|
+
}
|
|
97
|
+
function h(e, t) {
|
|
98
|
+
let n = e === "" ? ["0"] : e.split(";");
|
|
99
|
+
for (let e = 0; e < n.length; e++) {
|
|
100
|
+
let r = n[e];
|
|
101
|
+
if (r.includes(":")) {
|
|
102
|
+
p(r, t);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
let i = m(r);
|
|
106
|
+
if (i === void 0) continue;
|
|
107
|
+
if (i !== 38 && i !== 48) {
|
|
108
|
+
f(i, t);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
let a = m(n[e + 1] ?? ""), o;
|
|
112
|
+
a === 5 && e + 2 < n.length ? (o = c(m(n[e + 2])), e += 2) : a === 2 && e + 4 < n.length && (o = l(m(n[e + 2]), m(n[e + 3]), m(n[e + 4])), e += 4), o && (i === 38 ? t.foreground = o : t.background = o);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function g(e, t) {
|
|
116
|
+
for (let n = t; n < e.length; n++) {
|
|
117
|
+
let t = e.charCodeAt(n);
|
|
118
|
+
if (t >= 64 && t <= 126) return n;
|
|
119
|
+
}
|
|
120
|
+
return e.length - 1;
|
|
121
|
+
}
|
|
122
|
+
function _(t, n) {
|
|
123
|
+
for (let i = n; i < t.length; i++) {
|
|
124
|
+
if (t[i] === "\x07" || t[i] === r) return i;
|
|
125
|
+
if (t[i] === e && t[i + 1] === "\\") return i + 1;
|
|
126
|
+
}
|
|
127
|
+
return t.length - 1;
|
|
128
|
+
}
|
|
129
|
+
function v(r) {
|
|
130
|
+
let i = a(), o = [], s = [], c = "", l = "", f = !1, p = () => {
|
|
131
|
+
if (!l) return;
|
|
132
|
+
let e = u(i), t = s[s.length - 1];
|
|
133
|
+
t && d(t.style, e) ? t.text += l : s.push({
|
|
134
|
+
text: l,
|
|
135
|
+
style: e
|
|
136
|
+
}), c += l, l = "";
|
|
137
|
+
}, m = () => {
|
|
138
|
+
p(), o.push({
|
|
139
|
+
text: c,
|
|
140
|
+
segments: s
|
|
141
|
+
}), s = [], c = "";
|
|
142
|
+
}, v = 0;
|
|
143
|
+
for (; v < r.length;) {
|
|
144
|
+
let a = r[v], o = r.charCodeAt(v);
|
|
145
|
+
if (a === "\n") {
|
|
146
|
+
m(), v++;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (a === "\r") {
|
|
150
|
+
m(), v += r[v + 1] === "\n" ? 2 : 1;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
let s = a === e && r[v + 1] === "[";
|
|
154
|
+
if (s || a === t) {
|
|
155
|
+
p(), f = !0;
|
|
156
|
+
let e = v + (s ? 2 : 1), t = g(r, e);
|
|
157
|
+
t < r.length && r[t] === "m" && h(r.slice(e, t), i), v = t + 1;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
let c = a === e && (r[v + 1] === "]" || "PX^_".includes(r[v + 1] ?? ""));
|
|
161
|
+
if (c || a === n || o === 144 || o === 152 || o === 158 || o === 159) {
|
|
162
|
+
p(), f = !0, v = _(r, v + (c ? 2 : 1)) + 1;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (a === e) {
|
|
166
|
+
for (p(), f = !0, v++; v < r.length && r.charCodeAt(v) >= 32 && r.charCodeAt(v) <= 47;) v++;
|
|
167
|
+
v < r.length && v++;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (o < 32 && a !== " " || o >= 127 && o <= 159) {
|
|
171
|
+
p(), f = !0, v++;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
l += a, v++;
|
|
175
|
+
}
|
|
176
|
+
return m(), {
|
|
177
|
+
hasAnsi: f,
|
|
178
|
+
text: o.map((e) => e.text).join("\n"),
|
|
179
|
+
lines: o
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function y(e) {
|
|
183
|
+
return o(e) ? v(e).text : e;
|
|
184
|
+
}
|
|
185
|
+
function b(e, t = "") {
|
|
186
|
+
let n = typeof e == "string" ? {
|
|
187
|
+
text: e,
|
|
188
|
+
segments: e ? [{ text: e }] : []
|
|
189
|
+
} : e;
|
|
190
|
+
if (!t) return n.segments.map((e) => ({
|
|
191
|
+
...e,
|
|
192
|
+
marked: !1
|
|
193
|
+
}));
|
|
194
|
+
let r = n.text.toLowerCase(), i = t.toLowerCase();
|
|
195
|
+
if (!i) return n.segments.map((e) => ({
|
|
196
|
+
...e,
|
|
197
|
+
marked: !1
|
|
198
|
+
}));
|
|
199
|
+
let a = [], o = r.indexOf(i);
|
|
200
|
+
for (; o !== -1;) a.push([o, o + t.length]), o = r.indexOf(i, o + t.length);
|
|
201
|
+
if (!a.length) return n.segments.map((e) => ({
|
|
202
|
+
...e,
|
|
203
|
+
marked: !1
|
|
204
|
+
}));
|
|
205
|
+
let s = [], c = 0, l = 0;
|
|
206
|
+
for (let e of n.segments) {
|
|
207
|
+
let t = c, n = c + e.text.length, r = t;
|
|
208
|
+
for (; r < n;) {
|
|
209
|
+
for (; l < a.length && a[l][1] <= r;) l++;
|
|
210
|
+
let i = a[l], o = !!(i && i[0] < n && i[1] > r), c = o ? Math.min(n, i[1]) : Math.min(n, i?.[0] ?? n);
|
|
211
|
+
s.push({
|
|
212
|
+
text: e.text.slice(r - t, c - t),
|
|
213
|
+
style: e.style,
|
|
214
|
+
marked: o
|
|
215
|
+
}), r = c;
|
|
216
|
+
}
|
|
217
|
+
c = n;
|
|
218
|
+
}
|
|
219
|
+
return s;
|
|
220
|
+
}
|
|
221
|
+
//#endregion
|
|
222
|
+
export { y as ansiPlainText, b as ansiRenderPieces, o as hasAnsiSequences, v as parseAnsi };
|
|
223
|
+
|
|
224
|
+
//# sourceMappingURL=ansi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansi.js","names":[],"sources":["../../src/lib/ansi.ts"],"sourcesContent":["/**\n * Safe, dependency-free ANSI/ECMA-48 text parser for static console transcripts.\n *\n * Only SGR (Select Graphic Rendition, CSI … m) changes presentation. Other terminal control sequences are\n * consumed without being executed: cursor movement / erase commands have no useful meaning in a static file,\n * while OSC hyperlinks and device-control strings must never become active page content. The result is plain\n * text plus a small whitelist of CSS properties, so callers can render it with normal Vue text nodes.\n */\n\nexport interface AnsiTextStyle {\n color?: string\n backgroundColor?: string\n fontWeight?: '700'\n fontStyle?: 'italic'\n opacity?: number\n textDecorationLine?: string\n textDecorationStyle?: 'double'\n visibility?: 'hidden'\n}\n\nexport interface AnsiSegment {\n text: string\n style?: AnsiTextStyle\n}\n\nexport interface AnsiLine {\n text: string\n segments: AnsiSegment[]\n}\n\nexport interface AnsiDocument {\n /** True when at least one ANSI/C1 control sequence was consumed. */\n hasAnsi: boolean\n /** Control-free text, with CR/LF variants normalized to `\\n`. */\n text: string\n lines: AnsiLine[]\n}\n\nexport interface AnsiRenderPiece extends AnsiSegment {\n marked: boolean\n}\n\ninterface SgrState {\n foreground?: string\n background?: string\n bold: boolean\n dim: boolean\n italic: boolean\n underline: boolean\n doubleUnderline: boolean\n strike: boolean\n overline: boolean\n inverse: boolean\n conceal: boolean\n}\n\nconst ESC = '\\u001b'\nconst CSI = '\\u009b'\nconst OSC = '\\u009d'\nconst ST = '\\u009c'\n\n// Theme-aware ANSI 0..15 palette. Extended 256-color / truecolor values are emitted as validated rgb().\nconst ANSI_COLORS = [\n 'var(--ansi-black, #24292f)',\n 'var(--ansi-red, #cf222e)',\n 'var(--ansi-green, #116329)',\n 'var(--ansi-yellow, #9a6700)',\n 'var(--ansi-blue, #0969da)',\n 'var(--ansi-magenta, #8250df)',\n 'var(--ansi-cyan, #1b7c83)',\n 'var(--ansi-white, #57606a)',\n 'var(--ansi-bright-black, #57606a)',\n 'var(--ansi-bright-red, #a40e26)',\n 'var(--ansi-bright-green, #1a7f37)',\n 'var(--ansi-bright-yellow, #bf8700)',\n 'var(--ansi-bright-blue, #218bff)',\n 'var(--ansi-bright-magenta, #a475f9)',\n 'var(--ansi-bright-cyan, #3192aa)',\n 'var(--ansi-bright-white, #6e7781)',\n] as const\n\nfunction defaultState(): SgrState {\n return {\n foreground: undefined,\n background: undefined,\n bold: false,\n dim: false,\n italic: false,\n underline: false,\n doubleUnderline: false,\n strike: false,\n overline: false,\n inverse: false,\n conceal: false,\n }\n}\n\n/** Fast gate used by the viewers so ordinary large text does not allocate a segment tree. */\nexport function hasAnsiSequences(text: string): boolean {\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i)\n if (code === 0x1b || (code >= 0x80 && code <= 0x9f)) return true\n }\n return false\n}\n\nfunction byte(value: number | undefined): value is number {\n return value !== undefined && Number.isInteger(value) && value >= 0 && value <= 255\n}\n\nfunction indexedColor(index: number | undefined): string | undefined {\n if (!byte(index)) return undefined\n if (index < 16) return ANSI_COLORS[index]\n if (index < 232) {\n const n = index - 16\n const levels = [0, 95, 135, 175, 215, 255]\n const r = levels[Math.floor(n / 36)]\n const g = levels[Math.floor((n % 36) / 6)]\n const b = levels[n % 6]\n return `rgb(${r} ${g} ${b})`\n }\n const gray = 8 + (index - 232) * 10\n return `rgb(${gray} ${gray} ${gray})`\n}\n\nfunction rgbColor(\n r: number | undefined,\n g: number | undefined,\n b: number | undefined,\n): string | undefined {\n return byte(r) && byte(g) && byte(b) ? `rgb(${r} ${g} ${b})` : undefined\n}\n\nfunction styleFor(state: SgrState): AnsiTextStyle | undefined {\n let foreground = state.foreground\n let background = state.background\n if (state.inverse) {\n const inverseForeground = background ?? 'var(--code-bg)'\n background = foreground ?? 'var(--text)'\n foreground = inverseForeground\n }\n\n const style: AnsiTextStyle = {}\n if (foreground) style.color = foreground\n if (background) style.backgroundColor = background\n if (state.bold) style.fontWeight = '700'\n if (state.italic) style.fontStyle = 'italic'\n if (state.dim) style.opacity = 0.65\n const decorations: string[] = []\n if (state.underline || state.doubleUnderline) decorations.push('underline')\n if (state.strike) decorations.push('line-through')\n if (state.overline) decorations.push('overline')\n if (decorations.length) style.textDecorationLine = decorations.join(' ')\n if (state.doubleUnderline) style.textDecorationStyle = 'double'\n if (state.conceal) style.visibility = 'hidden'\n return Object.keys(style).length ? style : undefined\n}\n\nfunction sameStyle(a: AnsiTextStyle | undefined, b: AnsiTextStyle | undefined): boolean {\n if (a === b) return true\n if (!a || !b) return false\n return (\n a.color === b.color &&\n a.backgroundColor === b.backgroundColor &&\n a.fontWeight === b.fontWeight &&\n a.fontStyle === b.fontStyle &&\n a.opacity === b.opacity &&\n a.textDecorationLine === b.textDecorationLine &&\n a.textDecorationStyle === b.textDecorationStyle &&\n a.visibility === b.visibility\n )\n}\n\nfunction applyBasicSgr(code: number, state: SgrState): void {\n if (code === 0) Object.assign(state, defaultState())\n else if (code === 1) state.bold = true\n else if (code === 2) state.dim = true\n else if (code === 3) state.italic = true\n else if (code === 4) {\n state.underline = true\n state.doubleUnderline = false\n } else if (code === 7) state.inverse = true\n else if (code === 8) state.conceal = true\n else if (code === 9) state.strike = true\n else if (code === 21) {\n state.underline = true\n state.doubleUnderline = true\n } else if (code === 22) {\n state.bold = false\n state.dim = false\n } else if (code === 23) state.italic = false\n else if (code === 24) {\n state.underline = false\n state.doubleUnderline = false\n } else if (code === 27) state.inverse = false\n else if (code === 28) state.conceal = false\n else if (code === 29) state.strike = false\n else if (code >= 30 && code <= 37) state.foreground = ANSI_COLORS[code - 30]\n else if (code === 39) state.foreground = undefined\n else if (code >= 40 && code <= 47) state.background = ANSI_COLORS[code - 40]\n else if (code === 49) state.background = undefined\n else if (code === 53) state.overline = true\n else if (code === 55) state.overline = false\n else if (code >= 90 && code <= 97) state.foreground = ANSI_COLORS[code - 90 + 8]\n else if (code >= 100 && code <= 107) state.background = ANSI_COLORS[code - 100 + 8]\n}\n\nfunction applyColonColor(token: string, state: SgrState): boolean {\n const raw = token.split(':')\n const target = Number(raw[0])\n if (target !== 38 && target !== 48) return false\n const mode = Number(raw[1])\n let color: string | undefined\n if (mode === 5) color = indexedColor(Number(raw[raw.length - 1]))\n else if (mode === 2 && raw.length >= 5) {\n const rgb = raw.slice(-3).map(Number)\n color = rgbColor(rgb[0], rgb[1], rgb[2])\n }\n if (color) {\n if (target === 38) state.foreground = color\n else state.background = color\n }\n return true\n}\n\nfunction sgrNumber(token: string): number | undefined {\n if (token === '') return 0\n if (!/^\\d+$/.test(token)) return undefined\n return Number(token)\n}\n\nfunction applySgr(parameters: string, state: SgrState): void {\n const tokens = parameters === '' ? ['0'] : parameters.split(';')\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i]\n if (token.includes(':')) {\n applyColonColor(token, state)\n continue\n }\n const code = sgrNumber(token)\n if (code === undefined) continue\n if (code !== 38 && code !== 48) {\n applyBasicSgr(code, state)\n continue\n }\n\n const mode = sgrNumber(tokens[i + 1] ?? '')\n let color: string | undefined\n if (mode === 5 && i + 2 < tokens.length) {\n color = indexedColor(sgrNumber(tokens[i + 2]))\n i += 2\n } else if (mode === 2 && i + 4 < tokens.length) {\n color = rgbColor(sgrNumber(tokens[i + 2]), sgrNumber(tokens[i + 3]), sgrNumber(tokens[i + 4]))\n i += 4\n }\n if (color) {\n if (code === 38) state.foreground = color\n else state.background = color\n }\n }\n}\n\nfunction csiEnd(text: string, start: number): number {\n for (let i = start; i < text.length; i++) {\n const code = text.charCodeAt(i)\n if (code >= 0x40 && code <= 0x7e) return i\n }\n return text.length - 1\n}\n\nfunction stringControlEnd(text: string, start: number): number {\n for (let i = start; i < text.length; i++) {\n if (text[i] === '\\u0007' || text[i] === ST) return i\n if (text[i] === ESC && text[i + 1] === '\\\\') return i + 1\n }\n return text.length - 1\n}\n\n/** Parse ANSI presentation and return only inert text + validated styles. */\nexport function parseAnsi(text: string): AnsiDocument {\n const state = defaultState()\n const lines: AnsiLine[] = []\n let segments: AnsiSegment[] = []\n let lineText = ''\n let buffer = ''\n let hasAnsi = false\n\n const flushText = (): void => {\n if (!buffer) return\n const style = styleFor(state)\n const previous = segments[segments.length - 1]\n if (previous && sameStyle(previous.style, style)) previous.text += buffer\n else segments.push({ text: buffer, style })\n lineText += buffer\n buffer = ''\n }\n const finishLine = (): void => {\n flushText()\n lines.push({ text: lineText, segments })\n segments = []\n lineText = ''\n }\n\n let i = 0\n while (i < text.length) {\n const char = text[i]\n const code = text.charCodeAt(i)\n\n if (char === '\\n') {\n finishLine()\n i++\n continue\n }\n if (char === '\\r') {\n finishLine()\n i += text[i + 1] === '\\n' ? 2 : 1\n continue\n }\n\n const isEscCsi = char === ESC && text[i + 1] === '['\n if (isEscCsi || char === CSI) {\n flushText()\n hasAnsi = true\n const bodyStart = i + (isEscCsi ? 2 : 1)\n const end = csiEnd(text, bodyStart)\n if (end < text.length && text[end] === 'm') applySgr(text.slice(bodyStart, end), state)\n i = end + 1\n continue\n }\n\n const isEscString = char === ESC && (text[i + 1] === ']' || 'PX^_'.includes(text[i + 1] ?? ''))\n const isC1String =\n char === OSC || code === 0x90 || code === 0x98 || code === 0x9e || code === 0x9f\n if (isEscString || isC1String) {\n flushText()\n hasAnsi = true\n const bodyStart = i + (isEscString ? 2 : 1)\n i = stringControlEnd(text, bodyStart) + 1\n continue\n }\n\n if (char === ESC) {\n flushText()\n hasAnsi = true\n i++\n // Consume the intermediates and final byte of a non-CSI escape sequence (charset selection, save/restore,\n // keypad mode, and similar commands). A truncated trailing ESC is simply discarded.\n while (i < text.length && text.charCodeAt(i) >= 0x20 && text.charCodeAt(i) <= 0x2f) i++\n if (i < text.length) i++\n continue\n }\n\n if ((code < 0x20 && char !== '\\t') || (code >= 0x7f && code <= 0x9f)) {\n flushText()\n hasAnsi = true\n i++\n continue\n }\n\n buffer += char\n i++\n }\n\n finishLine()\n return { hasAnsi, text: lines.map((line) => line.text).join('\\n'), lines }\n}\n\n/** Plain text for search/copy/folding; avoids parsing the overwhelmingly common no-ANSI path. */\nexport function ansiPlainText(text: string): string {\n return hasAnsiSequences(text) ? parseAnsi(text).text : text\n}\n\n/** Split one parsed (or ordinary) line around a case-insensitive search query without losing ANSI styling. */\nexport function ansiRenderPieces(line: AnsiLine | string, query = ''): AnsiRenderPiece[] {\n const source: AnsiLine =\n typeof line === 'string' ? { text: line, segments: line ? [{ text: line }] : [] } : line\n if (!query) return source.segments.map((segment) => ({ ...segment, marked: false }))\n\n const lower = source.text.toLowerCase()\n const needle = query.toLowerCase()\n if (!needle) return source.segments.map((segment) => ({ ...segment, marked: false }))\n\n const matches: Array<[number, number]> = []\n let found = lower.indexOf(needle)\n while (found !== -1) {\n matches.push([found, found + query.length])\n found = lower.indexOf(needle, found + query.length)\n }\n if (!matches.length) return source.segments.map((segment) => ({ ...segment, marked: false }))\n\n const pieces: AnsiRenderPiece[] = []\n let offset = 0\n let matchIndex = 0\n for (const segment of source.segments) {\n const segmentStart = offset\n const segmentEnd = offset + segment.text.length\n let cursor = segmentStart\n while (cursor < segmentEnd) {\n while (matchIndex < matches.length && matches[matchIndex][1] <= cursor) matchIndex++\n const match = matches[matchIndex]\n const marked = Boolean(match && match[0] < segmentEnd && match[1] > cursor)\n const boundary = marked\n ? Math.min(segmentEnd, match[1])\n : Math.min(segmentEnd, match?.[0] ?? segmentEnd)\n pieces.push({\n text: segment.text.slice(cursor - segmentStart, boundary - segmentStart),\n style: segment.style,\n marked,\n })\n cursor = boundary\n }\n offset = segmentEnd\n }\n return pieces\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Generic, dependency-free reader for OLE2 Compound File Binary Format (MS-CFB / CFBF). */
|
|
2
|
+
export interface CompoundFileEntry {
|
|
3
|
+
/** Raw UTF-16 directory name, excluding its null terminator. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** 1 = storage, 2 = stream, 5 = root storage. */
|
|
6
|
+
type: number;
|
|
7
|
+
start: number;
|
|
8
|
+
size: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class CompoundFileError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Read-only compound-file mini-filesystem. Used by both MSI metadata parsing and DOCX OLE package extraction.
|
|
15
|
+
* Sector chains are bounded and stream reads are clamped to the input so corrupt files cannot loop forever or
|
|
16
|
+
* read outside their supplied ArrayBuffer.
|
|
17
|
+
*/
|
|
18
|
+
export declare class CompoundFile {
|
|
19
|
+
private readonly buffer;
|
|
20
|
+
private readonly sectorSize;
|
|
21
|
+
private readonly maxSectors;
|
|
22
|
+
private readonly miniSectorSize;
|
|
23
|
+
private readonly miniCutoff;
|
|
24
|
+
private readonly fat;
|
|
25
|
+
private readonly miniFat;
|
|
26
|
+
private miniStream;
|
|
27
|
+
readonly entries: CompoundFileEntry[];
|
|
28
|
+
constructor(buffer: ArrayBuffer);
|
|
29
|
+
findStream(name: string): CompoundFileEntry | undefined;
|
|
30
|
+
/** Return one stream's bytes, bounded to its declared size and the input's available sectors. */
|
|
31
|
+
stream(entry: CompoundFileEntry): Uint8Array;
|
|
32
|
+
private sectorOffset;
|
|
33
|
+
private chain;
|
|
34
|
+
private sectorBytes;
|
|
35
|
+
private readFatStream;
|
|
36
|
+
private readMiniStream;
|
|
37
|
+
}
|