@eternalheart/vue-file-preview 1.5.7 → 1.6.0

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.
Files changed (63) hide show
  1. package/README.md +6 -0
  2. package/README.zh-CN.md +6 -0
  3. package/lib/FilePreviewContent.vue.d.ts +4 -1
  4. package/lib/FilePreviewContent.vue.d.ts.map +1 -1
  5. package/lib/FilePreviewEmbed.vue.d.ts +4 -1
  6. package/lib/FilePreviewEmbed.vue.d.ts.map +1 -1
  7. package/lib/FilePreviewModal.vue.d.ts +3 -0
  8. package/lib/FilePreviewModal.vue.d.ts.map +1 -1
  9. package/lib/chunks/{index-BX4Z60kq.mjs → index-2RMNnT0y.mjs} +22 -22
  10. package/lib/chunks/{index-BX4Z60kq.mjs.map → index-2RMNnT0y.mjs.map} +1 -1
  11. package/lib/chunks/{index-zUjR2PO_.mjs → index-B3Bv_Etp.mjs} +14 -14
  12. package/lib/chunks/{index-zUjR2PO_.mjs.map → index-B3Bv_Etp.mjs.map} +1 -1
  13. package/lib/chunks/{index-lfAz_44B.mjs → index-BAbJRSyS.mjs} +2 -2
  14. package/lib/chunks/{index-lfAz_44B.mjs.map → index-BAbJRSyS.mjs.map} +1 -1
  15. package/lib/chunks/{index-DAlOJW1K.mjs → index-BMz5d0Rs.mjs} +12 -12
  16. package/lib/chunks/{index-DAlOJW1K.mjs.map → index-BMz5d0Rs.mjs.map} +1 -1
  17. package/lib/chunks/{index-B81eS8ZU.mjs → index-C-ikNsDh.mjs} +2 -2
  18. package/lib/chunks/{index-B81eS8ZU.mjs.map → index-C-ikNsDh.mjs.map} +1 -1
  19. package/lib/chunks/index-C1Ev7K-W.mjs +265 -0
  20. package/lib/chunks/index-C1Ev7K-W.mjs.map +1 -0
  21. package/lib/chunks/{index-D3HEYT2-.mjs → index-CKKL3xiq.mjs} +24 -24
  22. package/lib/chunks/{index-D3HEYT2-.mjs.map → index-CKKL3xiq.mjs.map} +1 -1
  23. package/lib/chunks/{index-C6rL8w0j.mjs → index-CLDPeQbI.mjs} +7 -7
  24. package/lib/chunks/{index-C6rL8w0j.mjs.map → index-CLDPeQbI.mjs.map} +1 -1
  25. package/lib/chunks/{index-Cr5BqQ4w.mjs → index-CdUSfYfF.mjs} +19 -19
  26. package/lib/chunks/{index-Cr5BqQ4w.mjs.map → index-CdUSfYfF.mjs.map} +1 -1
  27. package/lib/chunks/{index-CCelprzZ.mjs → index-Cl9ZiWVl.mjs} +2 -2
  28. package/lib/chunks/{index-CCelprzZ.mjs.map → index-Cl9ZiWVl.mjs.map} +1 -1
  29. package/lib/chunks/{index-DxvfLZT4.mjs → index-Cy83gsDL.mjs} +49 -49
  30. package/lib/chunks/{index-DxvfLZT4.mjs.map → index-Cy83gsDL.mjs.map} +1 -1
  31. package/lib/chunks/{index-DrKqRTg_.mjs → index-D-YwSyrE.mjs} +24 -24
  32. package/lib/chunks/{index-DrKqRTg_.mjs.map → index-D-YwSyrE.mjs.map} +1 -1
  33. package/lib/chunks/{index-7qDT5hbP.mjs → index-DD9QZ4a2.mjs} +10 -10
  34. package/lib/chunks/{index-7qDT5hbP.mjs.map → index-DD9QZ4a2.mjs.map} +1 -1
  35. package/lib/chunks/{index-DezIRCWU.mjs → index-DL3qn-zG.mjs} +2 -2
  36. package/lib/chunks/{index-DezIRCWU.mjs.map → index-DL3qn-zG.mjs.map} +1 -1
  37. package/lib/chunks/{index-C7YsVakC.mjs → index-DcLACobl.mjs} +9 -9
  38. package/lib/chunks/{index-C7YsVakC.mjs.map → index-DcLACobl.mjs.map} +1 -1
  39. package/lib/chunks/{index-Bfj4Hl_r.mjs → index-Dcruruhk.mjs} +2 -2
  40. package/lib/chunks/{index-Bfj4Hl_r.mjs.map → index-Dcruruhk.mjs.map} +1 -1
  41. package/lib/chunks/{index-CkUaOFQc.mjs → index-Dqqq0VnB.mjs} +2 -2
  42. package/lib/chunks/{index-CkUaOFQc.mjs.map → index-Dqqq0VnB.mjs.map} +1 -1
  43. package/lib/chunks/{index-Vj1-8fIZ.mjs → index-DxSw5Ekp.mjs} +2 -2
  44. package/lib/chunks/{index-Vj1-8fIZ.mjs.map → index-DxSw5Ekp.mjs.map} +1 -1
  45. package/lib/chunks/{index-DOyDC7Qw.mjs → index-EPkoXaAV.mjs} +2 -2
  46. package/lib/chunks/{index-DOyDC7Qw.mjs.map → index-EPkoXaAV.mjs.map} +1 -1
  47. package/lib/chunks/{index-B8AUVu3R.mjs → index-M_Nf3MY5.mjs} +377 -326
  48. package/lib/chunks/index-M_Nf3MY5.mjs.map +1 -0
  49. package/lib/chunks/{useShikiHighlight-CZ3m7eHx.mjs → useShikiHighlight-CIk_v_UB.mjs} +2 -2
  50. package/lib/chunks/{useShikiHighlight-CZ3m7eHx.mjs.map → useShikiHighlight-CIk_v_UB.mjs.map} +1 -1
  51. package/lib/index.cjs +45 -45
  52. package/lib/index.cjs.map +1 -1
  53. package/lib/index.css +1 -1
  54. package/lib/index.mjs +2 -2
  55. package/lib/renderers/Cad/index.vue.d.ts +11 -0
  56. package/lib/renderers/Cad/index.vue.d.ts.map +1 -0
  57. package/lib/renderers/Cad/toolbar.d.ts +16 -0
  58. package/lib/renderers/Cad/toolbar.d.ts.map +1 -0
  59. package/lib/renderers/lazy.d.ts +1 -0
  60. package/lib/renderers/lazy.d.ts.map +1 -1
  61. package/lib/renderers/registry.d.ts.map +1 -1
  62. package/package.json +4 -1
  63. package/lib/chunks/index-B8AUVu3R.mjs.map +0 -1
package/README.md CHANGED
@@ -271,6 +271,10 @@ Differences from `FilePreviewModal`:
271
271
  - **Formats**: TTF, OTF, WOFF, WOFF2
272
272
  - **Features**: Font metadata (family, designer, version), character set preview, custom text input, multi-size display
273
273
 
274
+ ### CAD / 3D Models
275
+ - **Formats**: DXF, STL, OBJ, GLTF, GLB
276
+ - **Features**: Interactive 3D viewer with orbit/zoom/pan controls, wireframe/solid toggle, grid & axes display, auto-centering
277
+
274
278
  ### Code & Text
275
279
  - **Markdown**: GitHub Flavored Markdown, code highlighting
276
280
  - **Code Files**: JS, TS, Python, Java, C++, Go, Rust, and 40+ languages
@@ -360,6 +364,7 @@ Differences from `FilePreviewModal`:
360
364
  | `headless` | `boolean` | ❌ | Headless mode — hides toolbar and navigation arrows |
361
365
  | `theme` | `Theme` | ❌ | Theme mode: `'auto' \| 'dark' \| 'light'` (default `'dark'`) |
362
366
  | `showDownload` | `boolean` | ❌ | Whether to show the download button (default `true`) |
367
+ | `showClose` | `boolean` | ❌ | Whether to show the close button (default `true` for modal) |
363
368
 
364
369
  ### FilePreviewModal Events
365
370
 
@@ -382,6 +387,7 @@ Differences from `FilePreviewModal`:
382
387
  | `headless` | `boolean` | ❌ | `false` | Headless mode — hides toolbar and navigation arrows |
383
388
  | `theme` | `Theme` | ❌ | `'dark'` | Theme mode: `'auto' \| 'dark' \| 'light'` |
384
389
  | `showDownload` | `boolean` | ❌ | `true` | Whether to show the download button |
390
+ | `showClose` | `boolean` | ❌ | `false` | Whether to show the close button (default `false` for embed) |
385
391
 
386
392
  ### FilePreviewEmbed Events
387
393
 
package/README.zh-CN.md CHANGED
@@ -271,6 +271,10 @@ const files = [
271
271
  - **格式**: TTF, OTF, WOFF, WOFF2
272
272
  - **功能**: 字体元数据(字体家族、设计师、版本)、字符集预览、自定义文本输入、多字号展示
273
273
 
274
+ ### CAD / 3D 模型
275
+ - **格式**: DXF, STL, OBJ, GLTF, GLB
276
+ - **功能**: 交互式 3D 查看器(旋转/缩放/平移)、线框/实体切换、网格与坐标轴显示、自动居中
277
+
274
278
  ### 代码 & 文本
275
279
  - **Markdown**: GitHub Flavored Markdown,代码高亮
276
280
  - **代码文件**: JS, TS, Python, Java, C++, Go, Rust 等 40+ 种语言
@@ -360,6 +364,7 @@ const files = [
360
364
  | `headless` | `boolean` | ❌ | 无头模式,隐藏工具栏和导航箭头 |
361
365
  | `theme` | `Theme` | ❌ | 主题模式: `'auto' \| 'dark' \| 'light'`(默认 `'dark'`) |
362
366
  | `showDownload` | `boolean` | ❌ | 是否显示下载按钮(默认 `true`) |
367
+ | `showClose` | `boolean` | ❌ | 是否显示关闭按钮(modal 模式默认 `true`) |
363
368
 
364
369
  ### FilePreviewModal 事件
365
370
 
@@ -382,6 +387,7 @@ const files = [
382
387
  | `headless` | `boolean` | ❌ | `false` | 无头模式,隐藏工具栏和导航箭头 |
383
388
  | `theme` | `Theme` | ❌ | `'dark'` | 主题模式: `'auto' \| 'dark' \| 'light'` |
384
389
  | `showDownload` | `boolean` | ❌ | `true` | 是否显示下载按钮 |
390
+ | `showClose` | `boolean` | ❌ | `false` | 是否显示关闭按钮(embed 模式默认 `false`) |
385
391
 
386
392
  ### FilePreviewEmbed 事件
387
393
 
@@ -24,8 +24,10 @@ interface Props {
24
24
  shouldFetchAsBlob?: ShouldFetchAsBlob;
25
25
  /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
26
26
  onDownload?: (file: PreviewFile) => void | Promise<void>;
27
- /** 关闭回调:传入后工具栏显示关闭按钮 */
27
+ /** 关闭回调 */
28
28
  onClose?: () => void;
29
+ /** 是否显示关闭按钮,默认根据 mode 决定(modal: true, embed: false) */
30
+ showClose?: boolean;
29
31
  /** 是否显示下载按钮,默认 true */
30
32
  showDownload?: boolean;
31
33
  }
@@ -50,6 +52,7 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
50
52
  headless: boolean;
51
53
  shouldFetchAsBlob: ShouldFetchAsBlob;
52
54
  onDownload: (file: PreviewFile) => void | Promise<void>;
55
+ showClose: boolean;
53
56
  showDownload: boolean;
54
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
55
58
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"FilePreviewContent.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewContent.vue"],"names":[],"mappings":"AA8jBA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,SAAS,CAAC;AAarE,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,kCAAkC;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;;;;;;;;;iBAXe,kBAAkB;oBAEf,cAAc;UAdxB,OAAO,GAAG,OAAO;aAoBd,MAAM,IAAI;WAVZ,KAAK;qBAZK,cAAc,EAAE;qBAIhB,MAAM;YAEf,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;kBAIzC,OAAO;;AAwtBxB,wBAQG"}
1
+ {"version":3,"file":"FilePreviewContent.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewContent.vue"],"names":[],"mappings":"AAokBA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,SAAS,CAAC;AAarE,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,kCAAkC;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,WAAW;IACX,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;;;;;;;;;iBAbe,kBAAkB;oBAEf,cAAc;UAdxB,OAAO,GAAG,OAAO;aAoBd,MAAM,IAAI;WAVZ,KAAK;qBAZK,cAAc,EAAE;qBAIhB,MAAM;YAEf,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;eAI5C,OAAO;kBAEJ,OAAO;;AA8tBxB,wBAQG"}
@@ -24,8 +24,10 @@ interface Props {
24
24
  shouldFetchAsBlob?: ShouldFetchAsBlob;
25
25
  /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
26
26
  onDownload?: (file: PreviewFile) => void | Promise<void>;
27
- /** 关闭回调:传入后工具栏显示关闭按钮 */
27
+ /** 关闭回调 */
28
28
  onClose?: () => void;
29
+ /** 是否显示关闭按钮,默认根据 mode 决定(embed: false) */
30
+ showClose?: boolean;
29
31
  /** 是否显示下载按钮,默认 true */
30
32
  showDownload?: boolean;
31
33
  }
@@ -51,6 +53,7 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
51
53
  headless: boolean;
52
54
  shouldFetchAsBlob: ShouldFetchAsBlob;
53
55
  onDownload: (file: PreviewFile) => void | Promise<void>;
56
+ showClose: boolean;
54
57
  showDownload: boolean;
55
58
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
56
59
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"FilePreviewEmbed.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewEmbed.vue"],"names":[],"mappings":"AAgIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACjM,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;;;;;;;;;iBAXe,kBAAkB;oBAEf,cAAc;YAZtB,MAAM,GAAG,MAAM;WAFhB,MAAM,GAAG,MAAM;aAoBb,MAAM,IAAI;WAVZ,KAAK;kBAbE,MAAM;qBACH,cAAc,EAAE;YAMzB,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;kBAIzC,OAAO;;AAmLxB,wBAQG"}
1
+ {"version":3,"file":"FilePreviewEmbed.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewEmbed.vue"],"names":[],"mappings":"AAoIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACjM,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,WAAW;IACX,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;;;;;;;;;iBAbe,kBAAkB;oBAEf,cAAc;YAZtB,MAAM,GAAG,MAAM;WAFhB,MAAM,GAAG,MAAM;aAoBb,MAAM,IAAI;WAVZ,KAAK;kBAbE,MAAM;qBACH,cAAc,EAAE;YAMzB,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;eAI5C,OAAO;kBAEJ,OAAO;;AAuLxB,wBAQG"}
@@ -21,6 +21,8 @@ interface Props {
21
21
  shouldFetchAsBlob?: ShouldFetchAsBlob;
22
22
  /** 自定义下载回调;不传时库内默认通过 fetcher 拉 Blob 触发下载 */
23
23
  onDownload?: (file: PreviewFile) => void | Promise<void>;
24
+ /** 是否显示关闭按钮,默认根据 mode 决定(modal: true) */
25
+ showClose?: boolean;
24
26
  /** 是否显示下载按钮,默认 true */
25
27
  showDownload?: boolean;
26
28
  }
@@ -42,6 +44,7 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
42
44
  headless: boolean;
43
45
  shouldFetchAsBlob: ShouldFetchAsBlob;
44
46
  onDownload: (file: PreviewFile) => void | Promise<void>;
47
+ showClose: boolean;
45
48
  showDownload: boolean;
46
49
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
47
50
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"FilePreviewModal.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewModal.vue"],"names":[],"mappings":"AAyIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACjM,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9C,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;;;;;;;;;iBATe,kBAAkB;oBAEf,cAAc;WAJvB,KAAK;qBARK,cAAc,EAAE;YAEzB,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;kBAEzC,OAAO;;AA6NxB,wBAQG"}
1
+ {"version":3,"file":"FilePreviewModal.vue.d.ts","sourceRoot":"","sources":["../src/FilePreviewModal.vue"],"names":[],"mappings":"AA6IA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACjM,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9C,UAAU,KAAK;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,SAAS;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,yCAAyC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;;;;;;;;;iBAXe,kBAAkB;oBAEf,cAAc;WAJvB,KAAK;qBARK,cAAc,EAAE;YAEzB,MAAM;cAEJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;cAE1C,OAAO;uBAQE,iBAAiB;gBAExB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;eAE5C,OAAO;kBAEJ,OAAO;;AAiOxB,wBAQG"}
@@ -1,6 +1,6 @@
1
- import { defineComponent as Me, ref as s, watch as H, onBeforeUnmount as ee, onMounted as _e, computed as te, openBlock as x, createElementBlock as C, normalizeStyle as ae, createVNode as Re, unref as le, createElementVNode as X, createTextVNode as Le, toDisplayString as S, createCommentVNode as L, createBlock as oe, normalizeClass as ke } from "vue";
1
+ import { defineComponent as Me, ref as i, watch as H, onBeforeUnmount as ee, onMounted as _e, computed as te, openBlock as x, createElementBlock as C, normalizeStyle as ae, createVNode as Re, unref as le, createElementVNode as X, createTextVNode as Le, toDisplayString as S, createCommentVNode as L, createBlock as oe, normalizeClass as ke } from "vue";
2
2
  import { ZoomOut as Ee, ZoomIn as Ce, Scan as Te, Maximize2 as Ue, RotateCcw as Ye, RotateCw as ze, RefreshCw as Se, Loader2 as Xe } from "lucide-vue-next";
3
- import { u as De, n as We, o as Be, N as Oe } from "./index-B8AUVu3R.mjs";
3
+ import { u as De, i as We, n as Be, N as Oe } from "./index-M_Nf3MY5.mjs";
4
4
  import { _ as ne } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
5
5
  import { T as je } from "./base.types-DaftHyg7.mjs";
6
6
  const Pe = {
@@ -22,13 +22,13 @@ const Pe = {
22
22
  fileSize: {},
23
23
  file: {}
24
24
  },
25
- setup(se, { expose: ie }) {
26
- const f = se, V = new je(), { t: m } = De(), i = s(1), k = s(0), E = s(!1), w = s(null), d = s(!1), D = s(0), M = s(null), _ = s(""), R = s(1), T = s(1), F = s(!1), o = s({ x: 0, y: 0 }), g = s(!1);
25
+ setup(ie, { expose: se }) {
26
+ const f = ie, V = new je(), { t: m } = De(), s = i(1), k = i(0), E = i(!1), w = i(null), d = i(!1), D = i(0), M = i(null), _ = i(""), R = i(1), T = i(1), F = i(!1), o = i({ x: 0, y: 0 }), g = i(!1);
27
27
  let U = { x: 0, y: 0 };
28
- const h = s(1), r = s({ width: 0, height: 0 });
29
- H([i, k], () => {
28
+ const h = i(1), r = i({ width: 0, height: 0 });
29
+ H([s, k], () => {
30
30
  V.notify();
31
- }), ie({
31
+ }), se({
32
32
  getToolbarGroups: () => [
33
33
  {
34
34
  items: [
@@ -37,11 +37,11 @@ const Pe = {
37
37
  icon: Ee,
38
38
  tooltip: m.value("toolbar.zoom_out"),
39
39
  action: ce,
40
- disabled: i.value <= 0.01
40
+ disabled: s.value <= 0.01
41
41
  },
42
42
  {
43
43
  type: "text",
44
- content: `${Math.round(i.value * 100)}%`,
44
+ content: `${Math.round(s.value * 100)}%`,
45
45
  minWidth: "3rem"
46
46
  },
47
47
  {
@@ -49,7 +49,7 @@ const Pe = {
49
49
  icon: Ce,
50
50
  tooltip: m.value("toolbar.zoom_in"),
51
51
  action: ue,
52
- disabled: i.value >= 10
52
+ disabled: s.value >= 10
53
53
  }
54
54
  ]
55
55
  },
@@ -99,30 +99,30 @@ const Pe = {
99
99
  onToolbarChange: (e) => V.subscribe(e)
100
100
  });
101
101
  const ue = () => {
102
- i.value = Math.min(i.value + 0.1, 10);
102
+ s.value = Math.min(s.value + 0.1, 10);
103
103
  }, ce = () => {
104
- i.value = Math.max(i.value - 0.1, 0.01);
104
+ s.value = Math.max(s.value - 0.1, 0.01);
105
105
  }, re = () => {
106
106
  k.value = (k.value + 90) % 360;
107
107
  }, ve = () => {
108
108
  k.value = (k.value - 90 + 360) % 360;
109
109
  }, fe = () => {
110
- i.value = 1, k.value = 0, o.value = { x: 0, y: 0 };
110
+ s.value = 1, k.value = 0, o.value = { x: 0, y: 0 };
111
111
  }, de = () => {
112
112
  G();
113
113
  }, G = () => {
114
114
  if (v.value && r.value.width > 0 && r.value.height > 0) {
115
115
  const e = v.value.clientWidth, t = v.value.clientHeight, a = e / r.value.width, u = t / r.value.height;
116
- i.value = Math.max(0.01, Math.min(10, Math.min(a, u))), o.value = { x: 0, y: 0 };
116
+ s.value = Math.max(0.01, Math.min(10, Math.min(a, u))), o.value = { x: 0, y: 0 };
117
117
  }
118
- }, he = s(null), v = s(null);
118
+ }, he = i(null), v = i(null);
119
119
  let Y = null, W = null, B = null;
120
120
  const p = /* @__PURE__ */ new Map();
121
121
  let O = !1, j = 0, I = 1, Z = { x: 0, y: 0 }, A = 0;
122
122
  H(
123
123
  () => [f.url, f.file],
124
124
  async () => {
125
- if (_.value = "", E.value = !1, w.value = null, d.value = !1, M.value = null, D.value = 0, o.value = { x: 0, y: 0 }, h.value = 1, i.value = 1, R.value = 1, T.value = 1, F.value = !1, Y && (URL.revokeObjectURL(Y), Y = null), p.forEach((e) => URL.revokeObjectURL(e)), p.clear(), W = null, B = null, !f.file) {
125
+ if (_.value = "", E.value = !1, w.value = null, d.value = !1, M.value = null, D.value = 0, o.value = { x: 0, y: 0 }, h.value = 1, s.value = 1, R.value = 1, T.value = 1, F.value = !1, Y && (URL.revokeObjectURL(Y), Y = null), p.forEach((e) => URL.revokeObjectURL(e)), p.clear(), W = null, B = null, !f.file) {
126
126
  _.value = f.url;
127
127
  return;
128
128
  }
@@ -187,10 +187,10 @@ const Pe = {
187
187
  Y && URL.revokeObjectURL(Y), p.forEach((t) => URL.revokeObjectURL(t)), p.clear();
188
188
  const e = v.value;
189
189
  e && e.removeEventListener("wheel", N);
190
- }), H(i, (e) => {
190
+ }), H(s, (e) => {
191
191
  h.value = e;
192
192
  }), H(h, (e) => {
193
- i.value = e;
193
+ s.value = e;
194
194
  });
195
195
  const P = (e, t) => {
196
196
  const a = v.value;
@@ -205,12 +205,12 @@ const Pe = {
205
205
  const t = e.currentTarget;
206
206
  if (r.value = { width: t.naturalWidth, height: t.naturalHeight }, v.value && r.value.width > 0 && r.value.height > 0) {
207
207
  const a = v.value.clientWidth, u = v.value.clientHeight, n = a / r.value.width, c = u / r.value.height, l = Math.min(n, c);
208
- i.value = Math.max(0.01, Math.min(10, l)), o.value = { x: 0, y: 0 };
208
+ s.value = Math.max(0.01, Math.min(10, l)), o.value = { x: 0, y: 0 };
209
209
  }
210
210
  }, me = () => {
211
211
  w.value = m.value("image.load_failed"), E.value = !0;
212
212
  }, ge = () => {
213
- o.value = { x: 0, y: 0 }, i.value = 1;
213
+ o.value = { x: 0, y: 0 }, s.value = 1;
214
214
  }, N = (e) => {
215
215
  e.preventDefault(), e.stopPropagation();
216
216
  const t = v.value;
@@ -255,7 +255,7 @@ const Pe = {
255
255
  y: t[0].clientY - o.value.y
256
256
  };
257
257
  const a = Date.now();
258
- a - A < 300 && (o.value = { x: 0, y: 0 }, i.value = 1), A = a;
258
+ a - A < 300 && (o.value = { x: 0, y: 0 }, s.value = 1), A = a;
259
259
  } else t.length === 2 && (g.value = !1, j = Math.hypot(
260
260
  t[1].clientX - t[0].clientX,
261
261
  t[1].clientY - t[0].clientY
@@ -360,4 +360,4 @@ const Pe = {
360
360
  export {
361
361
  at as default
362
362
  };
363
- //# sourceMappingURL=index-BX4Z60kq.mjs.map
363
+ //# sourceMappingURL=index-2RMNnT0y.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-BX4Z60kq.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { Loader2, ZoomIn, ZoomOut, RotateCw, RotateCcw, Scan, RefreshCw, Maximize2 } from 'lucide-vue-next';\nimport { formatFileSize, detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\nimport { ToolbarEventEmitter } from '../base.types';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nconst props = defineProps<{\n url: string;\n fileSize?: number;\n file?: PreviewFile | File;\n}>();\n\nconst emitter = new ToolbarEventEmitter();\n\nconst { t } = useTranslator();\n\n// 内部状态管理\nconst zoom = ref(1);\nconst rotation = ref(0);\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst decoding = ref(false);\nconst decodeProgress = ref(0);\nconst decodeError = ref<string | null>(null);\nconst imageSrc = ref<string>('');\nconst currentPage = ref(1);\nconst totalPages = ref(1);\nconst isRawThumbnail = ref(false);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\n// 通知工具栏变化\nwatch([zoom, rotation], () => {\n emitter.notify();\n});\n\n// 工具栏配置(对齐 React 的 4 个按钮组)\nconst getToolbarGroups = (): ToolbarGroup[] => [\n {\n items: [\n {\n type: 'button',\n icon: ZoomOut,\n tooltip: t.value('toolbar.zoom_out'),\n action: handleZoomOut,\n disabled: zoom.value <= 0.01,\n },\n {\n type: 'text',\n content: `${Math.round(zoom.value * 100)}%`,\n minWidth: '3rem',\n },\n {\n type: 'button',\n icon: ZoomIn,\n tooltip: t.value('toolbar.zoom_in'),\n action: handleZoomIn,\n disabled: zoom.value >= 10,\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: Scan,\n tooltip: t.value('toolbar.fit_to_window'),\n action: handleFitToWidth,\n },\n {\n type: 'button',\n icon: Maximize2,\n tooltip: t.value('toolbar.original_size'),\n action: handleOriginalSize,\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: RotateCcw,\n tooltip: t.value('toolbar.rotate_left'),\n action: handleRotateLeft,\n },\n {\n type: 'button',\n icon: RotateCw,\n tooltip: t.value('toolbar.rotate_right'),\n action: handleRotateRight,\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: RefreshCw,\n tooltip: t.value('toolbar.reset'),\n action: handleReset,\n },\n ],\n },\n];\n\n// 暴露接口\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n onToolbarChange: (listener) => emitter.subscribe(listener),\n});\n\n// 工具栏操作\nconst handleZoomIn = () => {\n zoom.value = Math.min(zoom.value + 0.1, 10);\n};\n\nconst handleZoomOut = () => {\n zoom.value = Math.max(zoom.value - 0.1, 0.01);\n};\n\nconst handleRotateRight = () => {\n rotation.value = (rotation.value + 90) % 360;\n};\n\nconst handleRotateLeft = () => {\n rotation.value = (rotation.value - 90 + 360) % 360;\n};\n\nconst handleOriginalSize = () => {\n zoom.value = 1;\n rotation.value = 0;\n position.value = { x: 0, y: 0 };\n};\n\nconst handleReset = () => {\n handleFitToWidth();\n};\n\nconst handleFitToWidth = () => {\n if (containerRef.value && naturalSize.value.width > 0 && naturalSize.value.height > 0) {\n const containerWidth = containerRef.value.clientWidth;\n const containerHeight = containerRef.value.clientHeight;\n const scaleX = containerWidth / naturalSize.value.width;\n const scaleY = containerHeight / naturalSize.value.height;\n zoom.value = Math.max(0.01, Math.min(10, Math.min(scaleX, scaleY)));\n position.value = { x: 0, y: 0 };\n }\n};\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet blobUrl: string | null = null;\nlet fileBlobCache: Blob | null = null;\nlet loaderCache: any = null;\nconst pageCache = new Map<number, string>();\n\nlet isTouchDevice = false;\nlet touchStartDistance = 0;\nlet touchStartZoom = 1;\nlet touchStartPos = { x: 0, y: 0 };\nlet lastTapTime = 0;\n\n// 解码逻辑\nwatch(\n () => [props.url, props.file] as const,\n async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n imageSrc.value = '';\n loaded.value = false;\n error.value = null;\n decoding.value = false;\n decodeError.value = null;\n decodeProgress.value = 0;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n zoom.value = 1;\n currentPage.value = 1;\n totalPages.value = 1;\n isRawThumbnail.value = false;\n\n // 清理旧的 blob URL 与缓存\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n fileBlobCache = null;\n loaderCache = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!props.file) {\n imageSrc.value = props.url;\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(props.file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n imageSrc.value = props.url;\n return;\n }\n\n // 需要解码\n decoding.value = true;\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (props.file instanceof Blob) {\n fileBlob = props.file;\n } else {\n const response = await fetch(props.url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n // 缓存 Blob 与 loader\n fileBlobCache = fileBlob;\n loaderCache = loader;\n\n // 标记 RAW 缩略图模式\n const isRaw = mimeType.startsWith('image/x-');\n if (isRaw) {\n isRawThumbnail.value = true;\n }\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (metadata.pageCount && metadata.pageCount > 1) {\n totalPages.value = metadata.pageCount;\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n decodeProgress.value = percent;\n },\n });\n\n // 生成 blob URL\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrl = url;\n pageCache.set(1, url);\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '解码失败';\n decoding.value = false;\n }\n },\n { immediate: true }\n);\n\n// 多页 TIFF 翻页\nconst handlePageChange = async (page: number) => {\n if (!fileBlobCache || !loaderCache) return;\n if (page < 1 || page > totalPages.value) return;\n\n // 命中缓存:直接切换\n const cached = pageCache.get(page);\n if (cached) {\n currentPage.value = page;\n imageSrc.value = cached;\n return;\n }\n\n // 解码新页面\n decoding.value = true;\n try {\n const decodedBlob = await loaderCache.decode(fileBlobCache, { page });\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCache.size >= 10) {\n const firstKey = pageCache.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCache.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCache.delete(firstKey);\n }\n }\n\n pageCache.set(page, url);\n currentPage.value = page;\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '翻页解码失败';\n decoding.value = false;\n }\n};\n\n// Cleanup on unmount\nonBeforeUnmount(() => {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\n// 同步 zoom 和 internalZoom\nwatch(zoom, (z) => {\n internalZoom.value = z;\n});\n\nwatch(internalZoom, (z) => {\n zoom.value = z;\n});\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n\n // 自动适应窗口\n if (containerRef.value && naturalSize.value.width > 0 && naturalSize.value.height > 0) {\n const containerWidth = containerRef.value.clientWidth;\n const containerHeight = containerRef.value.clientHeight;\n const scaleX = containerWidth / naturalSize.value.width;\n const scaleY = containerHeight / naturalSize.value.height;\n const newZoom = Math.min(scaleX, scaleY);\n zoom.value = Math.max(0.01, Math.min(10, newZoom));\n position.value = { x: 0, y: 0 };\n }\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n zoom.value = 1;\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n container.addEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n container.removeEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n if (isTouchDevice) return;\n isDragging.value = false;\n};\n\n// 触屏事件处理\nconst handleTouchStart = (e: TouchEvent) => {\n isTouchDevice = true;\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1) {\n // 单指拖拽\n isDragging.value = true;\n dragStart = {\n x: touches[0].clientX - position.value.x,\n y: touches[0].clientY - position.value.y,\n };\n\n // 双击检测\n const now = Date.now();\n if (now - lastTapTime < 300) {\n // 双击复原:居中 + 缩放100%\n position.value = { x: 0, y: 0 };\n zoom.value = 1;\n }\n lastTapTime = now;\n } else if (touches.length === 2) {\n // 双指缩放初始化\n isDragging.value = false;\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n touchStartDistance = distance;\n touchStartZoom = internalZoom.value;\n touchStartPos = { ...position.value };\n }\n};\n\nconst handleTouchMove = (e: TouchEvent) => {\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1 && isDragging.value) {\n // 单指拖拽\n position.value = clampPosition(\n {\n x: touches[0].clientX - dragStart.x,\n y: touches[0].clientY - dragStart.y,\n },\n internalZoom.value\n );\n } else if (touches.length === 2) {\n // 双指缩放\n const container = containerRef.value;\n if (!container) return;\n\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n\n // 最小距离变化阈值,防止抖动\n if (Math.abs(distance - touchStartDistance) < 5) return;\n\n const scale = distance / touchStartDistance;\n const newZoom = Math.max(0.01, Math.min(10, touchStartZoom * scale));\n\n // 双指中心点作为缩放原点\n const rect = container.getBoundingClientRect();\n const centerX = (touches[0].clientX + touches[1].clientX) / 2 - rect.left - rect.width / 2;\n const centerY = (touches[0].clientY + touches[1].clientY) / 2 - rect.top - rect.height / 2;\n\n const zoomScale = newZoom / internalZoom.value;\n position.value = clampPosition(\n {\n x: centerX - zoomScale * (centerX - touchStartPos.x),\n y: centerY - zoomScale * (centerY - touchStartPos.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n }\n};\n\nconst handleTouchEnd = () => {\n isDragging.value = false;\n touchStartDistance = 0;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${rotation.value}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value && !error.value && !decodeError.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab', touchAction: 'none' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <!-- 解码中 -->\n <div\n v-if=\"decoding\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10\"\n >\n <Loader2 class=\"vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin\" />\n <p class=\"vfp-mt-4 vfp-text-fg-secondary\">\n 正在解码... <span v-if=\"decodeProgress > 0\">{{ Math.round(decodeProgress) }}%</span>\n </p>\n </div>\n\n <!-- 解码错误 -->\n <RendererError v-if=\"decodeError\" :message=\"t('image.decode_failed')\" :detail=\"decodeError\" />\n\n <div v-if=\"!loaded && !error && !decoding && !decodeError\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <img\n v-if=\"imageSrc\"\n ref=\"imgRef\"\n :src=\"imageSrc\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', (!loaded || error || decodeError) && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n\n <!-- 多页 TIFF 翻页器 -->\n <div\n v-if=\"totalPages > 1\"\n class=\"vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md\"\n >\n <button\n type=\"button\"\n :disabled=\"currentPage <= 1 || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage - 1)\"\n >\n 上一页\n </button>\n <span class=\"vfp-text-fg-secondary vfp-tabular-nums\">\n {{ currentPage }} / {{ totalPages }}\n </span>\n <button\n type=\"button\"\n :disabled=\"currentPage >= totalPages || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage + 1)\"\n >\n 下一页\n </button>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emitter","ToolbarEventEmitter","t","useTranslator","zoom","ref","rotation","loaded","error","decoding","decodeProgress","decodeError","imageSrc","currentPage","totalPages","isRawThumbnail","position","isDragging","dragStart","internalZoom","naturalSize","watch","__expose","ZoomOut","handleZoomOut","ZoomIn","handleZoomIn","Scan","handleFitToWidth","Maximize2","handleOriginalSize","RotateCcw","handleRotateLeft","RotateCw","handleRotateRight","RefreshCw","handleReset","listener","containerRef","containerWidth","containerHeight","scaleX","scaleY","imgRef","blobUrl","fileBlobCache","loaderCache","pageCache","isTouchDevice","touchStartDistance","touchStartZoom","touchStartPos","lastTapTime","url","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","err","handlePageChange","page","cached","firstKey","oldUrl","onBeforeUnmount","container","handleWheelNative","z","clampPosition","pos","currentZoom","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","newZoom","handleError","handleDoubleClick","rect","mouseX","mouseY","delta","prev","scale","onMounted","handleTouchStart","handleTouchMove","handleTouchEnd","handleMouseDown","handleMouseMove","handleMouseUp","touches","now","distance","centerX","centerY","zoomScale","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_createVNode","_unref","Loader2","_createElementVNode","_hoisted_2","_createBlock","RendererError","_hoisted_4","_cache","_normalizeClass","_hoisted_6","_toDisplayString","_hoisted_7","$event","_hoisted_8","_hoisted_9","_hoisted_10"],"mappings":"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"}
1
+ {"version":3,"file":"index-2RMNnT0y.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { Loader2, ZoomIn, ZoomOut, RotateCw, RotateCcw, Scan, RefreshCw, Maximize2 } from 'lucide-vue-next';\nimport { formatFileSize, detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\nimport { ToolbarEventEmitter } from '../base.types';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nconst props = defineProps<{\n url: string;\n fileSize?: number;\n file?: PreviewFile | File;\n}>();\n\nconst emitter = new ToolbarEventEmitter();\n\nconst { t } = useTranslator();\n\n// 内部状态管理\nconst zoom = ref(1);\nconst rotation = ref(0);\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst decoding = ref(false);\nconst decodeProgress = ref(0);\nconst decodeError = ref<string | null>(null);\nconst imageSrc = ref<string>('');\nconst currentPage = ref(1);\nconst totalPages = ref(1);\nconst isRawThumbnail = ref(false);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\n// 通知工具栏变化\nwatch([zoom, rotation], () => {\n emitter.notify();\n});\n\n// 工具栏配置(对齐 React 的 4 个按钮组)\nconst getToolbarGroups = (): ToolbarGroup[] => [\n {\n items: [\n {\n type: 'button',\n icon: ZoomOut,\n tooltip: t.value('toolbar.zoom_out'),\n action: handleZoomOut,\n disabled: zoom.value <= 0.01,\n },\n {\n type: 'text',\n content: `${Math.round(zoom.value * 100)}%`,\n minWidth: '3rem',\n },\n {\n type: 'button',\n icon: ZoomIn,\n tooltip: t.value('toolbar.zoom_in'),\n action: handleZoomIn,\n disabled: zoom.value >= 10,\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: Scan,\n tooltip: t.value('toolbar.fit_to_window'),\n action: handleFitToWidth,\n },\n {\n type: 'button',\n icon: Maximize2,\n tooltip: t.value('toolbar.original_size'),\n action: handleOriginalSize,\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: RotateCcw,\n tooltip: t.value('toolbar.rotate_left'),\n action: handleRotateLeft,\n },\n {\n type: 'button',\n icon: RotateCw,\n tooltip: t.value('toolbar.rotate_right'),\n action: handleRotateRight,\n },\n ],\n },\n {\n items: [\n {\n type: 'button',\n icon: RefreshCw,\n tooltip: t.value('toolbar.reset'),\n action: handleReset,\n },\n ],\n },\n];\n\n// 暴露接口\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n onToolbarChange: (listener) => emitter.subscribe(listener),\n});\n\n// 工具栏操作\nconst handleZoomIn = () => {\n zoom.value = Math.min(zoom.value + 0.1, 10);\n};\n\nconst handleZoomOut = () => {\n zoom.value = Math.max(zoom.value - 0.1, 0.01);\n};\n\nconst handleRotateRight = () => {\n rotation.value = (rotation.value + 90) % 360;\n};\n\nconst handleRotateLeft = () => {\n rotation.value = (rotation.value - 90 + 360) % 360;\n};\n\nconst handleOriginalSize = () => {\n zoom.value = 1;\n rotation.value = 0;\n position.value = { x: 0, y: 0 };\n};\n\nconst handleReset = () => {\n handleFitToWidth();\n};\n\nconst handleFitToWidth = () => {\n if (containerRef.value && naturalSize.value.width > 0 && naturalSize.value.height > 0) {\n const containerWidth = containerRef.value.clientWidth;\n const containerHeight = containerRef.value.clientHeight;\n const scaleX = containerWidth / naturalSize.value.width;\n const scaleY = containerHeight / naturalSize.value.height;\n zoom.value = Math.max(0.01, Math.min(10, Math.min(scaleX, scaleY)));\n position.value = { x: 0, y: 0 };\n }\n};\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet blobUrl: string | null = null;\nlet fileBlobCache: Blob | null = null;\nlet loaderCache: any = null;\nconst pageCache = new Map<number, string>();\n\nlet isTouchDevice = false;\nlet touchStartDistance = 0;\nlet touchStartZoom = 1;\nlet touchStartPos = { x: 0, y: 0 };\nlet lastTapTime = 0;\n\n// 解码逻辑\nwatch(\n () => [props.url, props.file] as const,\n async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n imageSrc.value = '';\n loaded.value = false;\n error.value = null;\n decoding.value = false;\n decodeError.value = null;\n decodeProgress.value = 0;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n zoom.value = 1;\n currentPage.value = 1;\n totalPages.value = 1;\n isRawThumbnail.value = false;\n\n // 清理旧的 blob URL 与缓存\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n fileBlobCache = null;\n loaderCache = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!props.file) {\n imageSrc.value = props.url;\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(props.file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n imageSrc.value = props.url;\n return;\n }\n\n // 需要解码\n decoding.value = true;\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (props.file instanceof Blob) {\n fileBlob = props.file;\n } else {\n const response = await fetch(props.url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n // 缓存 Blob 与 loader\n fileBlobCache = fileBlob;\n loaderCache = loader;\n\n // 标记 RAW 缩略图模式\n const isRaw = mimeType.startsWith('image/x-');\n if (isRaw) {\n isRawThumbnail.value = true;\n }\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (metadata.pageCount && metadata.pageCount > 1) {\n totalPages.value = metadata.pageCount;\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n decodeProgress.value = percent;\n },\n });\n\n // 生成 blob URL\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrl = url;\n pageCache.set(1, url);\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '解码失败';\n decoding.value = false;\n }\n },\n { immediate: true }\n);\n\n// 多页 TIFF 翻页\nconst handlePageChange = async (page: number) => {\n if (!fileBlobCache || !loaderCache) return;\n if (page < 1 || page > totalPages.value) return;\n\n // 命中缓存:直接切换\n const cached = pageCache.get(page);\n if (cached) {\n currentPage.value = page;\n imageSrc.value = cached;\n return;\n }\n\n // 解码新页面\n decoding.value = true;\n try {\n const decodedBlob = await loaderCache.decode(fileBlobCache, { page });\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCache.size >= 10) {\n const firstKey = pageCache.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCache.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCache.delete(firstKey);\n }\n }\n\n pageCache.set(page, url);\n currentPage.value = page;\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '翻页解码失败';\n decoding.value = false;\n }\n};\n\n// Cleanup on unmount\nonBeforeUnmount(() => {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\n// 同步 zoom 和 internalZoom\nwatch(zoom, (z) => {\n internalZoom.value = z;\n});\n\nwatch(internalZoom, (z) => {\n zoom.value = z;\n});\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n\n // 自动适应窗口\n if (containerRef.value && naturalSize.value.width > 0 && naturalSize.value.height > 0) {\n const containerWidth = containerRef.value.clientWidth;\n const containerHeight = containerRef.value.clientHeight;\n const scaleX = containerWidth / naturalSize.value.width;\n const scaleY = containerHeight / naturalSize.value.height;\n const newZoom = Math.min(scaleX, scaleY);\n zoom.value = Math.max(0.01, Math.min(10, newZoom));\n position.value = { x: 0, y: 0 };\n }\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n zoom.value = 1;\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n container.addEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n container.removeEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n if (isTouchDevice) return;\n isDragging.value = false;\n};\n\n// 触屏事件处理\nconst handleTouchStart = (e: TouchEvent) => {\n isTouchDevice = true;\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1) {\n // 单指拖拽\n isDragging.value = true;\n dragStart = {\n x: touches[0].clientX - position.value.x,\n y: touches[0].clientY - position.value.y,\n };\n\n // 双击检测\n const now = Date.now();\n if (now - lastTapTime < 300) {\n // 双击复原:居中 + 缩放100%\n position.value = { x: 0, y: 0 };\n zoom.value = 1;\n }\n lastTapTime = now;\n } else if (touches.length === 2) {\n // 双指缩放初始化\n isDragging.value = false;\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n touchStartDistance = distance;\n touchStartZoom = internalZoom.value;\n touchStartPos = { ...position.value };\n }\n};\n\nconst handleTouchMove = (e: TouchEvent) => {\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1 && isDragging.value) {\n // 单指拖拽\n position.value = clampPosition(\n {\n x: touches[0].clientX - dragStart.x,\n y: touches[0].clientY - dragStart.y,\n },\n internalZoom.value\n );\n } else if (touches.length === 2) {\n // 双指缩放\n const container = containerRef.value;\n if (!container) return;\n\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n\n // 最小距离变化阈值,防止抖动\n if (Math.abs(distance - touchStartDistance) < 5) return;\n\n const scale = distance / touchStartDistance;\n const newZoom = Math.max(0.01, Math.min(10, touchStartZoom * scale));\n\n // 双指中心点作为缩放原点\n const rect = container.getBoundingClientRect();\n const centerX = (touches[0].clientX + touches[1].clientX) / 2 - rect.left - rect.width / 2;\n const centerY = (touches[0].clientY + touches[1].clientY) / 2 - rect.top - rect.height / 2;\n\n const zoomScale = newZoom / internalZoom.value;\n position.value = clampPosition(\n {\n x: centerX - zoomScale * (centerX - touchStartPos.x),\n y: centerY - zoomScale * (centerY - touchStartPos.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n }\n};\n\nconst handleTouchEnd = () => {\n isDragging.value = false;\n touchStartDistance = 0;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${rotation.value}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value && !error.value && !decodeError.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab', touchAction: 'none' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <!-- 解码中 -->\n <div\n v-if=\"decoding\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10\"\n >\n <Loader2 class=\"vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin\" />\n <p class=\"vfp-mt-4 vfp-text-fg-secondary\">\n 正在解码... <span v-if=\"decodeProgress > 0\">{{ Math.round(decodeProgress) }}%</span>\n </p>\n </div>\n\n <!-- 解码错误 -->\n <RendererError v-if=\"decodeError\" :message=\"t('image.decode_failed')\" :detail=\"decodeError\" />\n\n <div v-if=\"!loaded && !error && !decoding && !decodeError\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <img\n v-if=\"imageSrc\"\n ref=\"imgRef\"\n :src=\"imageSrc\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', (!loaded || error || decodeError) && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n\n <!-- 多页 TIFF 翻页器 -->\n <div\n v-if=\"totalPages > 1\"\n class=\"vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md\"\n >\n <button\n type=\"button\"\n :disabled=\"currentPage <= 1 || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage - 1)\"\n >\n 上一页\n </button>\n <span class=\"vfp-text-fg-secondary vfp-tabular-nums\">\n {{ currentPage }} / {{ totalPages }}\n </span>\n <button\n type=\"button\"\n :disabled=\"currentPage >= totalPages || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage + 1)\"\n >\n 下一页\n </button>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emitter","ToolbarEventEmitter","t","useTranslator","zoom","ref","rotation","loaded","error","decoding","decodeProgress","decodeError","imageSrc","currentPage","totalPages","isRawThumbnail","position","isDragging","dragStart","internalZoom","naturalSize","watch","__expose","ZoomOut","handleZoomOut","ZoomIn","handleZoomIn","Scan","handleFitToWidth","Maximize2","handleOriginalSize","RotateCcw","handleRotateLeft","RotateCw","handleRotateRight","RefreshCw","handleReset","listener","containerRef","containerWidth","containerHeight","scaleX","scaleY","imgRef","blobUrl","fileBlobCache","loaderCache","pageCache","isTouchDevice","touchStartDistance","touchStartZoom","touchStartPos","lastTapTime","url","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","err","handlePageChange","page","cached","firstKey","oldUrl","onBeforeUnmount","container","handleWheelNative","z","clampPosition","pos","currentZoom","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","newZoom","handleError","handleDoubleClick","rect","mouseX","mouseY","delta","prev","scale","onMounted","handleTouchStart","handleTouchMove","handleTouchEnd","handleMouseDown","handleMouseMove","handleMouseUp","touches","now","distance","centerX","centerY","zoomScale","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_createVNode","_unref","Loader2","_createElementVNode","_hoisted_2","_createBlock","RendererError","_hoisted_4","_cache","_normalizeClass","_hoisted_6","_toDisplayString","_hoisted_7","$event","_hoisted_8","_hoisted_9","_hoisted_10"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAWA,UAAMA,IAAQC,IAMRC,IAAU,IAAIC,GAAA,GAEd,EAAE,GAAAC,EAAA,IAAMC,GAAA,GAGRC,IAAOC,EAAI,CAAC,GACZC,IAAWD,EAAI,CAAC,GAChBE,IAASF,EAAI,EAAK,GAClBG,IAAQH,EAAmB,IAAI,GAC/BI,IAAWJ,EAAI,EAAK,GACpBK,IAAiBL,EAAI,CAAC,GACtBM,IAAcN,EAAmB,IAAI,GACrCO,IAAWP,EAAY,EAAE,GACzBQ,IAAcR,EAAI,CAAC,GACnBS,IAAaT,EAAI,CAAC,GAClBU,IAAiBV,EAAI,EAAK,GAC1BW,IAAWX,EAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAC7BY,IAAaZ,EAAI,EAAK;AAC5B,QAAIa,IAAY,EAAE,GAAG,GAAG,GAAG,EAAA;AAC3B,UAAMC,IAAed,EAAI,CAAC,GACpBe,IAAcf,EAAI,EAAE,OAAO,GAAG,QAAQ,GAAG;AAG/C,IAAAgB,EAAM,CAACjB,GAAME,CAAQ,GAAG,MAAM;AAC5B,MAAAN,EAAQ,OAAA;AAAA,IACV,CAAC,GAwEDsB,GAA6B;AAAA,MAC3B,kBAtEuB,MAAsB;AAAA,QAC7C;AAAA,UACE,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,MAAMC;AAAA,cACN,SAASrB,EAAE,MAAM,kBAAkB;AAAA,cACnC,QAAQsB;AAAA,cACR,UAAUpB,EAAK,SAAS;AAAA,YAAA;AAAA,YAE1B;AAAA,cACE,MAAM;AAAA,cACN,SAAS,GAAG,KAAK,MAAMA,EAAK,QAAQ,GAAG,CAAC;AAAA,cACxC,UAAU;AAAA,YAAA;AAAA,YAEZ;AAAA,cACE,MAAM;AAAA,cACN,MAAMqB;AAAA,cACN,SAASvB,EAAE,MAAM,iBAAiB;AAAA,cAClC,QAAQwB;AAAA,cACR,UAAUtB,EAAK,SAAS;AAAA,YAAA;AAAA,UAC1B;AAAA,QACF;AAAA,QAEF;AAAA,UACE,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,MAAMuB;AAAA,cACN,SAASzB,EAAE,MAAM,uBAAuB;AAAA,cACxC,QAAQ0B;AAAA,YAAA;AAAA,YAEV;AAAA,cACE,MAAM;AAAA,cACN,MAAMC;AAAA,cACN,SAAS3B,EAAE,MAAM,uBAAuB;AAAA,cACxC,QAAQ4B;AAAA,YAAA;AAAA,UACV;AAAA,QACF;AAAA,QAEF;AAAA,UACE,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,MAAMC;AAAA,cACN,SAAS7B,EAAE,MAAM,qBAAqB;AAAA,cACtC,QAAQ8B;AAAA,YAAA;AAAA,YAEV;AAAA,cACE,MAAM;AAAA,cACN,MAAMC;AAAA,cACN,SAAS/B,EAAE,MAAM,sBAAsB;AAAA,cACvC,QAAQgC;AAAA,YAAA;AAAA,UACV;AAAA,QACF;AAAA,QAEF;AAAA,UACE,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,MAAMC;AAAA,cACN,SAASjC,EAAE,MAAM,eAAe;AAAA,cAChC,QAAQkC;AAAA,YAAA;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MAMA,iBAAiB,CAACC,MAAarC,EAAQ,UAAUqC,CAAQ;AAAA,IAAA,CAC1D;AAGD,UAAMX,KAAe,MAAM;AACzB,MAAAtB,EAAK,QAAQ,KAAK,IAAIA,EAAK,QAAQ,KAAK,EAAE;AAAA,IAC5C,GAEMoB,KAAgB,MAAM;AAC1B,MAAApB,EAAK,QAAQ,KAAK,IAAIA,EAAK,QAAQ,KAAK,IAAI;AAAA,IAC9C,GAEM8B,KAAoB,MAAM;AAC9B,MAAA5B,EAAS,SAASA,EAAS,QAAQ,MAAM;AAAA,IAC3C,GAEM0B,KAAmB,MAAM;AAC7B,MAAA1B,EAAS,SAASA,EAAS,QAAQ,KAAK,OAAO;AAAA,IACjD,GAEMwB,KAAqB,MAAM;AAC/B,MAAA1B,EAAK,QAAQ,GACbE,EAAS,QAAQ,GACjBU,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,IAC9B,GAEMoB,KAAc,MAAM;AACxB,MAAAR,EAAA;AAAA,IACF,GAEMA,IAAmB,MAAM;AAC7B,UAAIU,EAAa,SAASlB,EAAY,MAAM,QAAQ,KAAKA,EAAY,MAAM,SAAS,GAAG;AACrF,cAAMmB,IAAiBD,EAAa,MAAM,aACpCE,IAAkBF,EAAa,MAAM,cACrCG,IAASF,IAAiBnB,EAAY,MAAM,OAC5CsB,IAASF,IAAkBpB,EAAY,MAAM;AACnD,QAAAhB,EAAK,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,IAAIqC,GAAQC,CAAM,CAAC,CAAC,GAClE1B,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,MAC9B;AAAA,IACF,GAEM2B,KAAStC,EAA6B,IAAI,GAC1CiC,IAAejC,EAA2B,IAAI;AACpD,QAAIuC,IAAyB,MACzBC,IAA6B,MAC7BC,IAAmB;AACvB,UAAMC,wBAAgB,IAAA;AAEtB,QAAIC,IAAgB,IAChBC,IAAqB,GACrBC,IAAiB,GACjBC,IAAgB,EAAE,GAAG,GAAG,GAAG,EAAA,GAC3BC,IAAc;AAGlB,IAAA/B;AAAA,MACE,MAAM,CAACvB,EAAM,KAAKA,EAAM,IAAI;AAAA,MAC5B,YAAY;AA0BV,YAxBAc,EAAS,QAAQ,IACjBL,EAAO,QAAQ,IACfC,EAAM,QAAQ,MACdC,EAAS,QAAQ,IACjBE,EAAY,QAAQ,MACpBD,EAAe,QAAQ,GACvBM,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA,GAC5BG,EAAa,QAAQ,GACrBf,EAAK,QAAQ,GACbS,EAAY,QAAQ,GACpBC,EAAW,QAAQ,GACnBC,EAAe,QAAQ,IAGnB6B,MACF,IAAI,gBAAgBA,CAAO,GAC3BA,IAAU,OAEZG,EAAU,QAAQ,CAACM,MAAQ,IAAI,gBAAgBA,CAAG,CAAC,GACnDN,EAAU,MAAA,GACVF,IAAgB,MAChBC,IAAc,MAGV,CAAChD,EAAM,MAAM;AACf,UAAAc,EAAS,QAAQd,EAAM;AACvB;AAAA,QACF;AAEA,YAAI;AAEF,gBAAMwD,IAAW,MAAMC,GAAkBzD,EAAM,IAAI,GAC7C0D,IAAS,MAAMC,GAAqBH,CAAQ;AAGlD,cAAI,CAACE,KAAU,CAAE,MAAMA,EAAO,YAAYF,CAAQ,GAAI;AACpD,YAAA1C,EAAS,QAAQd,EAAM;AACvB;AAAA,UACF;AAGA,UAAAW,EAAS,QAAQ;AAGjB,cAAIiD;AACJ,cAAI5D,EAAM,gBAAgB;AACxB,YAAA4D,IAAW5D,EAAM;AAAA,eACZ;AACL,kBAAM6D,IAAW,MAAM,MAAM7D,EAAM,GAAG;AACtC,gBAAI,CAAC6D,EAAS,GAAI,OAAM,IAAI,MAAM,sBAAsB;AACxD,YAAAD,IAAW,MAAMC,EAAS,KAAA;AAAA,UAC5B;AAaA,cAVAd,IAAgBa,GAChBZ,IAAcU,GAGAF,EAAS,WAAW,UAAU,MAE1CvC,EAAe,QAAQ,KAIrByC,EAAO;AACT,gBAAI;AACF,oBAAMI,IAAW,MAAMJ,EAAO,YAAYE,CAAQ;AAClD,cAAIE,EAAS,aAAaA,EAAS,YAAY,MAC7C9C,EAAW,QAAQ8C,EAAS;AAAA,YAEhC,QAAQ;AAAA,YAER;AAIF,gBAAMC,IAAc,MAAML,EAAO,OAAOE,GAAU;AAAA,YAChD,MAAM;AAAA,YACN,aAAa;AAAA,YACb,YAAY,CAACI,MAAoB;AAC/B,cAAApD,EAAe,QAAQoD;AAAA,YACzB;AAAA,UAAA,CACD,GAGKT,IAAM,OAAOQ,KAAgB,WAC/BA,IACA,IAAI,gBAAgBA,CAAW;AAEnC,UAAAjB,IAAUS,GACVN,EAAU,IAAI,GAAGM,CAAG,GACpBzC,EAAS,QAAQyC,GACjB5C,EAAS,QAAQ;AAAA,QACnB,SAASsD,GAAU;AACjB,UAAApD,EAAY,SAAQoD,KAAA,gBAAAA,EAAK,YAAW,QACpCtD,EAAS,QAAQ;AAAA,QACnB;AAAA,MACF;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK;AAIpB,UAAMuD,IAAmB,OAAOC,MAAiB;AAE/C,UADI,CAACpB,KAAiB,CAACC,KACnBmB,IAAO,KAAKA,IAAOnD,EAAW,MAAO;AAGzC,YAAMoD,IAASnB,EAAU,IAAIkB,CAAI;AACjC,UAAIC,GAAQ;AACV,QAAArD,EAAY,QAAQoD,GACpBrD,EAAS,QAAQsD;AACjB;AAAA,MACF;AAGA,MAAAzD,EAAS,QAAQ;AACjB,UAAI;AACF,cAAMoD,IAAc,MAAMf,EAAY,OAAOD,GAAe,EAAE,MAAAoB,GAAM,GAC9DZ,IAAM,OAAOQ,KAAgB,WAC/BA,IACA,IAAI,gBAAgBA,CAAW;AAGnC,YAAId,EAAU,QAAQ,IAAI;AACxB,gBAAMoB,IAAWpB,EAAU,KAAA,EAAO,OAAO;AACzC,cAAIoB,MAAa,QAAW;AAC1B,kBAAMC,IAASrB,EAAU,IAAIoB,CAAQ;AACrC,YAAIC,KAAQ,IAAI,gBAAgBA,CAAM,GACtCrB,EAAU,OAAOoB,CAAQ;AAAA,UAC3B;AAAA,QACF;AAEA,QAAApB,EAAU,IAAIkB,GAAMZ,CAAG,GACvBxC,EAAY,QAAQoD,GACpBrD,EAAS,QAAQyC,GACjB5C,EAAS,QAAQ;AAAA,MACnB,SAASsD,GAAU;AACjB,QAAApD,EAAY,SAAQoD,KAAA,gBAAAA,EAAK,YAAW,UACpCtD,EAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAGA,IAAA4D,GAAgB,MAAM;AACpB,MAAIzB,KACF,IAAI,gBAAgBA,CAAO,GAE7BG,EAAU,QAAQ,CAACM,MAAQ,IAAI,gBAAgBA,CAAG,CAAC,GACnDN,EAAU,MAAA;AACV,YAAMuB,IAAYhC,EAAa;AAC/B,MAAIgC,KACFA,EAAU,oBAAoB,SAASC,CAAiB;AAAA,IAE5D,CAAC,GAGDlD,EAAMjB,GAAM,CAACoE,MAAM;AACjB,MAAArD,EAAa,QAAQqD;AAAA,IACvB,CAAC,GAEDnD,EAAMF,GAAc,CAACqD,MAAM;AACzB,MAAApE,EAAK,QAAQoE;AAAA,IACf,CAAC;AAED,UAAMC,IAAgB,CAACC,GAA+BC,MAAwB;AAC5E,YAAML,IAAYhC,EAAa;AAC/B,UAAI,CAACgC,KAAalD,EAAY,MAAM,UAAU,EAAG,QAAOsD;AAExD,YAAME,IAAaN,EAAU,aACvBO,IAAaP,EAAU,cACvBQ,IAAO1D,EAAY,MAAM,QAAQuD,GACjCI,IAAO3D,EAAY,MAAM,SAASuD,GAElCK,IAAS,KAAK,IAAI,IAAIJ,IAAa,MAAMC,IAAa,IAAI,GAC1DI,KAAUL,IAAaE,KAAQ,IAAIE,GACnCE,KAAUL,IAAaE,KAAQ,IAAIC;AAEzC,aAAO;AAAA,QACL,GAAGC,IAAS,IAAI,KAAK,IAAI,CAACA,GAAQ,KAAK,IAAIA,GAAQP,EAAI,CAAC,CAAC,IAAI;AAAA,QAC7D,GAAGQ,IAAS,IAAI,KAAK,IAAI,CAACA,GAAQ,KAAK,IAAIA,GAAQR,EAAI,CAAC,CAAC,IAAI;AAAA,MAAA;AAAA,IAEjE,GAEMS,KAAa,CAAC,MAAa;AAC/B,MAAA5E,EAAO,QAAQ;AACf,YAAM6E,IAAM,EAAE;AAId,UAHAhE,EAAY,QAAQ,EAAE,OAAOgE,EAAI,cAAc,QAAQA,EAAI,cAAA,GAGvD9C,EAAa,SAASlB,EAAY,MAAM,QAAQ,KAAKA,EAAY,MAAM,SAAS,GAAG;AACrF,cAAMmB,IAAiBD,EAAa,MAAM,aACpCE,IAAkBF,EAAa,MAAM,cACrCG,IAASF,IAAiBnB,EAAY,MAAM,OAC5CsB,IAASF,IAAkBpB,EAAY,MAAM,QAC7CiE,IAAU,KAAK,IAAI5C,GAAQC,CAAM;AACvC,QAAAtC,EAAK,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAIiF,CAAO,CAAC,GACjDrE,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,MAC9B;AAAA,IACF,GAEMsE,KAAc,MAAM;AACxB,MAAA9E,EAAM,QAAQN,EAAE,MAAM,mBAAmB,GACzCK,EAAO,QAAQ;AAAA,IACjB,GAEMgF,KAAoB,MAAM;AAC9B,MAAAvE,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA,GAC5BZ,EAAK,QAAQ;AAAA,IACf,GAGMmE,IAAoB,CAAC,MAAkB;AAC3C,QAAE,eAAA,GACF,EAAE,gBAAA;AAEF,YAAMD,IAAYhC,EAAa;AAC/B,UAAI,CAACgC,EAAW;AAEhB,YAAMkB,IAAOlB,EAAU,sBAAA,GACjBmB,IAAS,EAAE,UAAUD,EAAK,OAAOA,EAAK,QAAQ,GAC9CE,IAAS,EAAE,UAAUF,EAAK,MAAMA,EAAK,SAAS,GAE9CG,IAAQ,EAAE,SAAS,IAAI,QAAQ,MAC/BC,IAAOzE,EAAa,OACpBkE,IAAU,KAAK,IAAI,MAAM,KAAK,IAAI,IAAIO,IAAOD,CAAK,CAAC,GACnDE,IAAQR,IAAUO;AAExB,MAAA5E,EAAS,QAAQyD;AAAA,QACf;AAAA,UACE,GAAGgB,IAASI,KAASJ,IAASzE,EAAS,MAAM;AAAA,UAC7C,GAAG0E,IAASG,KAASH,IAAS1E,EAAS,MAAM;AAAA,QAAA;AAAA,QAE/CqE;AAAA,MAAA,GAGFlE,EAAa,QAAQkE;AAAA,IACvB;AAEA,IAAAS,GAAU,MAAM;AACd,YAAMxB,IAAYhC,EAAa;AAC/B,MAAIgC,MACFA,EAAU,iBAAiB,SAASC,GAAmB,EAAE,SAAS,IAAO,GACzED,EAAU,iBAAiB,cAAcyB,GAAkB,EAAE,SAAS,IAAO,GAC7EzB,EAAU,iBAAiB,aAAa0B,GAAiB,EAAE,SAAS,IAAO,GAC3E1B,EAAU,iBAAiB,YAAY2B,CAAc,GACrD3B,EAAU,iBAAiB,eAAe2B,CAAc;AAAA,IAE5D,CAAC,GAED5B,GAAgB,MAAM;AACpB,YAAMC,IAAYhC,EAAa;AAC/B,MAAIgC,MACFA,EAAU,oBAAoB,SAASC,CAAiB,GACxDD,EAAU,oBAAoB,cAAcyB,CAAgB,GAC5DzB,EAAU,oBAAoB,aAAa0B,CAAe,GAC1D1B,EAAU,oBAAoB,YAAY2B,CAAc,GACxD3B,EAAU,oBAAoB,eAAe2B,CAAc;AAAA,IAE/D,CAAC;AAED,UAAMC,KAAkB,CAAC,MAAkB;AACzC,MAAIlD,KACA,EAAE,WAAW,MACjB/B,EAAW,QAAQ,IACnBC,IAAY;AAAA,QACV,GAAG,EAAE,UAAUF,EAAS,MAAM;AAAA,QAC9B,GAAG,EAAE,UAAUA,EAAS,MAAM;AAAA,MAAA;AAAA,IAElC,GAEMmF,KAAkB,CAAC,MAAkB;AACzC,MAAInD,KACC/B,EAAW,UAChBD,EAAS,QAAQyD;AAAA,QACf;AAAA,UACE,GAAG,EAAE,UAAUvD,EAAU;AAAA,UACzB,GAAG,EAAE,UAAUA,EAAU;AAAA,QAAA;AAAA,QAE3BC,EAAa;AAAA,MAAA;AAAA,IAEjB,GAEMiF,IAAgB,MAAM;AAC1B,MAAIpD,MACJ/B,EAAW,QAAQ;AAAA,IACrB,GAGM8E,IAAmB,CAAC,MAAkB;AAC1C,MAAA/C,IAAgB,IAChB,EAAE,eAAA;AAEF,YAAMqD,IAAU,EAAE;AAClB,UAAIA,EAAQ,WAAW,GAAG;AAExB,QAAApF,EAAW,QAAQ,IACnBC,IAAY;AAAA,UACV,GAAGmF,EAAQ,CAAC,EAAE,UAAUrF,EAAS,MAAM;AAAA,UACvC,GAAGqF,EAAQ,CAAC,EAAE,UAAUrF,EAAS,MAAM;AAAA,QAAA;AAIzC,cAAMsF,IAAM,KAAK,IAAA;AACjB,QAAIA,IAAMlD,IAAc,QAEtBpC,EAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAA,GAC5BZ,EAAK,QAAQ,IAEfgD,IAAckD;AAAA,MAChB,MAAA,CAAWD,EAAQ,WAAW,MAE5BpF,EAAW,QAAQ,IAKnBgC,IAJiB,KAAK;AAAA,QACpBoD,EAAQ,CAAC,EAAE,UAAUA,EAAQ,CAAC,EAAE;AAAA,QAChCA,EAAQ,CAAC,EAAE,UAAUA,EAAQ,CAAC,EAAE;AAAA,MAAA,GAGlCnD,IAAiB/B,EAAa,OAC9BgC,IAAgB,EAAE,GAAGnC,EAAS,MAAA;AAAA,IAElC,GAEMgF,IAAkB,CAAC,MAAkB;AACzC,QAAE,eAAA;AAEF,YAAMK,IAAU,EAAE;AAClB,UAAIA,EAAQ,WAAW,KAAKpF,EAAW;AAErC,QAAAD,EAAS,QAAQyD;AAAA,UACf;AAAA,YACE,GAAG4B,EAAQ,CAAC,EAAE,UAAUnF,EAAU;AAAA,YAClC,GAAGmF,EAAQ,CAAC,EAAE,UAAUnF,EAAU;AAAA,UAAA;AAAA,UAEpCC,EAAa;AAAA,QAAA;AAAA,eAENkF,EAAQ,WAAW,GAAG;AAE/B,cAAM/B,IAAYhC,EAAa;AAC/B,YAAI,CAACgC,EAAW;AAEhB,cAAMiC,IAAW,KAAK;AAAA,UACpBF,EAAQ,CAAC,EAAE,UAAUA,EAAQ,CAAC,EAAE;AAAA,UAChCA,EAAQ,CAAC,EAAE,UAAUA,EAAQ,CAAC,EAAE;AAAA,QAAA;AAIlC,YAAI,KAAK,IAAIE,IAAWtD,CAAkB,IAAI,EAAG;AAEjD,cAAM4C,IAAQU,IAAWtD,GACnBoC,IAAU,KAAK,IAAI,MAAM,KAAK,IAAI,IAAInC,IAAiB2C,CAAK,CAAC,GAG7DL,IAAOlB,EAAU,sBAAA,GACjBkC,KAAWH,EAAQ,CAAC,EAAE,UAAUA,EAAQ,CAAC,EAAE,WAAW,IAAIb,EAAK,OAAOA,EAAK,QAAQ,GACnFiB,KAAWJ,EAAQ,CAAC,EAAE,UAAUA,EAAQ,CAAC,EAAE,WAAW,IAAIb,EAAK,MAAMA,EAAK,SAAS,GAEnFkB,IAAYrB,IAAUlE,EAAa;AACzC,QAAAH,EAAS,QAAQyD;AAAA,UACf;AAAA,YACE,GAAG+B,IAAUE,KAAaF,IAAUrD,EAAc;AAAA,YAClD,GAAGsD,IAAUC,KAAaD,IAAUtD,EAAc;AAAA,UAAA;AAAA,UAEpDkC;AAAA,QAAA,GAGFlE,EAAa,QAAQkE;AAAA,MACvB;AAAA,IACF,GAEMY,IAAiB,MAAM;AAC3B,MAAAhF,EAAW,QAAQ,IACnBgC,IAAqB;AAAA,IACvB,GAEM0D,KAAiBC,GAAS,OAAO;AAAA,MACrC,WAAW,aAAa5F,EAAS,MAAM,CAAC,OAAOA,EAAS,MAAM,CAAC,aAAaG,EAAa,KAAK,YAAYb,EAAS,KAAK;AAAA,MACxH,iBAAiB;AAAA,MACjB,YAAYW,EAAW,QAAQ,SAAS;AAAA,MACxC,SAASV,EAAO,SAAS,CAACC,EAAM,SAAS,CAACG,EAAY,QAAQ,IAAI;AAAA,IAAA,EAClE,GAEIkG,KAAWD,GAAS,MACpB9G,EAAM,YAAY,OAAa,KAC5B,MAAMgH,GAAehH,EAAM,QAAQ,CAAC,EAC5C;2BAICiH,EA4EM,OAAA;AAAA,eA3EA;AAAA,MAAJ,KAAIzE;AAAA,MACJ,OAAM;AAAA,MACL,oBAAiBrB,EAAA,QAAU,aAAA,QAAA,aAAA,QAAA;AAAA,MAC3B,aAAWiF;AAAA,MACX,aAAWC;AAAA,MACX,WAASC;AAAA,MACT,cAAYA;AAAA,IAAA;MAIL3F,EAAA,SADRuG,EAAA,GAAAD,EAQM,OARNE,IAQM;AAAA,QAJJC,GAA0EC,GAAAC,EAAA,GAAA,EAAjE,OAAM,0DAAwD;AAAA,QACvEC,EAEI,KAFJC,IAEI;AAAA,6BAFsC,aAChC,EAAA;AAAA,UAAY5G,EAAA,QAAc,KAA1BsG,EAAA,GAAAD,EAAwE,cAArC,KAAK,MAAMrG,EAAA,KAAc,KAAI,KAAC,CAAA;;;MAKxDC,EAAA,cAArB4G,GAA8FC,IAAA;AAAA;QAA3D,SAASL,GAAAjH,CAAA,EAAC,qBAAA;AAAA,QAA0B,QAAQS,EAAA;AAAA,MAAA;MAEnE,CAAAJ,EAAA,SAAM,CAAKC,EAAA,SAAK,CAAKC,EAAA,UAAaE,EAAA,SAA9CqG,KAAAD,EAIM,OAJNU,IAIM,CAAA,GAAAC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA;AAAA,QAHJL,EAEE,OAAA,EADA,OAAM,oHAAA,GAAmH,MAAA,EAAA;AAAA,MAAA;MAIxG7G,EAAA,cAArB+G,GAA+CC,IAAA;AAAA;QAAlB,SAAShH,EAAA;AAAA,MAAA;MAG9BI,EAAA,cADRmG,EAWE,OAAA;AAAA;iBATI;AAAA,QAAJ,KAAIpE;AAAA,QACH,KAAK/B,EAAA;AAAA,QACN,KAAI;AAAA,QACH,OAAK+G,GAAA,CAAA,mCAAA,CAAuCpH,EAAA,SAAUC,EAAA,SAASG,EAAA,UAAW,YAAA,CAAA;AAAA,QAC1E,UAAOgG,GAAA,KAAc;AAAA,QACrB,WAAW;AAAA,QACX,QAAMxB;AAAA,QACN,SAAOG;AAAA,QACP,YAAUC;AAAA,MAAA;MAILhF,EAAA,SAAM,CAAKC,EAAA,SAASY,EAAA,MAAY,QAAK,KAD7C4F,EAAA,GAAAD,EAKM,OALNa,IAKMC,EADDzG,EAAA,MAAY,KAAK,IAAG,QAAGyG,EAAGzG,EAAA,MAAY,MAAM,MAAMyF,GAAA,KAAQ,GAAA,CAAA;MAKvD/F,EAAA,QAAU,KADlBkG,KAAAD,EAuBM,OAvBNe,IAuBM;AAAA,QAnBJT,EAOS,UAAA;AAAA,UANP,MAAK;AAAA,UACJ,UAAUxG,EAAA,SAAW,KAASJ,EAAA;AAAA,UAC/B,OAAM;AAAA,UACL,SAAKiH,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAK,MAAE/D,EAAiBnD,EAAA,QAAW,CAAA;AAAA,QAAA,GACrC,SAED,GAAAmH,EAAA;AAAA,QACAX,EAEO,QAFPY,IAEOJ,EADFhH,OAAW,IAAG,UAAMC,EAAA,KAAU,GAAA,CAAA;AAAA,QAEnCuG,EAOS,UAAA;AAAA,UANP,MAAK;AAAA,UACJ,UAAUxG,EAAA,SAAeC,EAAA,SAAcL,EAAA;AAAA,UACxC,OAAM;AAAA,UACL,SAAKiH,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAK,MAAE/D,EAAiBnD,EAAA,QAAW,CAAA;AAAA,QAAA,GACrC,SAED,GAAAqH,EAAA;AAAA,MAAA;;;;"}
@@ -1,9 +1,9 @@
1
- import { defineComponent as I, computed as P, ref as c, watch as k, nextTick as D, openBlock as d, createElementBlock as u, createElementVNode as H, createBlock as K, toDisplayString as O } from "vue";
1
+ import { defineComponent as P, computed as D, ref as c, watch as k, nextTick as K, openBlock as d, createElementBlock as u, createElementVNode as H, createBlock as O, toDisplayString as R } from "vue";
2
2
  import N from "markdown-it";
3
- import Y from "@traptitech/markdown-it-katex";
3
+ import U from "@traptitech/markdown-it-katex";
4
4
  import { codeToHtml as E } from "shiki";
5
- import { Code as F, Eye as W } from "lucide-vue-next";
6
- import { u as z, a as J, b as Q, R as U, _ as X } from "./index-B8AUVu3R.mjs";
5
+ import { Code as Y, Eye as F } from "lucide-vue-next";
6
+ import { u as W, a as z, b as J, U as Q, _ as X } from "./index-M_Nf3MY5.mjs";
7
7
  import { _ as Z } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
8
8
  import { T as ee } from "./base.types-DaftHyg7.mjs";
9
9
  const te = {
@@ -19,13 +19,13 @@ const te = {
19
19
  }, ne = ["innerHTML"], le = {
20
20
  key: 3,
21
21
  class: "vfp-w-full vfp-h-full vfp-overflow-auto vfp-py-6 vfp-px-4"
22
- }, ae = ["innerHTML"], B = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>', L = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>', se = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>', ce = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>', ie = /* @__PURE__ */ I({
22
+ }, ae = ["innerHTML"], B = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>', L = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>', se = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>', ce = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>', ie = /* @__PURE__ */ P({
23
23
  __name: "index",
24
24
  props: {
25
25
  url: {}
26
26
  },
27
27
  setup(q, { expose: V }) {
28
- const _ = q, x = new ee(), { t: i } = z(), j = J(), G = Q(), y = P(() => G.value === "light" ? "github-light" : "github-dark"), s = c("preview"), b = c(""), v = c(""), f = c(""), p = c(!0), h = c(null), m = c(null);
28
+ const _ = q, x = new ee(), { t: i } = W(), j = z(), G = J(), y = D(() => G.value === "light" ? "github-light" : "github-dark"), s = c("preview"), b = c(""), v = c(""), f = c(""), p = c(!0), h = c(null), m = c(null);
29
29
  k([s, p], () => {
30
30
  x.notify();
31
31
  }), V({
@@ -35,7 +35,7 @@ const te = {
35
35
  items: [
36
36
  {
37
37
  type: "button",
38
- icon: s.value === "preview" ? F : W,
38
+ icon: s.value === "preview" ? Y : F,
39
39
  tooltip: s.value === "preview" ? i.value("toolbar.source") : i.value("toolbar.preview"),
40
40
  action: () => {
41
41
  s.value = s.value === "preview" ? "source" : "preview";
@@ -53,7 +53,7 @@ const te = {
53
53
  typographer: !1,
54
54
  breaks: !1
55
55
  });
56
- l.use(Y), l.renderer.rules.fence = (e, r) => {
56
+ l.use(U), l.renderer.rules.fence = (e, r) => {
57
57
  const t = e[r], n = t.info ? t.info.trim() : "", o = t.content;
58
58
  return n ? `<div class="code-block-wrapper">
59
59
  <div class="code-block-header">
@@ -76,7 +76,7 @@ const te = {
76
76
  const C = async () => {
77
77
  p.value = !0, h.value = null;
78
78
  try {
79
- const e = await U(_.url, { fetcher: j.value });
79
+ const e = await Q(_.url, { fetcher: j.value });
80
80
  b.value = e, v.value = l.render(e), p.value = !1;
81
81
  try {
82
82
  f.value = await E(e, { lang: "markdown", theme: y.value });
@@ -100,7 +100,7 @@ const te = {
100
100
  t.innerHTML = r ? B : L, t.title = i.value("markdown.copy_code");
101
101
  }, 2e3);
102
102
  }), t;
103
- }, R = async () => {
103
+ }, I = async () => {
104
104
  var t, n;
105
105
  if (!m.value) return;
106
106
  const e = m.value.querySelectorAll('pre[data-shiki-pending="1"]');
@@ -123,12 +123,12 @@ const te = {
123
123
  }
124
124
  };
125
125
  return k(() => _.url, C, { immediate: !0 }), k(v, async () => {
126
- v.value && (await D(), R());
126
+ v.value && (await K(), I());
127
127
  }), k(y, () => {
128
128
  b.value && C();
129
129
  }), (e, r) => p.value ? (d(), u("div", te, [...r[0] || (r[0] = [
130
130
  H("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
131
- ])])) : h.value ? (d(), K(Z, {
131
+ ])])) : h.value ? (d(), O(Z, {
132
132
  key: 1,
133
133
  message: h.value
134
134
  }, null, 8, ["message"])) : s.value === "source" ? (d(), u("div", oe, [
@@ -136,7 +136,7 @@ const te = {
136
136
  key: 1,
137
137
  class: "shiki-wrapper",
138
138
  innerHTML: f.value
139
- }, null, 8, ne)) : (d(), u("pre", re, O(b.value), 1))
139
+ }, null, 8, ne)) : (d(), u("pre", re, R(b.value), 1))
140
140
  ])) : (d(), u("div", le, [
141
141
  H("div", {
142
142
  ref_key: "containerRef",
@@ -150,4 +150,4 @@ const te = {
150
150
  export {
151
151
  ke as default
152
152
  };
153
- //# sourceMappingURL=index-zUjR2PO_.mjs.map
153
+ //# sourceMappingURL=index-B3Bv_Etp.mjs.map