李志伟 2 mesiacov pred
rodič
commit
b86ee45a25
72 zmenil súbory, kde vykonal 760 pridanie a 17287 odobranie
  1. 0 51
      .eslintrc.js
  2. 0 2
      .npmrc
  3. 3 0
      .vscode/extensions.json
  4. 3 250
      README.md
  5. 6 16
      index.html
  6. 21 37
      package.json
  7. 639 2947
      pnpm-lock.yaml
  8. 0 38
      prettier.js
  9. 0 12
      src/ libs/api.request.ts
  10. 0 62
      src/ libs/axios.ts
  11. 0 160
      src/ libs/file.ts
  12. 0 376
      src/ libs/tools.js
  13. 0 1093
      src/ libs/util.js
  14. 7 30
      src/App.vue
  15. 0 83
      src/api/module/file.js
  16. 0 120
      src/comm_js/index.js
  17. 0 35
      src/components/view_file/assets/excel_icon.svg
  18. 0 34
      src/components/view_file/assets/exe_icon.svg
  19. 0 54
      src/components/view_file/assets/folder_icon.svg
  20. 0 13
      src/components/view_file/assets/image_icon.svg
  21. 0 29
      src/components/view_file/assets/other_icon.svg
  22. 0 46
      src/components/view_file/assets/pdf_icon.svg
  23. 0 35
      src/components/view_file/assets/ppt_icon.svg
  24. 0 11
      src/components/view_file/assets/video_icon.svg
  25. 0 1
      src/components/view_file/assets/view_off.svg
  26. 0 35
      src/components/view_file/assets/word_icon.svg
  27. 0 24
      src/components/view_file/assets/zip_icon.svg
  28. 0 34
      src/components/view_file/index.less
  29. 0 180
      src/components/view_file/index.vue
  30. 0 102
      src/components/view_file/renders.js
  31. 0 41
      src/components/view_file/util.js
  32. 0 470
      src/components/view_file/vendors/colz/index.js
  33. 0 42
      src/components/view_file/vendors/image/ImageViewer.vue
  34. 0 13
      src/components/view_file/vendors/image/index.js
  35. 0 63
      src/components/view_file/vendors/other/index.vue
  36. 0 165
      src/components/view_file/vendors/pdf/PdfView.vue
  37. 0 8
      src/components/view_file/vendors/pdf/index.js
  38. 0 5051
      src/components/view_file/vendors/pptx/PPT.vue
  39. 0 25
      src/components/view_file/vendors/pptx/index.js
  40. 0 0
      src/components/view_file/vendors/pptx/libs/pptxToJson/index.js
  41. 0 31
      src/components/view_file/vendors/text/CodeViewer.vue
  42. 0 15
      src/components/view_file/vendors/text/index.js
  43. 0 807
      src/components/view_file/vendors/xlsx/Table.vue
  44. 0 69
      src/components/view_file/vendors/xlsx/color.js
  45. 0 27
      src/components/view_file/vendors/xlsx/index.js
  46. 0 49
      src/components/view_file/vendors/xlsx/util.js
  47. 0 61
      src/config/index.ts
  48. 9 16
      src/main.ts
  49. 11 13
      src/router/index.ts
  50. 0 63
      src/utils/pptxToJson/align.js
  51. 0 105
      src/utils/pptxToJson/border.js
  52. 0 210
      src/utils/pptxToJson/chart.js
  53. 0 176
      src/utils/pptxToJson/color.js
  54. 0 3
      src/utils/pptxToJson/constants.js
  55. 0 555
      src/utils/pptxToJson/fill.js
  56. 0 154
      src/utils/pptxToJson/fontStyle.js
  57. 0 182
      src/utils/pptxToJson/math.js
  58. 0 38
      src/utils/pptxToJson/position.js
  59. 0 1699
      src/utils/pptxToJson/pptxtojson.js
  60. 0 46
      src/utils/pptxToJson/readXmlFile.js
  61. 0 55
      src/utils/pptxToJson/schemeColor.js
  62. 0 19
      src/utils/pptxToJson/shadow.js
  63. 0 185
      src/utils/pptxToJson/shape.js
  64. 0 198
      src/utils/pptxToJson/table.js
  65. 0 284
      src/utils/pptxToJson/text.js
  66. 0 158
      src/utils/pptxToJson/utils.js
  67. 7 236
      src/views/index.vue
  68. 1 0
      src/vite-env.d.ts
  69. 14 0
      tsconfig.app.json
  70. 10 23
      tsconfig.json
  71. 24 0
      tsconfig.node.json
  72. 5 22
      vite.config.ts

+ 0 - 51
.eslintrc.js

@@ -1,51 +0,0 @@
-/*
- * @Author: mzr
- * @Date: 2023-04-07 14:59:16
- * @LastEditors: wzh
- * @LastEditTime: 2023-09-18 16:43:47
- * @Description:
- */
-module.exports = {
-  root: true,
-  parser: 'vue-eslint-parser',
-  parserOptions: {
-    // 指定ESlint的解析器
-    parser: '@typescript-eslint/parser',
-    // 允许使用ES语法
-    ecmaVersion: 2020,
-    // 允许使用import
-    sourceType: 'module',
-    // 允许解析JSX
-    ecmaFeatures: {
-      jsx: true,
-    },
-  },
-  env: {
-    browser: true,
-  },
-  extends: [
-    'plugin:vue/essential',
-    '@vue/standard',
-    'plugin:@typescript-eslint/recommended',
-    // '@vue/prettier',
-    // '@vue/prettier/@typescript-eslint'
-  ],
-  plugins: [
-    // 'vue'
-    '@typescript-eslint/eslint-plugin'
-  ],
-  rules: {
-    // allow debugger during development
-    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
-    'vue/no-parsing-error': [2, {
-      "x-invalid-end-tag": false
-    }],
-    '@typescript-eslint/no-explicit-any': 'off',
-    '@typescript-eslint/ban-ts-comment': 'off',
-    '@typescript-eslint/no-unused-vars': 0,
-    '@typescript-eslint/no-empty-function': 0,
-    '@typescript-eslint/no-this-alias': 0,
-    'vue/no-mutating-props': 'off',
-    'vue/script-setup-uses-vars': 'off'
-  }
-}

+ 0 - 2
.npmrc

@@ -1,2 +0,0 @@
-registry=http://nexus.wisdomcity.com.cn/repository/wisdomcity-npm-group/
-_auth=YWRtaW46V2lzZG9tY2l0eUBAMjAyMg==

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar"]
+}

+ 3 - 250
README.md

@@ -1,252 +1,5 @@
-<h2 id="rSVWk">1. 组件概述</h2>
-ViewFile 是一个功能强大的文件预览组件,支持多种文件格式的在线预览,包括文档、表格、演示文稿、图片和文本文件等。该组件能够根据文件类型自动选择合适的渲染器进行内容展示,为用户提供便捷的文件预览体验。
+# Vue 3 + TypeScript + Vite
 
-<h2 id="SK0VG">2. 组件结构</h2>
-ViewFile 组件采用模块化设计,主要包含以下部分:
-
-```plain
-view_file/
-├── index.vue          # 主组件入口
-├── index.less         # 样式文件
-├── util.js            # 工具函数
-├── renders.js         # 渲染器注册
-└── vendors/           # 各类型文件渲染器
-    ├── image/         # 图片渲染
-    ├── other/         # 不支持预览的文件处理
-    ├── pdf/           # PDF渲染
-    ├── pptx/          # PPT渲染
-    ├── text/          # 文本渲染
-    └── xlsx/          # Excel渲染
-    └── colz/          # Colz渲染    
-```
-
-<h2 id="shZJb">3. 使用方法</h2>
-<h3 id="i1B2h">3.1 基本用法</h3>
-1. 安装依赖包
-
-| 依赖包名称 | 版本 | 用途 |
-| :---: | :---: | :---: |
-| docx-preview | 0.3.5 | Word 文档预览 |
-| exceljs | 4.4.0 | Excel 文件解析 |
-| pdfjs-dist | 2.4.456  | PDF 文档预览 |
-| html2canvas | 1.4.1 | HTML 转图像 |
-| tinycolor2 | 1.6.0 | 颜色处理 |
-| x-data-spreadsheet | 1.1.9 | Excel 表格渲染 |
-| lodash-es | 4.17.21 | JavaScript 工具库 |
-| element-ui | 2.15.13 | el-image 显示图片 |
-
-
-```bash
-npm install docx-preview@0.3.5 exceljs@4.4.0 pdfjs-dist@2.4.456 html2canvas@1.4.1 tinycolor2@1.6.0 x-data-spreadsheet lodash-es element-ui
-```
-
-```bash
-yarn add docx-preview@0.3.5 exceljs@4.4.0 pdfjs-dist@2.4.456 html2canvas@1.4.1 tinycolor2@1.6.0 x-data-spreadsheet lodash-es element-ui
-```
-
-```bash
-pnpm add docx-preview@0.3.5 exceljs@4.4.0 pdfjs-dist@2.4.456 html2canvas@1.4.1 tinycolor2@1.6.0 x-data-spreadsheet lodash-es element-ui
-```
-
-2. 将viewFile组件源码移入项目components目录下在需要使用的页面中引入
-
-```vue
-<template>
-  <view-file
-    :file="fileObject" 
-    />
-</template>
-
-<script>
-  import ViewFile from "@/components/view_file/index.vue"
-
-  export default {
-    components: {
-      ViewFile
-    },
-    data() {
-      return {
-        fileObject: {
-          filename: "示例文件.docx",
-          type: "docx",
-          fileBuffer: null // ArrayBuffer类型的文件内容
-        }
-      }
-    }
-  }
-</script>
-```
-
-<h3 id="kWppv">3.2 参数说明</h3>
-Props
-
-| 参数名 | 类型 | 默认值 | 说明 | 是否必填 |
-| :---: | :---: | :---: | :---: | :---: |
-| file | Object | {} | 文件对象,包含文件名、类型和文件内容 | 是 |
-
-
-file 对象属性
-
-| 属性名 | 类型 | 说明 | 是否必填 |
-| :---: | :---: | :---: | :---: |
-| filename | String | 文件名称 | 是 |
-| type | String | 文件类型(扩展名,如docx、xlsx等) | 是 |
-| fileBuffer | ArrayBuffer | 文件内容的二进制数据 | 是 |
-
-
-<h2 id="lns5o">4. 支持的文件类型</h2>
-ViewFile 组件支持以下文件类型的在线预览:
-
-<h3 id="HGCfn">4.1 文档类</h3>
-+ Word文档 :docx
-+ PDF文档 :pdf
-
-<h3 id="d32Wg">4.2 表格类</h3>
-+ Excel表格 :xlsx
-
-<h3 id="DXweJ">4.3 演示文稿</h3>
-+ PowerPoint :pptx
-
-<h3 id="oH43n">4.4 图片类</h3>
-支持多种图片格式:
-
-+ gif
-+ jpg/jpeg
-+ bmp
-+ tiff/tif
-+ png
-+ svg
-
-<h3 id="ggdtM">4.5 文本类</h3>
-支持多种文本和代码文件:
-
-+ txt(纯文本)
-+ json(JSON数据)
-+ js(JavaScript)
-+ css(样式表)
-+ java(Java代码)
-+ py(Python代码)
-+ html(HTML文档)
-+ jsx(React JSX)
-+ ts/tsx(TypeScript)
-+ xml(XML文档)
-+ md(Markdown)
-+ log(日志文件)
-
-<h2 id="wc5fk">5. 示例代码</h2>
-<h3 id="XRxq1">5.1 从文件对象创建预览</h3>
-```vue
-<template>
-  <div>
-    <input type="file" @change="handleFileChange" />
-    <view-file
-      :file="fileObject" 
-    />
-  </div>
-</template>
-<script>
-import ViewFile from "@/components/view_file/index.vue"
-import { readBuffer } from "@/components/view_file/util"
-
-export default {
-  components: {
-    ViewFileComponent
-  },
-  data() {
-    return {
-      fileObject: {
-        filename: "",
-        type: "",
-        fileBuffer: null
-      }
-    }
-  },
-  methods: {
-    async handleFileChange(e) {
-      const file = e.target.files[0]
-      if (!file) return
-      try {
-        const buffer = await readBuffer(file)
-        this.fileObject = {
-          filename: file.name,
-          type: file.name.split('.').pop().toLowerCase(),
-          fileBuffer: buffer,
-        }
-      } catch (error) {
-        console.error('文件读取失败', error)
-      } 
-    }
-  }
-}
-</script>
-
-```
-
-<h3 id="GfNtc">5.2 从服务器获取文件并预览</h3>
-假设请求返回数据格式response.data
-
-| 属性名 | 类型 | 说明 |
-| :---: | :---: | :---: |
-| filename | String | 文件名称 |
-| file | Blob | 文件内容数据 |
-
-
-```vue
-<template>
-  <view-file 
-    :file="fileObject" 
-  />
-</template>
-<script>
-import ViewFile from "@/components/view_file/index.vue"
-import { readBuffer } from "@/components/view_file/util"
-import axios from 'axios'
-
-export default {
-  components: {
-    ViewFileComponent
-  },
-  data() {
-    return {
-      fileObject: {
-        filename: "",
-        type: "",
-        fileBuffer: null
-      }
-    }
-  },
-  methods: {
-    async fetchFile(fileId) {
-      try {
-        const response = await axios.get(`/api/files/${fileId}`)
-        const name = response.data.filename
-        // 获取文件名和类型
-        this.fileObject.filename = name
-        this.fileObject.type = name.split('.').pop().toLowerCase()
-        readBuffer(response.data.file).then((arrayBuffer) => {
-          this.fileObject.fileBuffer = arrayBuffer
-        })
-      } catch (error) {
-        console.error('文件获取失败', error)
-      }
-    }
-  },
-  mounted() {
-    // 假设从路由参数获取文件ID
-    const fileId = this.$route.params.fileId
-    if (fileId) {
-      this.fetchFile(fileId)
-    }
-  }
-}
-</script>
-
-```
-
-<h2 id="Dc4BG">6. 注意事项</h2>
-1. 确保提供正确的文件类型(扩展名),组件根据扩展名选择渲染器
-2. 文件内容必须是 ArrayBuffer 格式
-3. 大文件可能会影响性能,特别是复杂的Excel或PDF文件
-4. 对于不支持的文件类型,组件会显示提示信息而不是尝试渲染
-5. 组件内部已处理异常,但建议在外部添加错误处理逻辑
+This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
 
+Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).

+ 6 - 16
index.html

@@ -1,23 +1,13 @@
-<!--
- * @Author: LiZhiWei
- * @Date: 2025-04-09 09:04:17
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-09 10:17:33
- * @Description: 
--->
 <!doctype html>
 <html lang="en">
-
-<head>
+  <head>
     <meta charset="UTF-8" />
     <link rel="icon" type="image/svg+xml" href="/vite.svg" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite App</title>
-</head>
-
-<body>
+    <title>Vite + Vue + TS</title>
+  </head>
+  <body>
     <div id="app"></div>
     <script type="module" src="/src/main.ts"></script>
-</body>
-
-</html>
+  </body>
+</html>

+ 21 - 37
package.json

@@ -1,38 +1,22 @@
 {
-    "name": "preview-office",
-    "private": true,
-    "version": "0.0.0",
-    "type": "module",
-    "scripts": {
-        "dev": "vite",
-        "build": "tsc && vite build",
-        "preview": "vite preview"
-    },
-    "devDependencies": {
-        "@babel/types": "^7.27.0",
-        "@originjs/vite-plugin-require-context": "^1.0.9",
-        "less": "^4.3.0",
-        "typescript": "~5.7.2",
-        "vite": "^2.8.6",
-        "vite-plugin-vue2": "^2.0.3",
-        "vue-template-compiler": "^2.7.16"
-    },
-    "dependencies": {
-        "axios": "^1.8.4",
-        "docx-preview": "^0.3.5",
-        "element-ui": "^2.15.13",
-        "exceljs": "^4.4.0",
-        "file-saver": "^2.0.5",
-        "html2canvas": "^1.4.1",
-        "js-cookie": "^3.0.5",
-        "jszip": "^3.10.1",
-        "lodash-es": "^4.17.21",
-        "pdfjs-dist": "2.4.456",
-        "pptxtojson": "^1.3.1",
-        "tinycolor2": "^1.6.0",
-        "txml": "^5.1.1",
-        "vue": "2.7.16",
-        "vue-router": "^3.5.1",
-        "x-data-spreadsheet": "^1.1.9"
-    }
-}
+  "name": "wisdomcity-office",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vue-tsc -b && vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "vue": "^3.5.13",
+    "vue-router": "4"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^5.2.2",
+    "@vue/tsconfig": "^0.7.0",
+    "typescript": "~5.7.2",
+    "vite": "^6.3.1",
+    "vue-tsc": "^2.2.8"
+  }
+}

+ 639 - 2947
pnpm-lock.yaml

@@ -5,3151 +5,843 @@ settings:
   excludeLinksFromLockfile: false
 
 dependencies:
-  axios:
-    specifier: ^1.8.4
-    version: 1.8.4
-  docx-preview:
-    specifier: ^0.3.5
-    version: 0.3.5
-  element-ui:
-    specifier: ^2.15.13
-    version: 2.15.14(vue@2.7.16)
-  exceljs:
-    specifier: ^4.4.0
-    version: 4.4.0
-  file-saver:
-    specifier: ^2.0.5
-    version: 2.0.5
-  html2canvas:
-    specifier: ^1.4.1
-    version: 1.4.1
-  js-cookie:
-    specifier: ^3.0.5
-    version: 3.0.5
-  jszip:
-    specifier: ^3.10.1
-    version: 3.10.1
-  lodash-es:
-    specifier: ^4.17.21
-    version: 4.17.21
-  pdfjs-dist:
-    specifier: 2.4.456
-    version: 2.4.456
-  pptxtojson:
-    specifier: ^1.3.1
-    version: 1.3.1
-  tinycolor2:
-    specifier: ^1.6.0
-    version: 1.6.0
-  txml:
-    specifier: ^5.1.1
-    version: 5.1.1
   vue:
-    specifier: 2.7.16
-    version: 2.7.16
+    specifier: ^3.5.13
+    version: 3.5.13(typescript@5.7.3)
   vue-router:
-    specifier: ^3.5.1
-    version: 3.6.5(vue@2.7.16)
-  x-data-spreadsheet:
-    specifier: ^1.1.9
-    version: 1.1.9
+    specifier: '4'
+    version: 4.5.0(vue@3.5.13)
 
 devDependencies:
-  '@babel/types':
-    specifier: ^7.27.0
-    version: 7.27.0
-  '@originjs/vite-plugin-require-context':
-    specifier: ^1.0.9
-    version: 1.0.9
-  less:
-    specifier: ^4.3.0
-    version: 4.3.0
+  '@vitejs/plugin-vue':
+    specifier: ^5.2.2
+    version: 5.2.3(vite@6.3.3)(vue@3.5.13)
+  '@vue/tsconfig':
+    specifier: ^0.7.0
+    version: 0.7.0(typescript@5.7.3)(vue@3.5.13)
   typescript:
     specifier: ~5.7.2
     version: 5.7.3
   vite:
-    specifier: ^2.8.6
-    version: 2.9.18(less@4.3.0)
-  vite-plugin-vue2:
-    specifier: ^2.0.3
-    version: 2.0.3(vite@2.9.18)(vue-template-compiler@2.7.16)(vue@2.7.16)
-  vue-template-compiler:
-    specifier: ^2.7.16
-    version: 2.7.16
+    specifier: ^6.3.1
+    version: 6.3.3
+  vue-tsc:
+    specifier: ^2.2.8
+    version: 2.2.10(typescript@5.7.3)
 
 packages:
 
-  /@ampproject/remapping@2.3.0:
-    resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+  /@babel/helper-string-parser@7.25.9:
+    resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/helper-validator-identifier@7.25.9:
+    resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/parser@7.27.0:
+    resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==}
     engines: {node: '>=6.0.0'}
+    hasBin: true
     dependencies:
-      '@jridgewell/gen-mapping': 0.3.8
-      '@jridgewell/trace-mapping': 0.3.25
-    dev: true
+      '@babel/types': 7.27.0
 
-  /@babel/code-frame@7.26.2:
-    resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
+  /@babel/types@7.27.0:
+    resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
     engines: {node: '>=6.9.0'}
     dependencies:
+      '@babel/helper-string-parser': 7.25.9
       '@babel/helper-validator-identifier': 7.25.9
-      js-tokens: 4.0.0
-      picocolors: 1.1.1
-    dev: true
 
-  /@babel/compat-data@7.26.8:
-    resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==}
-    engines: {node: '>=6.9.0'}
+  /@esbuild/aix-ppc64@0.25.3:
+    resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==}
+    engines: {node: '>=18'}
+    cpu: [ppc64]
+    os: [aix]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/core@7.26.10:
-    resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@ampproject/remapping': 2.3.0
-      '@babel/code-frame': 7.26.2
-      '@babel/generator': 7.27.0
-      '@babel/helper-compilation-targets': 7.27.0
-      '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10)
-      '@babel/helpers': 7.27.0
-      '@babel/parser': 7.27.0
-      '@babel/template': 7.27.0
-      '@babel/traverse': 7.27.0
-      '@babel/types': 7.27.0
-      convert-source-map: 2.0.0
-      debug: 4.4.0
-      gensync: 1.0.0-beta.2
-      json5: 2.2.3
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/android-arm64@0.25.3:
+    resolution: {integrity: sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/generator@7.27.0:
-    resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/parser': 7.27.0
-      '@babel/types': 7.27.0
-      '@jridgewell/gen-mapping': 0.3.8
-      '@jridgewell/trace-mapping': 0.3.25
-      jsesc: 3.1.0
+  /@esbuild/android-arm@0.25.3:
+    resolution: {integrity: sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==}
+    engines: {node: '>=18'}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-annotate-as-pure@7.25.9:
-    resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.27.0
+  /@esbuild/android-x64@0.25.3:
+    resolution: {integrity: sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [android]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-compilation-targets@7.27.0:
-    resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/compat-data': 7.26.8
-      '@babel/helper-validator-option': 7.25.9
-      browserslist: 4.24.4
-      lru-cache: 5.1.1
-      semver: 6.3.1
+  /@esbuild/darwin-arm64@0.25.3:
+    resolution: {integrity: sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-create-class-features-plugin@7.27.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-annotate-as-pure': 7.25.9
-      '@babel/helper-member-expression-to-functions': 7.25.9
-      '@babel/helper-optimise-call-expression': 7.25.9
-      '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10)
-      '@babel/helper-skip-transparent-expression-wrappers': 7.25.9
-      '@babel/traverse': 7.27.0
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@babel/helper-member-expression-to-functions@7.25.9:
-    resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/traverse': 7.27.0
-      '@babel/types': 7.27.0
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/darwin-x64@0.25.3:
+    resolution: {integrity: sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-module-imports@7.25.9:
-    resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/traverse': 7.27.0
-      '@babel/types': 7.27.0
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/freebsd-arm64@0.25.3:
+    resolution: {integrity: sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-module-imports': 7.25.9
-      '@babel/helper-validator-identifier': 7.25.9
-      '@babel/traverse': 7.27.0
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/freebsd-x64@0.25.3:
+    resolution: {integrity: sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-optimise-call-expression@7.25.9:
-    resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.27.0
+  /@esbuild/linux-arm64@0.25.3:
+    resolution: {integrity: sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-plugin-utils@7.26.5:
-    resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==}
-    engines: {node: '>=6.9.0'}
+  /@esbuild/linux-arm@0.25.3:
+    resolution: {integrity: sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==}
+    engines: {node: '>=18'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-replace-supers@7.26.5(@babel/core@7.26.10):
-    resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-member-expression-to-functions': 7.25.9
-      '@babel/helper-optimise-call-expression': 7.25.9
-      '@babel/traverse': 7.27.0
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/linux-ia32@0.25.3:
+    resolution: {integrity: sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==}
+    engines: {node: '>=18'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-skip-transparent-expression-wrappers@7.25.9:
-    resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/traverse': 7.27.0
-      '@babel/types': 7.27.0
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/linux-loong64@0.25.3:
+    resolution: {integrity: sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==}
+    engines: {node: '>=18'}
+    cpu: [loong64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helper-string-parser@7.25.9:
-    resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
-    engines: {node: '>=6.9.0'}
-
-  /@babel/helper-validator-identifier@7.25.9:
-    resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
-    engines: {node: '>=6.9.0'}
+  /@esbuild/linux-mips64el@0.25.3:
+    resolution: {integrity: sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==}
+    engines: {node: '>=18'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
 
-  /@babel/helper-validator-option@7.25.9:
-    resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
-    engines: {node: '>=6.9.0'}
+  /@esbuild/linux-ppc64@0.25.3:
+    resolution: {integrity: sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==}
+    engines: {node: '>=18'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/helpers@7.27.0:
-    resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/template': 7.27.0
-      '@babel/types': 7.27.0
+  /@esbuild/linux-riscv64@0.25.3:
+    resolution: {integrity: sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==}
+    engines: {node: '>=18'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/parser@7.27.0:
-    resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==}
-    engines: {node: '>=6.0.0'}
-    hasBin: true
-    dependencies:
-      '@babel/types': 7.27.0
+  /@esbuild/linux-s390x@0.25.3:
+    resolution: {integrity: sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==}
+    engines: {node: '>=18'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
 
-  /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.26.10):
-    resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
-    engines: {node: '>=6.9.0'}
-    deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10)
-      '@babel/helper-plugin-utils': 7.26.5
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/linux-x64@0.25.3:
+    resolution: {integrity: sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-proposal-decorators@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10)
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.10)
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/netbsd-arm64@0.25.3:
+    resolution: {integrity: sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [netbsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.26.10):
-    resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==}
-    engines: {node: '>=6.9.0'}
-    deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.10)
+  /@esbuild/netbsd-x64@0.25.3:
+    resolution: {integrity: sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.26.10):
-    resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==}
-    engines: {node: '>=6.9.0'}
-    deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/compat-data': 7.26.8
-      '@babel/core': 7.26.10
-      '@babel/helper-compilation-targets': 7.27.0
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.10)
-      '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.10)
+  /@esbuild/openbsd-arm64@0.25.3:
+    resolution: {integrity: sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [openbsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==}
-    engines: {node: '>=6.9.0'}
-    deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/helper-skip-transparent-expression-wrappers': 7.25.9
-      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.10)
-    transitivePeerDependencies:
-      - supports-color
+  /@esbuild/openbsd-x64@0.25.3:
+    resolution: {integrity: sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@esbuild/sunos-x64@0.25.3:
+    resolution: {integrity: sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@esbuild/win32-arm64@0.25.3:
+    resolution: {integrity: sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==}
+    engines: {node: '>=18'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.10):
-    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@esbuild/win32-ia32@0.25.3:
+    resolution: {integrity: sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==}
+    engines: {node: '>=18'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.10):
-    resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@esbuild/win32-x64@0.25.3:
+    resolution: {integrity: sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==}
+    engines: {node: '>=18'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.10):
-    resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@jridgewell/sourcemap-codec@1.5.0:
+    resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+  /@rollup/rollup-android-arm-eabi@4.40.0:
+    resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@rollup/rollup-android-arm64@4.40.0:
+    resolution: {integrity: sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@rollup/rollup-darwin-arm64@4.40.0:
+    resolution: {integrity: sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-block-scoping@7.27.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@rollup/rollup-darwin-x64@4.40.0:
+    resolution: {integrity: sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/template': 7.27.0
+  /@rollup/rollup-freebsd-arm64@4.40.0:
+    resolution: {integrity: sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@rollup/rollup-freebsd-x64@4.40.0:
+    resolution: {integrity: sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-parameters@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
+  /@rollup/rollup-linux-arm-gnueabihf@4.40.0:
+    resolution: {integrity: sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-spread@7.25.9(@babel/core@7.26.10):
-    resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/helper-skip-transparent-expression-wrappers': 7.25.9
-    transitivePeerDependencies:
-      - supports-color
+  /@rollup/rollup-linux-arm-musleabihf@4.40.0:
+    resolution: {integrity: sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /@babel/plugin-transform-typescript@7.27.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-annotate-as-pure': 7.25.9
-      '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10)
-      '@babel/helper-plugin-utils': 7.26.5
-      '@babel/helper-skip-transparent-expression-wrappers': 7.25.9
-      '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10)
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@babel/template@7.27.0:
-    resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.26.2
-      '@babel/parser': 7.27.0
-      '@babel/types': 7.27.0
-    dev: true
-
-  /@babel/traverse@7.27.0:
-    resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.26.2
-      '@babel/generator': 7.27.0
-      '@babel/parser': 7.27.0
-      '@babel/template': 7.27.0
-      '@babel/types': 7.27.0
-      debug: 4.4.0
-      globals: 11.12.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@babel/types@7.27.0:
-    resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-string-parser': 7.25.9
-      '@babel/helper-validator-identifier': 7.25.9
-
-  /@esbuild/linux-loong64@0.14.54:
-    resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==}
-    engines: {node: '>=12'}
-    cpu: [loong64]
+  /@rollup/rollup-linux-arm64-gnu@4.40.0:
+    resolution: {integrity: sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==}
+    cpu: [arm64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@fast-csv/format@4.3.5:
-    resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==}
-    dependencies:
-      '@types/node': 14.18.63
-      lodash.escaperegexp: 4.1.2
-      lodash.isboolean: 3.0.3
-      lodash.isequal: 4.5.0
-      lodash.isfunction: 3.0.9
-      lodash.isnil: 4.0.0
-    dev: false
-
-  /@fast-csv/parse@4.3.6:
-    resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==}
-    dependencies:
-      '@types/node': 14.18.63
-      lodash.escaperegexp: 4.1.2
-      lodash.groupby: 4.6.0
-      lodash.isfunction: 3.0.9
-      lodash.isnil: 4.0.0
-      lodash.isundefined: 3.0.1
-      lodash.uniq: 4.5.0
-    dev: false
-
-  /@jest/types@26.6.2:
-    resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==}
-    engines: {node: '>= 10.14.2'}
-    dependencies:
-      '@types/istanbul-lib-coverage': 2.0.6
-      '@types/istanbul-reports': 3.0.4
-      '@types/node': 22.14.1
-      '@types/yargs': 15.0.19
-      chalk: 4.1.2
-    dev: true
-
-  /@jridgewell/gen-mapping@0.3.8:
-    resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
-    engines: {node: '>=6.0.0'}
-    dependencies:
-      '@jridgewell/set-array': 1.2.1
-      '@jridgewell/sourcemap-codec': 1.5.0
-      '@jridgewell/trace-mapping': 0.3.25
-    dev: true
-
-  /@jridgewell/resolve-uri@3.1.2:
-    resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
-    engines: {node: '>=6.0.0'}
-    dev: true
-
-  /@jridgewell/set-array@1.2.1:
-    resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
-    engines: {node: '>=6.0.0'}
-    dev: true
-
-  /@jridgewell/sourcemap-codec@1.5.0:
-    resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
-    dev: true
-
-  /@jridgewell/trace-mapping@0.3.25:
-    resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
-    dependencies:
-      '@jridgewell/resolve-uri': 3.1.2
-      '@jridgewell/sourcemap-codec': 1.5.0
-    dev: true
-
-  /@originjs/vite-plugin-require-context@1.0.9:
-    resolution: {integrity: sha512-xBC7XGm6HkniQ9x+P0yTS4uUua5bWKjnN0/FfHreCV22QrQ+zXIZVdCFDr0PPXuawXfPzqSzdljqffcpSCFNcA==}
-    dependencies:
-      '@types/jest': 26.0.24
-      node-dir: 0.1.17
-    dev: true
-
-  /@rollup/pluginutils@4.2.1:
-    resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
-    engines: {node: '>= 8.0.0'}
-    dependencies:
-      estree-walker: 2.0.2
-      picomatch: 2.3.1
-    dev: true
-
-  /@types/istanbul-lib-coverage@2.0.6:
-    resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
-    dev: true
-
-  /@types/istanbul-lib-report@3.0.3:
-    resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==}
-    dependencies:
-      '@types/istanbul-lib-coverage': 2.0.6
-    dev: true
-
-  /@types/istanbul-reports@3.0.4:
-    resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
-    dependencies:
-      '@types/istanbul-lib-report': 3.0.3
-    dev: true
-
-  /@types/jest@26.0.24:
-    resolution: {integrity: sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==}
-    dependencies:
-      jest-diff: 26.6.2
-      pretty-format: 26.6.2
-    dev: true
-
-  /@types/node@14.18.63:
-    resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==}
-    dev: false
-
-  /@types/node@22.14.1:
-    resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==}
-    dependencies:
-      undici-types: 6.21.0
-    dev: true
-
-  /@types/yargs-parser@21.0.3:
-    resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
-    dev: true
-
-  /@types/yargs@15.0.19:
-    resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==}
-    dependencies:
-      '@types/yargs-parser': 21.0.3
-    dev: true
-
-  /@vue/babel-helper-vue-jsx-merge-props@1.4.0:
-    resolution: {integrity: sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==}
-    dev: true
-
-  /@vue/babel-plugin-transform-vue-jsx@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/helper-module-imports': 7.25.9
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-      '@vue/babel-helper-vue-jsx-merge-props': 1.4.0
-      html-tags: 2.0.0
-      lodash.kebabcase: 4.1.1
-      svg-tags: 1.0.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@vue/babel-preset-jsx@1.4.0(@babel/core@7.26.10)(vue@2.7.16):
-    resolution: {integrity: sha512-QmfRpssBOPZWL5xw7fOuHNifCQcNQC1PrOo/4fu6xlhlKJJKSA3HqX92Nvgyx8fqHZTUGMPHmFA+IDqwXlqkSA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-      vue: '*'
-    peerDependenciesMeta:
-      vue:
-        optional: true
-    dependencies:
-      '@babel/core': 7.26.10
-      '@vue/babel-helper-vue-jsx-merge-props': 1.4.0
-      '@vue/babel-plugin-transform-vue-jsx': 1.4.0(@babel/core@7.26.10)
-      '@vue/babel-sugar-composition-api-inject-h': 1.4.0(@babel/core@7.26.10)
-      '@vue/babel-sugar-composition-api-render-instance': 1.4.0(@babel/core@7.26.10)
-      '@vue/babel-sugar-functional-vue': 1.4.0(@babel/core@7.26.10)
-      '@vue/babel-sugar-inject-h': 1.4.0(@babel/core@7.26.10)
-      '@vue/babel-sugar-v-model': 1.4.0(@babel/core@7.26.10)
-      '@vue/babel-sugar-v-on': 1.4.0(@babel/core@7.26.10)
-      vue: 2.7.16
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@vue/babel-sugar-composition-api-inject-h@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-VQq6zEddJHctnG4w3TfmlVp5FzDavUSut/DwR0xVoe/mJKXyMcsIibL42wPntozITEoY90aBV0/1d2KjxHU52g==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-    dev: true
-
-  /@vue/babel-sugar-composition-api-render-instance@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-6ZDAzcxvy7VcnCjNdHJ59mwK02ZFuP5CnucloidqlZwVQv5CQLijc3lGpR7MD3TWFi78J7+a8J56YxbCtHgT9Q==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-    dev: true
-
-  /@vue/babel-sugar-functional-vue@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-lTEB4WUFNzYt2In6JsoF9sAYVTo84wC4e+PoZWSgM6FUtqRJz7wMylaEhSRgG71YF+wfLD6cc9nqVeXN2rwBvw==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-    dev: true
-
-  /@vue/babel-sugar-inject-h@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-muwWrPKli77uO2fFM7eA3G1lAGnERuSz2NgAxuOLzrsTlQl8W4G+wwbM4nB6iewlKbwKRae3nL03UaF5ffAPMA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-    dev: true
-
-  /@vue/babel-sugar-v-model@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-0t4HGgXb7WHYLBciZzN5s0Hzqan4Ue+p/3FdQdcaHAb7s5D9WZFGoSxEZHrR1TFVZlAPu1bejTKGeAzaaG3NCQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-      '@vue/babel-helper-vue-jsx-merge-props': 1.4.0
-      '@vue/babel-plugin-transform-vue-jsx': 1.4.0(@babel/core@7.26.10)
-      camelcase: 5.3.1
-      html-tags: 2.0.0
-      svg-tags: 1.0.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@vue/babel-sugar-v-on@1.4.0(@babel/core@7.26.10):
-    resolution: {integrity: sha512-m+zud4wKLzSKgQrWwhqRObWzmTuyzl6vOP7024lrpeJM4x2UhQtRDLgYjXAw9xBXjCwS0pP9kXjg91F9ZNo9JA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
-      '@vue/babel-plugin-transform-vue-jsx': 1.4.0(@babel/core@7.26.10)
-      camelcase: 5.3.1
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@vue/compiler-sfc@2.7.16:
-    resolution: {integrity: sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==}
-    dependencies:
-      '@babel/parser': 7.27.0
-      postcss: 8.5.3
-      source-map: 0.6.1
-    optionalDependencies:
-      prettier: 2.8.8
-
-  /@vue/component-compiler-utils@3.3.0:
-    resolution: {integrity: sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==}
-    dependencies:
-      consolidate: 0.15.1
-      hash-sum: 1.0.2
-      lru-cache: 4.1.5
-      merge-source-map: 1.1.0
-      postcss: 7.0.39
-      postcss-selector-parser: 6.1.2
-      source-map: 0.6.1
-      vue-template-es2015-compiler: 1.9.1
-    optionalDependencies:
-      prettier: 2.8.8
-    transitivePeerDependencies:
-      - arc-templates
-      - atpl
-      - babel-core
-      - bracket-template
-      - coffee-script
-      - dot
-      - dust
-      - dustjs-helpers
-      - dustjs-linkedin
-      - eco
-      - ect
-      - ejs
-      - haml-coffee
-      - hamlet
-      - hamljs
-      - handlebars
-      - hogan.js
-      - htmling
-      - jade
-      - jazz
-      - jqtpl
-      - just
-      - liquid-node
-      - liquor
-      - lodash
-      - marko
-      - mote
-      - mustache
-      - nunjucks
-      - plates
-      - pug
-      - qejs
-      - ractive
-      - razor-tmpl
-      - react
-      - react-dom
-      - slm
-      - squirrelly
-      - swig
-      - swig-templates
-      - teacup
-      - templayed
-      - then-jade
-      - then-pug
-      - tinyliquid
-      - toffee
-      - twig
-      - twing
-      - underscore
-      - vash
-      - velocityjs
-      - walrus
-      - whiskers
-    dev: true
-
-  /ansi-escapes@1.4.0:
-    resolution: {integrity: sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /ansi-regex@2.1.1:
-    resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /ansi-regex@3.0.1:
-    resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==}
-    engines: {node: '>=4'}
-    dev: false
-
-  /ansi-regex@5.0.1:
-    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
-    engines: {node: '>=8'}
-    dev: true
-
-  /ansi-styles@2.2.1:
-    resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /ansi-styles@4.3.0:
-    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
-    engines: {node: '>=8'}
-    dependencies:
-      color-convert: 2.0.1
-    dev: true
-
-  /archiver-utils@2.1.0:
-    resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==}
-    engines: {node: '>= 6'}
-    dependencies:
-      glob: 7.2.3
-      graceful-fs: 4.2.11
-      lazystream: 1.0.1
-      lodash.defaults: 4.2.0
-      lodash.difference: 4.5.0
-      lodash.flatten: 4.4.0
-      lodash.isplainobject: 4.0.6
-      lodash.union: 4.6.0
-      normalize-path: 3.0.0
-      readable-stream: 2.3.8
-    dev: false
-
-  /archiver-utils@3.0.4:
-    resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==}
-    engines: {node: '>= 10'}
-    dependencies:
-      glob: 7.2.3
-      graceful-fs: 4.2.11
-      lazystream: 1.0.1
-      lodash.defaults: 4.2.0
-      lodash.difference: 4.5.0
-      lodash.flatten: 4.4.0
-      lodash.isplainobject: 4.0.6
-      lodash.union: 4.6.0
-      normalize-path: 3.0.0
-      readable-stream: 3.6.2
-    dev: false
-
-  /archiver@5.3.2:
-    resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==}
-    engines: {node: '>= 10'}
-    dependencies:
-      archiver-utils: 2.1.0
-      async: 3.2.6
-      buffer-crc32: 0.2.13
-      readable-stream: 3.6.2
-      readdir-glob: 1.1.3
-      tar-stream: 2.2.0
-      zip-stream: 4.1.1
-    dev: false
-
-  /async-validator@1.8.5:
-    resolution: {integrity: sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==}
-    dependencies:
-      babel-runtime: 6.26.0
-    dev: false
-
-  /async@3.2.6:
-    resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
-    dev: false
-
-  /asynckit@0.4.0:
-    resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
-    dev: false
-
-  /axios@1.8.4:
-    resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==}
-    dependencies:
-      follow-redirects: 1.15.9
-      form-data: 4.0.2
-      proxy-from-env: 1.1.0
-    transitivePeerDependencies:
-      - debug
-    dev: false
-
-  /babel-helper-vue-jsx-merge-props@2.0.3:
-    resolution: {integrity: sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==}
-    dev: false
-
-  /babel-polyfill@6.23.0:
-    resolution: {integrity: sha512-0l7mVU+LrQ2X/ZTUq63T5i3VyR2aTgcRTFmBcD6djQ/Fek6q1A9t5u0F4jZVYHzp78jwWAzGfLpAY1b4/I3lfg==}
-    dependencies:
-      babel-runtime: 6.26.0
-      core-js: 2.6.12
-      regenerator-runtime: 0.10.5
-    dev: false
-
-  /babel-runtime@6.26.0:
-    resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==}
-    dependencies:
-      core-js: 2.6.12
-      regenerator-runtime: 0.11.1
-    dev: false
-
-  /balanced-match@1.0.2:
-    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
-
-  /base64-arraybuffer@1.0.2:
-    resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
-    engines: {node: '>= 0.6.0'}
-    dev: false
-
-  /base64-js@1.5.1:
-    resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
-    dev: false
-
-  /big-integer@1.6.52:
-    resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==}
-    engines: {node: '>=0.6'}
-    dev: false
-
-  /binary@0.3.0:
-    resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==}
-    dependencies:
-      buffers: 0.1.1
-      chainsaw: 0.1.0
-    dev: false
-
-  /bl@4.1.0:
-    resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
-    dependencies:
-      buffer: 5.7.1
-      inherits: 2.0.4
-      readable-stream: 3.6.2
-    dev: false
-
-  /bluebird@3.4.7:
-    resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==}
-    dev: false
-
-  /bluebird@3.7.2:
-    resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
-    dev: true
-
-  /brace-expansion@1.1.11:
-    resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
-    dependencies:
-      balanced-match: 1.0.2
-      concat-map: 0.0.1
-
-  /brace-expansion@2.0.1:
-    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
-    dependencies:
-      balanced-match: 1.0.2
-    dev: false
-
-  /browserslist@4.24.4:
-    resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==}
-    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
-    hasBin: true
-    dependencies:
-      caniuse-lite: 1.0.30001715
-      electron-to-chromium: 1.5.139
-      node-releases: 2.0.19
-      update-browserslist-db: 1.1.3(browserslist@4.24.4)
-    dev: true
-
-  /buffer-crc32@0.2.13:
-    resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
-    dev: false
-
-  /buffer-indexof-polyfill@1.0.2:
-    resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==}
-    engines: {node: '>=0.10'}
-    dev: false
-
-  /buffer@5.7.1:
-    resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
-    dependencies:
-      base64-js: 1.5.1
-      ieee754: 1.2.1
-    dev: false
-
-  /buffers@0.1.1:
-    resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==}
-    engines: {node: '>=0.2.0'}
-    dev: false
-
-  /call-bind-apply-helpers@1.0.2:
-    resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      es-errors: 1.3.0
-      function-bind: 1.1.2
-    dev: false
-
-  /camelcase@5.3.1:
-    resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
-    engines: {node: '>=6'}
-    dev: true
-
-  /caniuse-lite@1.0.30001715:
-    resolution: {integrity: sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==}
-    dev: true
-
-  /chainsaw@0.1.0:
-    resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==}
-    dependencies:
-      traverse: 0.3.9
-    dev: false
-
-  /chalk@1.1.3:
-    resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      ansi-styles: 2.2.1
-      escape-string-regexp: 1.0.5
-      has-ansi: 2.0.0
-      strip-ansi: 3.0.1
-      supports-color: 2.0.0
-    dev: false
-
-  /chalk@4.1.2:
-    resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
-    engines: {node: '>=10'}
-    dependencies:
-      ansi-styles: 4.3.0
-      supports-color: 7.2.0
-    dev: true
-
-  /chardet@0.4.2:
-    resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==}
-    dev: false
-
-  /cli-cursor@2.1.0:
-    resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==}
-    engines: {node: '>=4'}
-    dependencies:
-      restore-cursor: 2.0.0
-    dev: false
-
-  /cli-width@2.2.1:
-    resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==}
-    dev: false
-
-  /color-convert@2.0.1:
-    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
-    engines: {node: '>=7.0.0'}
-    dependencies:
-      color-name: 1.1.4
-    dev: true
-
-  /color-name@1.1.4:
-    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-    dev: true
-
-  /combined-stream@1.0.8:
-    resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
-    engines: {node: '>= 0.8'}
-    dependencies:
-      delayed-stream: 1.0.0
-    dev: false
-
-  /compress-commons@4.1.2:
-    resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==}
-    engines: {node: '>= 10'}
-    dependencies:
-      buffer-crc32: 0.2.13
-      crc32-stream: 4.0.3
-      normalize-path: 3.0.0
-      readable-stream: 3.6.2
-    dev: false
-
-  /concat-map@0.0.1:
-    resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
-
-  /consolidate@0.15.1:
-    resolution: {integrity: sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==}
-    engines: {node: '>= 0.10.0'}
-    deprecated: Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog
-    peerDependencies:
-      arc-templates: ^0.5.3
-      atpl: '>=0.7.6'
-      babel-core: ^6.26.3
-      bracket-template: ^1.1.5
-      coffee-script: ^1.12.7
-      dot: ^1.1.3
-      dust: ^0.3.0
-      dustjs-helpers: ^1.7.4
-      dustjs-linkedin: ^2.7.5
-      eco: ^1.1.0-rc-3
-      ect: ^0.5.9
-      ejs: ^3.1.5
-      haml-coffee: ^1.14.1
-      hamlet: ^0.3.3
-      hamljs: ^0.6.2
-      handlebars: ^4.7.6
-      hogan.js: ^3.0.2
-      htmling: ^0.0.8
-      jade: ^1.11.0
-      jazz: ^0.0.18
-      jqtpl: ~1.1.0
-      just: ^0.1.8
-      liquid-node: ^3.0.1
-      liquor: ^0.0.5
-      lodash: ^4.17.20
-      marko: ^3.14.4
-      mote: ^0.2.0
-      mustache: ^3.0.0
-      nunjucks: ^3.2.2
-      plates: ~0.4.11
-      pug: ^3.0.0
-      qejs: ^3.0.5
-      ractive: ^1.3.12
-      razor-tmpl: ^1.3.1
-      react: ^16.13.1
-      react-dom: ^16.13.1
-      slm: ^2.0.0
-      squirrelly: ^5.1.0
-      swig: ^1.4.2
-      swig-templates: ^2.0.3
-      teacup: ^2.0.0
-      templayed: '>=0.2.3'
-      then-jade: '*'
-      then-pug: '*'
-      tinyliquid: ^0.2.34
-      toffee: ^0.3.6
-      twig: ^1.15.2
-      twing: ^5.0.2
-      underscore: ^1.11.0
-      vash: ^0.13.0
-      velocityjs: ^2.0.1
-      walrus: ^0.10.1
-      whiskers: ^0.4.0
-    peerDependenciesMeta:
-      arc-templates:
-        optional: true
-      atpl:
-        optional: true
-      babel-core:
-        optional: true
-      bracket-template:
-        optional: true
-      coffee-script:
-        optional: true
-      dot:
-        optional: true
-      dust:
-        optional: true
-      dustjs-helpers:
-        optional: true
-      dustjs-linkedin:
-        optional: true
-      eco:
-        optional: true
-      ect:
-        optional: true
-      ejs:
-        optional: true
-      haml-coffee:
-        optional: true
-      hamlet:
-        optional: true
-      hamljs:
-        optional: true
-      handlebars:
-        optional: true
-      hogan.js:
-        optional: true
-      htmling:
-        optional: true
-      jade:
-        optional: true
-      jazz:
-        optional: true
-      jqtpl:
-        optional: true
-      just:
-        optional: true
-      liquid-node:
-        optional: true
-      liquor:
-        optional: true
-      lodash:
-        optional: true
-      marko:
-        optional: true
-      mote:
-        optional: true
-      mustache:
-        optional: true
-      nunjucks:
-        optional: true
-      plates:
-        optional: true
-      pug:
-        optional: true
-      qejs:
-        optional: true
-      ractive:
-        optional: true
-      razor-tmpl:
-        optional: true
-      react:
-        optional: true
-      react-dom:
-        optional: true
-      slm:
-        optional: true
-      squirrelly:
-        optional: true
-      swig:
-        optional: true
-      swig-templates:
-        optional: true
-      teacup:
-        optional: true
-      templayed:
-        optional: true
-      then-jade:
-        optional: true
-      then-pug:
-        optional: true
-      tinyliquid:
-        optional: true
-      toffee:
-        optional: true
-      twig:
-        optional: true
-      twing:
-        optional: true
-      underscore:
-        optional: true
-      vash:
-        optional: true
-      velocityjs:
-        optional: true
-      walrus:
-        optional: true
-      whiskers:
-        optional: true
-    dependencies:
-      bluebird: 3.7.2
-    dev: true
-
-  /consolidate@0.16.0:
-    resolution: {integrity: sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==}
-    engines: {node: '>= 0.10.0'}
-    deprecated: Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog
-    peerDependencies:
-      arc-templates: ^0.5.3
-      atpl: '>=0.7.6'
-      babel-core: ^6.26.3
-      bracket-template: ^1.1.5
-      coffee-script: ^1.12.7
-      dot: ^1.1.3
-      dust: ^0.3.0
-      dustjs-helpers: ^1.7.4
-      dustjs-linkedin: ^2.7.5
-      eco: ^1.1.0-rc-3
-      ect: ^0.5.9
-      ejs: ^3.1.5
-      haml-coffee: ^1.14.1
-      hamlet: ^0.3.3
-      hamljs: ^0.6.2
-      handlebars: ^4.7.6
-      hogan.js: ^3.0.2
-      htmling: ^0.0.8
-      jade: ^1.11.0
-      jazz: ^0.0.18
-      jqtpl: ~1.1.0
-      just: ^0.1.8
-      liquid-node: ^3.0.1
-      liquor: ^0.0.5
-      lodash: ^4.17.20
-      marko: ^3.14.4
-      mote: ^0.2.0
-      mustache: ^4.0.1
-      nunjucks: ^3.2.2
-      plates: ~0.4.11
-      pug: ^3.0.0
-      qejs: ^3.0.5
-      ractive: ^1.3.12
-      razor-tmpl: ^1.3.1
-      react: ^16.13.1
-      react-dom: ^16.13.1
-      slm: ^2.0.0
-      squirrelly: ^5.1.0
-      swig: ^1.4.2
-      swig-templates: ^2.0.3
-      teacup: ^2.0.0
-      templayed: '>=0.2.3'
-      then-jade: '*'
-      then-pug: '*'
-      tinyliquid: ^0.2.34
-      toffee: ^0.3.6
-      twig: ^1.15.2
-      twing: ^5.0.2
-      underscore: ^1.11.0
-      vash: ^0.13.0
-      velocityjs: ^2.0.1
-      walrus: ^0.10.1
-      whiskers: ^0.4.0
-    peerDependenciesMeta:
-      arc-templates:
-        optional: true
-      atpl:
-        optional: true
-      babel-core:
-        optional: true
-      bracket-template:
-        optional: true
-      coffee-script:
-        optional: true
-      dot:
-        optional: true
-      dust:
-        optional: true
-      dustjs-helpers:
-        optional: true
-      dustjs-linkedin:
-        optional: true
-      eco:
-        optional: true
-      ect:
-        optional: true
-      ejs:
-        optional: true
-      haml-coffee:
-        optional: true
-      hamlet:
-        optional: true
-      hamljs:
-        optional: true
-      handlebars:
-        optional: true
-      hogan.js:
-        optional: true
-      htmling:
-        optional: true
-      jade:
-        optional: true
-      jazz:
-        optional: true
-      jqtpl:
-        optional: true
-      just:
-        optional: true
-      liquid-node:
-        optional: true
-      liquor:
-        optional: true
-      lodash:
-        optional: true
-      marko:
-        optional: true
-      mote:
-        optional: true
-      mustache:
-        optional: true
-      nunjucks:
-        optional: true
-      plates:
-        optional: true
-      pug:
-        optional: true
-      qejs:
-        optional: true
-      ractive:
-        optional: true
-      razor-tmpl:
-        optional: true
-      react:
-        optional: true
-      react-dom:
-        optional: true
-      slm:
-        optional: true
-      squirrelly:
-        optional: true
-      swig:
-        optional: true
-      swig-templates:
-        optional: true
-      teacup:
-        optional: true
-      templayed:
-        optional: true
-      then-jade:
-        optional: true
-      then-pug:
-        optional: true
-      tinyliquid:
-        optional: true
-      toffee:
-        optional: true
-      twig:
-        optional: true
-      twing:
-        optional: true
-      underscore:
-        optional: true
-      vash:
-        optional: true
-      velocityjs:
-        optional: true
-      walrus:
-        optional: true
-      whiskers:
-        optional: true
-    dependencies:
-      bluebird: 3.7.2
-    dev: true
-
-  /convert-source-map@2.0.0:
-    resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
-    dev: true
-
-  /copy-anything@2.0.6:
-    resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
-    dependencies:
-      is-what: 3.14.1
-    dev: true
-
-  /core-js@2.6.12:
-    resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
-    deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
-    requiresBuild: true
-    dev: false
-
-  /core-util-is@1.0.3:
-    resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
-    dev: false
-
-  /crc-32@1.2.2:
-    resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
-    engines: {node: '>=0.8'}
-    hasBin: true
-    dev: false
-
-  /crc32-stream@4.0.3:
-    resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==}
-    engines: {node: '>= 10'}
-    dependencies:
-      crc-32: 1.2.2
-      readable-stream: 3.6.2
-    dev: false
-
-  /css-line-break@2.1.0:
-    resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
-    dependencies:
-      utrie: 1.0.2
-    dev: false
-
-  /cssesc@3.0.0:
-    resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
-    engines: {node: '>=4'}
-    hasBin: true
-    dev: true
-
-  /csstype@3.1.3:
-    resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
-
-  /dayjs@1.11.13:
-    resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
-    dev: false
-
-  /de-indent@1.0.2:
-    resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
-    dev: true
-
-  /debug@4.4.0:
-    resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
-    engines: {node: '>=6.0'}
-    peerDependencies:
-      supports-color: '*'
-    peerDependenciesMeta:
-      supports-color:
-        optional: true
-    dependencies:
-      ms: 2.1.3
-    dev: true
-
-  /deepmerge@1.5.2:
-    resolution: {integrity: sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /deepmerge@4.3.1:
-    resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
-    engines: {node: '>=0.10.0'}
-    dev: true
-
-  /delayed-stream@1.0.0:
-    resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
-    engines: {node: '>=0.4.0'}
-    dev: false
-
-  /diff-sequences@26.6.2:
-    resolution: {integrity: sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==}
-    engines: {node: '>= 10.14.2'}
-    dev: true
-
-  /docx-preview@0.3.5:
-    resolution: {integrity: sha512-nod1jG5PkvzDIiZAcgAY4gSFQzgmAAChcuZH4Hj9dj7oCzscY3Hn8NfbUv7X7Jk4xL1lfKO113JLDhWKOt6fYw==}
-    dependencies:
-      jszip: 3.10.1
-    dev: false
-
-  /dunder-proto@1.0.1:
-    resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      call-bind-apply-helpers: 1.0.2
-      es-errors: 1.3.0
-      gopd: 1.2.0
-    dev: false
-
-  /duplexer2@0.1.4:
-    resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==}
-    dependencies:
-      readable-stream: 2.3.8
-    dev: false
-
-  /electron-to-chromium@1.5.139:
-    resolution: {integrity: sha512-GGnRYOTdN5LYpwbIr0rwP/ZHOQSvAF6TG0LSzp28uCBb9JiXHJGmaaKw29qjNJc5bGnnp6kXJqRnGMQoELwi5w==}
-    dev: true
-
-  /element-ui@2.15.14(vue@2.7.16):
-    resolution: {integrity: sha512-2v9fHL0ZGINotOlRIAJD5YuVB8V7WKxrE9Qy7dXhRipa035+kF7WuU/z+tEmLVPBcJ0zt8mOu1DKpWcVzBK8IA==}
-    peerDependencies:
-      vue: ^2.5.17
-    dependencies:
-      async-validator: 1.8.5
-      babel-helper-vue-jsx-merge-props: 2.0.3
-      deepmerge: 1.5.2
-      normalize-wheel: 1.0.1
-      resize-observer-polyfill: 1.5.1
-      throttle-debounce: 1.1.0
-      vue: 2.7.16
-    dev: false
-
-  /encoding@0.1.13:
-    resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
-    dependencies:
-      iconv-lite: 0.6.3
-    dev: false
-
-  /end-of-stream@1.4.4:
-    resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
-    dependencies:
-      once: 1.4.0
-    dev: false
-
-  /errno@0.1.8:
-    resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
-    hasBin: true
-    requiresBuild: true
-    dependencies:
-      prr: 1.0.1
-    dev: true
-    optional: true
-
-  /es-define-property@1.0.1:
-    resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
-    engines: {node: '>= 0.4'}
-    dev: false
-
-  /es-errors@1.3.0:
-    resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
-    engines: {node: '>= 0.4'}
-    dev: false
-
-  /es-object-atoms@1.1.1:
-    resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      es-errors: 1.3.0
-    dev: false
-
-  /es-set-tostringtag@2.1.0:
-    resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      es-errors: 1.3.0
-      get-intrinsic: 1.3.0
-      has-tostringtag: 1.0.2
-      hasown: 2.0.2
-    dev: false
-
-  /esbuild-android-64@0.14.54:
-    resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-android-arm64@0.14.54:
-    resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-darwin-64@0.14.54:
-    resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-darwin-arm64@0.14.54:
-    resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-freebsd-64@0.14.54:
-    resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-freebsd-arm64@0.14.54:
-    resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-32@0.14.54:
-    resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-64@0.14.54:
-    resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-arm64@0.14.54:
-    resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-arm@0.14.54:
-    resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-mips64le@0.14.54:
-    resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==}
-    engines: {node: '>=12'}
-    cpu: [mips64el]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-ppc64le@0.14.54:
-    resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-riscv64@0.14.54:
-    resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==}
-    engines: {node: '>=12'}
-    cpu: [riscv64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-linux-s390x@0.14.54:
-    resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==}
-    engines: {node: '>=12'}
-    cpu: [s390x]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-netbsd-64@0.14.54:
-    resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [netbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-openbsd-64@0.14.54:
-    resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [openbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-sunos-64@0.14.54:
-    resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [sunos]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-windows-32@0.14.54:
-    resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-windows-64@0.14.54:
-    resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild-windows-arm64@0.14.54:
-    resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /esbuild@0.14.54:
-    resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==}
-    engines: {node: '>=12'}
-    hasBin: true
-    requiresBuild: true
-    optionalDependencies:
-      '@esbuild/linux-loong64': 0.14.54
-      esbuild-android-64: 0.14.54
-      esbuild-android-arm64: 0.14.54
-      esbuild-darwin-64: 0.14.54
-      esbuild-darwin-arm64: 0.14.54
-      esbuild-freebsd-64: 0.14.54
-      esbuild-freebsd-arm64: 0.14.54
-      esbuild-linux-32: 0.14.54
-      esbuild-linux-64: 0.14.54
-      esbuild-linux-arm: 0.14.54
-      esbuild-linux-arm64: 0.14.54
-      esbuild-linux-mips64le: 0.14.54
-      esbuild-linux-ppc64le: 0.14.54
-      esbuild-linux-riscv64: 0.14.54
-      esbuild-linux-s390x: 0.14.54
-      esbuild-netbsd-64: 0.14.54
-      esbuild-openbsd-64: 0.14.54
-      esbuild-sunos-64: 0.14.54
-      esbuild-windows-32: 0.14.54
-      esbuild-windows-64: 0.14.54
-      esbuild-windows-arm64: 0.14.54
-    dev: true
-
-  /escalade@3.2.0:
-    resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
-    engines: {node: '>=6'}
-    dev: true
-
-  /escape-string-regexp@1.0.5:
-    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
-    engines: {node: '>=0.8.0'}
-    dev: false
-
-  /estree-walker@2.0.2:
-    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
-    dev: true
-
-  /exceljs@4.4.0:
-    resolution: {integrity: sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==}
-    engines: {node: '>=8.3.0'}
-    dependencies:
-      archiver: 5.3.2
-      dayjs: 1.11.13
-      fast-csv: 4.3.6
-      jszip: 3.10.1
-      readable-stream: 3.6.2
-      saxes: 5.0.1
-      tmp: 0.2.3
-      unzipper: 0.10.14
-      uuid: 8.3.2
-    dev: false
-
-  /external-editor@2.2.0:
-    resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==}
-    engines: {node: '>=0.12'}
-    dependencies:
-      chardet: 0.4.2
-      iconv-lite: 0.4.24
-      tmp: 0.0.33
-    dev: false
-
-  /fast-csv@4.3.6:
-    resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==}
-    engines: {node: '>=10.0.0'}
-    dependencies:
-      '@fast-csv/format': 4.3.5
-      '@fast-csv/parse': 4.3.6
-    dev: false
-
-  /figures@2.0.0:
-    resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==}
-    engines: {node: '>=4'}
-    dependencies:
-      escape-string-regexp: 1.0.5
-    dev: false
-
-  /file-saver@2.0.5:
-    resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
-    dev: false
-
-  /follow-redirects@1.15.9:
-    resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
-    engines: {node: '>=4.0'}
-    peerDependencies:
-      debug: '*'
-    peerDependenciesMeta:
-      debug:
-        optional: true
-    dev: false
-
-  /form-data@4.0.2:
-    resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
-    engines: {node: '>= 6'}
-    dependencies:
-      asynckit: 0.4.0
-      combined-stream: 1.0.8
-      es-set-tostringtag: 2.1.0
-      mime-types: 2.1.35
-    dev: false
-
-  /fs-constants@1.0.0:
-    resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
-    dev: false
-
-  /fs-extra@10.1.0:
-    resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
-    engines: {node: '>=12'}
-    dependencies:
-      graceful-fs: 4.2.11
-      jsonfile: 6.1.0
-      universalify: 2.0.1
-    dev: true
-
-  /fs.realpath@1.0.0:
-    resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
-    dev: false
-
-  /fsevents@2.3.3:
-    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
-    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /fstream@1.0.12:
-    resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==}
-    engines: {node: '>=0.6'}
-    deprecated: This package is no longer supported.
-    dependencies:
-      graceful-fs: 4.2.11
-      inherits: 2.0.4
-      mkdirp: 0.5.6
-      rimraf: 2.7.1
-    dev: false
-
-  /function-bind@1.1.2:
-    resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
-
-  /gensync@1.0.0-beta.2:
-    resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
-    engines: {node: '>=6.9.0'}
-    dev: true
-
-  /get-intrinsic@1.3.0:
-    resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      call-bind-apply-helpers: 1.0.2
-      es-define-property: 1.0.1
-      es-errors: 1.3.0
-      es-object-atoms: 1.1.1
-      function-bind: 1.1.2
-      get-proto: 1.0.1
-      gopd: 1.2.0
-      has-symbols: 1.1.0
-      hasown: 2.0.2
-      math-intrinsics: 1.1.0
-    dev: false
-
-  /get-proto@1.0.1:
-    resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      dunder-proto: 1.0.1
-      es-object-atoms: 1.1.1
-    dev: false
-
-  /glob@7.2.3:
-    resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
-    deprecated: Glob versions prior to v9 are no longer supported
-    dependencies:
-      fs.realpath: 1.0.0
-      inflight: 1.0.6
-      inherits: 2.0.4
-      minimatch: 3.1.2
-      once: 1.4.0
-      path-is-absolute: 1.0.1
-    dev: false
-
-  /globals@11.12.0:
-    resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
-    engines: {node: '>=4'}
-    dev: true
-
-  /gopd@1.2.0:
-    resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
-    engines: {node: '>= 0.4'}
-    dev: false
-
-  /graceful-fs@4.2.11:
-    resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
-
-  /has-ansi@2.0.0:
-    resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      ansi-regex: 2.1.1
-    dev: false
-
-  /has-flag@4.0.0:
-    resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
-    engines: {node: '>=8'}
-    dev: true
-
-  /has-symbols@1.1.0:
-    resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
-    engines: {node: '>= 0.4'}
-    dev: false
-
-  /has-tostringtag@1.0.2:
-    resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      has-symbols: 1.1.0
-    dev: false
-
-  /hash-sum@1.0.2:
-    resolution: {integrity: sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==}
-    dev: true
-
-  /hash-sum@2.0.0:
-    resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
-    dev: true
-
-  /hasown@2.0.2:
-    resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      function-bind: 1.1.2
-
-  /he@1.2.0:
-    resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
-    hasBin: true
-    dev: true
-
-  /html-tags@2.0.0:
-    resolution: {integrity: sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==}
-    engines: {node: '>=4'}
-    dev: true
-
-  /html2canvas@1.4.1:
-    resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
-    engines: {node: '>=8.0.0'}
-    dependencies:
-      css-line-break: 2.1.0
-      text-segmentation: 1.0.3
-    dev: false
-
-  /iconv-lite@0.4.24:
-    resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      safer-buffer: 2.1.2
-    dev: false
-
-  /iconv-lite@0.6.3:
-    resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      safer-buffer: 2.1.2
-
-  /ieee754@1.2.1:
-    resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
-    dev: false
-
-  /image-size@0.5.5:
-    resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
-    engines: {node: '>=0.10.0'}
-    hasBin: true
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /immediate@3.0.6:
-    resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
-    dev: false
-
-  /inflight@1.0.6:
-    resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
-    deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
-    dependencies:
-      once: 1.4.0
-      wrappy: 1.0.2
-    dev: false
-
-  /inherits@2.0.4:
-    resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
-    dev: false
-
-  /inquirer@3.0.6:
-    resolution: {integrity: sha512-thluxTGBXUGb8DuQcvH9/CM/CrcGyB5xUpWc9x6Slqcq1z/hRr2a6KxUpX4ddRfmbe0hg3E4jTvo5833aWz3BA==}
-    dependencies:
-      ansi-escapes: 1.4.0
-      chalk: 1.1.3
-      cli-cursor: 2.1.0
-      cli-width: 2.2.1
-      external-editor: 2.2.0
-      figures: 2.0.0
-      lodash: 4.17.21
-      mute-stream: 0.0.7
-      run-async: 2.4.1
-      rx: 4.1.0
-      string-width: 2.1.1
-      strip-ansi: 3.0.1
-      through: 2.3.8
-    dev: false
-
-  /is-core-module@2.16.1:
-    resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      hasown: 2.0.2
-    dev: true
-
-  /is-fullwidth-code-point@2.0.0:
-    resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==}
-    engines: {node: '>=4'}
-    dev: false
-
-  /is-stream@1.1.0:
-    resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /is-what@3.14.1:
-    resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
-    dev: true
-
-  /isarray@1.0.0:
-    resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
-    dev: false
-
-  /jest-diff@26.6.2:
-    resolution: {integrity: sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==}
-    engines: {node: '>= 10.14.2'}
-    dependencies:
-      chalk: 4.1.2
-      diff-sequences: 26.6.2
-      jest-get-type: 26.3.0
-      pretty-format: 26.6.2
-    dev: true
-
-  /jest-get-type@26.3.0:
-    resolution: {integrity: sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==}
-    engines: {node: '>= 10.14.2'}
-    dev: true
-
-  /js-cookie@3.0.5:
-    resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
-    engines: {node: '>=14'}
-    dev: false
-
-  /js-tokens@4.0.0:
-    resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
-    dev: true
-
-  /jsesc@3.1.0:
-    resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
-    engines: {node: '>=6'}
-    hasBin: true
-    dev: true
-
-  /json5@2.2.3:
-    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
-    engines: {node: '>=6'}
-    hasBin: true
-    dev: true
-
-  /jsonfile@6.1.0:
-    resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
-    dependencies:
-      universalify: 2.0.1
-    optionalDependencies:
-      graceful-fs: 4.2.11
-    dev: true
-
-  /jszip@3.10.1:
-    resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
-    dependencies:
-      lie: 3.3.0
-      pako: 1.0.11
-      readable-stream: 2.3.8
-      setimmediate: 1.0.5
-    dev: false
-
-  /lazystream@1.0.1:
-    resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
-    engines: {node: '>= 0.6.3'}
-    dependencies:
-      readable-stream: 2.3.8
-    dev: false
-
-  /less@4.3.0:
-    resolution: {integrity: sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==}
-    engines: {node: '>=14'}
-    hasBin: true
-    dependencies:
-      copy-anything: 2.0.6
-      parse-node-version: 1.0.1
-      tslib: 2.8.1
-    optionalDependencies:
-      errno: 0.1.8
-      graceful-fs: 4.2.11
-      image-size: 0.5.5
-      make-dir: 2.1.0
-      mime: 1.6.0
-      needle: 3.3.1
-      source-map: 0.6.1
-    dev: true
-
-  /lie@3.3.0:
-    resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
-    dependencies:
-      immediate: 3.0.6
-    dev: false
-
-  /listenercount@1.0.1:
-    resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==}
-    dev: false
-
-  /lodash-es@4.17.21:
-    resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
-    dev: false
-
-  /lodash.defaults@4.2.0:
-    resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
-    dev: false
-
-  /lodash.difference@4.5.0:
-    resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==}
-    dev: false
-
-  /lodash.escaperegexp@4.1.2:
-    resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==}
-    dev: false
-
-  /lodash.flatten@4.4.0:
-    resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==}
-    dev: false
-
-  /lodash.groupby@4.6.0:
-    resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==}
-    dev: false
-
-  /lodash.isboolean@3.0.3:
-    resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
-    dev: false
-
-  /lodash.isequal@4.5.0:
-    resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
-    deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
-    dev: false
-
-  /lodash.isfunction@3.0.9:
-    resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==}
-    dev: false
-
-  /lodash.isnil@4.0.0:
-    resolution: {integrity: sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==}
-    dev: false
-
-  /lodash.isplainobject@4.0.6:
-    resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
-    dev: false
-
-  /lodash.isundefined@3.0.1:
-    resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==}
-    dev: false
-
-  /lodash.kebabcase@4.1.1:
-    resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==}
-    dev: true
-
-  /lodash.union@4.6.0:
-    resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==}
-    dev: false
-
-  /lodash.uniq@4.5.0:
-    resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
-    dev: false
-
-  /lodash@4.17.21:
-    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
-    dev: false
-
-  /lru-cache@4.1.5:
-    resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
-    dependencies:
-      pseudomap: 1.0.2
-      yallist: 2.1.2
-    dev: true
-
-  /lru-cache@5.1.1:
-    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
-    dependencies:
-      yallist: 3.1.1
-    dev: true
-
-  /magic-string@0.26.7:
-    resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==}
-    engines: {node: '>=12'}
-    dependencies:
-      sourcemap-codec: 1.4.8
-    dev: true
-
-  /make-dir@2.1.0:
-    resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
-    engines: {node: '>=6'}
-    requiresBuild: true
-    dependencies:
-      pify: 4.0.1
-      semver: 5.7.2
-    dev: true
-    optional: true
-
-  /math-intrinsics@1.1.0:
-    resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
-    engines: {node: '>= 0.4'}
-    dev: false
-
-  /merge-source-map@1.1.0:
-    resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==}
-    dependencies:
-      source-map: 0.6.1
-    dev: true
-
-  /mime-db@1.52.0:
-    resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
-    engines: {node: '>= 0.6'}
-    dev: false
-
-  /mime-types@2.1.35:
-    resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
-    engines: {node: '>= 0.6'}
-    dependencies:
-      mime-db: 1.52.0
-    dev: false
-
-  /mime@1.6.0:
-    resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
-    engines: {node: '>=4'}
-    hasBin: true
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /mimic-fn@1.2.0:
-    resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==}
-    engines: {node: '>=4'}
-    dev: false
-
-  /minimatch@3.1.2:
-    resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
-    dependencies:
-      brace-expansion: 1.1.11
-
-  /minimatch@5.1.6:
-    resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
-    engines: {node: '>=10'}
-    dependencies:
-      brace-expansion: 2.0.1
-    dev: false
-
-  /minimist@1.2.0:
-    resolution: {integrity: sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==}
-    dev: false
-
-  /minimist@1.2.8:
-    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
-    dev: false
-
-  /mkdirp@0.5.6:
-    resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
-    hasBin: true
-    dependencies:
-      minimist: 1.2.8
-    dev: false
-
-  /ms@2.1.3:
-    resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
-    dev: true
-
-  /mute-stream@0.0.7:
-    resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==}
-    dev: false
-
-  /nanoid@3.3.11:
-    resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
-    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
-    hasBin: true
-
-  /needle@3.3.1:
-    resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
-    engines: {node: '>= 4.4.x'}
-    hasBin: true
-    requiresBuild: true
-    dependencies:
-      iconv-lite: 0.6.3
-      sax: 1.4.1
-    dev: true
-    optional: true
-
-  /node-dir@0.1.17:
-    resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==}
-    engines: {node: '>= 0.10.5'}
-    dependencies:
-      minimatch: 3.1.2
-    dev: true
-
-  /node-fetch@1.6.3:
-    resolution: {integrity: sha512-BDxbhLHXFFFvilHjh9xihcDyPkXQ+kjblxnl82zAX41xUYSNvuRpFRznmldR9+OKu+p+ULZ7hNoyunlLB5ecUA==}
-    dependencies:
-      encoding: 0.1.13
-      is-stream: 1.1.0
-    dev: false
-
-  /node-releases@2.0.19:
-    resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
-    dev: true
-
-  /normalize-path@3.0.0:
-    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /normalize-wheel@1.0.1:
-    resolution: {integrity: sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==}
-    dev: false
-
-  /object-assign@4.1.1:
-    resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /once@1.4.0:
-    resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
-    dependencies:
-      wrappy: 1.0.2
-    dev: false
-
-  /onetime@2.0.1:
-    resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==}
-    engines: {node: '>=4'}
-    dependencies:
-      mimic-fn: 1.2.0
-    dev: false
-
-  /opencollective-postinstall@2.0.3:
-    resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==}
-    hasBin: true
-    dev: false
-
-  /opencollective@1.0.3:
-    resolution: {integrity: sha512-YBRI0Qa8+Ui0/STV1qYuPrJm889PT3oCPHMVoL+8Y3nwCffj7PSrB2NlGgrhgBKDujxTjxknHWJ/FiqOsYcIDw==}
-    hasBin: true
-    dependencies:
-      babel-polyfill: 6.23.0
-      chalk: 1.1.3
-      inquirer: 3.0.6
-      minimist: 1.2.0
-      node-fetch: 1.6.3
-      opn: 4.0.2
-    dev: false
-
-  /opn@4.0.2:
-    resolution: {integrity: sha512-iPBWbPP4OEOzR1xfhpGLDh+ypKBOygunZhM9jBtA7FS5sKjEiMZw0EFb82hnDOmTZX90ZWLoZKUza4cVt8MexA==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      object-assign: 4.1.1
-      pinkie-promise: 2.0.1
-    dev: false
-
-  /os-tmpdir@1.0.2:
-    resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /pako@1.0.11:
-    resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
-    dev: false
-
-  /parse-node-version@1.0.1:
-    resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
-    engines: {node: '>= 0.10'}
-    dev: true
-
-  /path-is-absolute@1.0.1:
-    resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /path-parse@1.0.7:
-    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
-    dev: true
-
-  /pdfjs-dist@2.4.456:
-    resolution: {integrity: sha512-yckJEHq3F48hcp6wStEpbN9McOj328Ib09UrBlGAKxvN2k+qYPN5iq6TH6jD1C0pso7zTep+g/CKsYgdrQd5QA==}
-    dev: false
-
-  /picocolors@0.2.1:
-    resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==}
-    dev: true
-
-  /picocolors@1.1.1:
-    resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
-
-  /picomatch@2.3.1:
-    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
-    engines: {node: '>=8.6'}
-    dev: true
-
-  /pify@4.0.1:
-    resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
-    engines: {node: '>=6'}
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /pinkie-promise@2.0.1:
-    resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      pinkie: 2.0.4
-    dev: false
-
-  /pinkie@2.0.4:
-    resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
-  /postcss-selector-parser@6.1.2:
-    resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
-    engines: {node: '>=4'}
-    dependencies:
-      cssesc: 3.0.0
-      util-deprecate: 1.0.2
-    dev: true
-
-  /postcss@7.0.39:
-    resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==}
-    engines: {node: '>=6.0.0'}
-    dependencies:
-      picocolors: 0.2.1
-      source-map: 0.6.1
-    dev: true
-
-  /postcss@8.5.3:
-    resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
-    engines: {node: ^10 || ^12 || >=14}
-    dependencies:
-      nanoid: 3.3.11
-      picocolors: 1.1.1
-      source-map-js: 1.2.1
-
-  /pptxtojson@1.3.1:
-    resolution: {integrity: sha512-+FcSS70PTkgdlExXCEUoNL2DZcySueonyYpnQANeD6BW1AX8313o6zF71t5wN7tnO1cxh1p0/J90fBV5yMzTCA==}
-    dependencies:
-      jszip: 3.10.1
-      tinycolor2: 1.6.0
-      txml: 5.1.1
-    dev: false
-
-  /prettier@2.8.8:
-    resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
-    engines: {node: '>=10.13.0'}
-    hasBin: true
-
-  /pretty-format@26.6.2:
-    resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==}
-    engines: {node: '>= 10'}
-    dependencies:
-      '@jest/types': 26.6.2
-      ansi-regex: 5.0.1
-      ansi-styles: 4.3.0
-      react-is: 17.0.2
-    dev: true
-
-  /process-nextick-args@2.0.1:
-    resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
-    dev: false
-
-  /proxy-from-env@1.1.0:
-    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
-    dev: false
-
-  /prr@1.0.1:
-    resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+  /@rollup/rollup-linux-arm64-musl@4.40.0:
+    resolution: {integrity: sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==}
+    cpu: [arm64]
+    os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /pseudomap@1.0.2:
-    resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
+  /@rollup/rollup-linux-loongarch64-gnu@4.40.0:
+    resolution: {integrity: sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==}
+    cpu: [loong64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /querystring@0.2.1:
-    resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==}
-    engines: {node: '>=0.4.x'}
-    deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
+  /@rollup/rollup-linux-powerpc64le-gnu@4.40.0:
+    resolution: {integrity: sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /react-is@17.0.2:
-    resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+  /@rollup/rollup-linux-riscv64-gnu@4.40.0:
+    resolution: {integrity: sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /readable-stream@2.3.8:
-    resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
-    dependencies:
-      core-util-is: 1.0.3
-      inherits: 2.0.4
-      isarray: 1.0.0
-      process-nextick-args: 2.0.1
-      safe-buffer: 5.1.2
-      string_decoder: 1.1.1
-      util-deprecate: 1.0.2
-    dev: false
-
-  /readable-stream@3.6.2:
-    resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
-    engines: {node: '>= 6'}
-    dependencies:
-      inherits: 2.0.4
-      string_decoder: 1.3.0
-      util-deprecate: 1.0.2
-    dev: false
-
-  /readdir-glob@1.1.3:
-    resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==}
-    dependencies:
-      minimatch: 5.1.6
-    dev: false
-
-  /regenerator-runtime@0.10.5:
-    resolution: {integrity: sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==}
-    dev: false
-
-  /regenerator-runtime@0.11.1:
-    resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==}
-    dev: false
-
-  /resize-observer-polyfill@1.5.1:
-    resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
-    dev: false
-
-  /resolve@1.22.10:
-    resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
-    engines: {node: '>= 0.4'}
-    hasBin: true
-    dependencies:
-      is-core-module: 2.16.1
-      path-parse: 1.0.7
-      supports-preserve-symlinks-flag: 1.0.0
+  /@rollup/rollup-linux-riscv64-musl@4.40.0:
+    resolution: {integrity: sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /restore-cursor@2.0.0:
-    resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==}
-    engines: {node: '>=4'}
-    dependencies:
-      onetime: 2.0.1
-      signal-exit: 3.0.7
-    dev: false
-
-  /rimraf@2.7.1:
-    resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
-    deprecated: Rimraf versions prior to v4 are no longer supported
-    hasBin: true
-    dependencies:
-      glob: 7.2.3
-    dev: false
-
-  /rollup@2.77.3:
-    resolution: {integrity: sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==}
-    engines: {node: '>=10.0.0'}
-    hasBin: true
-    optionalDependencies:
-      fsevents: 2.3.3
+  /@rollup/rollup-linux-s390x-gnu@4.40.0:
+    resolution: {integrity: sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /rollup@2.79.2:
-    resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==}
-    engines: {node: '>=10.0.0'}
-    hasBin: true
-    optionalDependencies:
-      fsevents: 2.3.3
+  /@rollup/rollup-linux-x64-gnu@4.40.0:
+    resolution: {integrity: sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /run-async@2.4.1:
-    resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
-    engines: {node: '>=0.12.0'}
-    dev: false
-
-  /rx@4.1.0:
-    resolution: {integrity: sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==}
-    dev: false
-
-  /safe-buffer@5.1.2:
-    resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
-    dev: false
-
-  /safe-buffer@5.2.1:
-    resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
-    dev: false
-
-  /safer-buffer@2.1.2:
-    resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
-
-  /sax@1.4.1:
-    resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
+  /@rollup/rollup-linux-x64-musl@4.40.0:
+    resolution: {integrity: sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==}
+    cpu: [x64]
+    os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /saxes@5.0.1:
-    resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==}
-    engines: {node: '>=10'}
-    dependencies:
-      xmlchars: 2.2.0
-    dev: false
-
-  /semver@5.7.2:
-    resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
-    hasBin: true
+  /@rollup/rollup-win32-arm64-msvc@4.40.0:
+    resolution: {integrity: sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==}
+    cpu: [arm64]
+    os: [win32]
     requiresBuild: true
     dev: true
     optional: true
 
-  /semver@6.3.1:
-    resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
-    hasBin: true
+  /@rollup/rollup-win32-ia32-msvc@4.40.0:
+    resolution: {integrity: sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /setimmediate@1.0.5:
-    resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
-    dev: false
-
-  /signal-exit@3.0.7:
-    resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
-    dev: false
+  /@rollup/rollup-win32-x64-msvc@4.40.0:
+    resolution: {integrity: sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
 
-  /slash@3.0.0:
-    resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
-    engines: {node: '>=8'}
+  /@types/estree@1.0.7:
+    resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
     dev: true
 
-  /source-map-js@1.2.1:
-    resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
-    engines: {node: '>=0.10.0'}
+  /@vitejs/plugin-vue@5.2.3(vite@6.3.3)(vue@3.5.13):
+    resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    peerDependencies:
+      vite: ^5.0.0 || ^6.0.0
+      vue: ^3.2.25
+    dependencies:
+      vite: 6.3.3
+      vue: 3.5.13(typescript@5.7.3)
+    dev: true
 
-  /source-map@0.6.1:
-    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
-    engines: {node: '>=0.10.0'}
+  /@volar/language-core@2.4.12:
+    resolution: {integrity: sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==}
+    dependencies:
+      '@volar/source-map': 2.4.12
+    dev: true
 
-  /source-map@0.7.4:
-    resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
-    engines: {node: '>= 8'}
+  /@volar/source-map@2.4.12:
+    resolution: {integrity: sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==}
     dev: true
 
-  /sourcemap-codec@1.4.8:
-    resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
-    deprecated: Please use @jridgewell/sourcemap-codec instead
+  /@volar/typescript@2.4.12:
+    resolution: {integrity: sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==}
+    dependencies:
+      '@volar/language-core': 2.4.12
+      path-browserify: 1.0.1
+      vscode-uri: 3.1.0
     dev: true
 
-  /string-width@2.1.1:
-    resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==}
-    engines: {node: '>=4'}
+  /@vue/compiler-core@3.5.13:
+    resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
     dependencies:
-      is-fullwidth-code-point: 2.0.0
-      strip-ansi: 4.0.0
-    dev: false
+      '@babel/parser': 7.27.0
+      '@vue/shared': 3.5.13
+      entities: 4.5.0
+      estree-walker: 2.0.2
+      source-map-js: 1.2.1
 
-  /string_decoder@1.1.1:
-    resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+  /@vue/compiler-dom@3.5.13:
+    resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==}
     dependencies:
-      safe-buffer: 5.1.2
-    dev: false
+      '@vue/compiler-core': 3.5.13
+      '@vue/shared': 3.5.13
 
-  /string_decoder@1.3.0:
-    resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+  /@vue/compiler-sfc@3.5.13:
+    resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==}
     dependencies:
-      safe-buffer: 5.2.1
-    dev: false
+      '@babel/parser': 7.27.0
+      '@vue/compiler-core': 3.5.13
+      '@vue/compiler-dom': 3.5.13
+      '@vue/compiler-ssr': 3.5.13
+      '@vue/shared': 3.5.13
+      estree-walker: 2.0.2
+      magic-string: 0.30.17
+      postcss: 8.5.3
+      source-map-js: 1.2.1
 
-  /strip-ansi@3.0.1:
-    resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==}
-    engines: {node: '>=0.10.0'}
+  /@vue/compiler-ssr@3.5.13:
+    resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==}
     dependencies:
-      ansi-regex: 2.1.1
-    dev: false
+      '@vue/compiler-dom': 3.5.13
+      '@vue/shared': 3.5.13
 
-  /strip-ansi@4.0.0:
-    resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==}
-    engines: {node: '>=4'}
+  /@vue/compiler-vue2@2.7.16:
+    resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
     dependencies:
-      ansi-regex: 3.0.1
-    dev: false
+      de-indent: 1.0.2
+      he: 1.2.0
+    dev: true
 
-  /supports-color@2.0.0:
-    resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==}
-    engines: {node: '>=0.8.0'}
+  /@vue/devtools-api@6.6.4:
+    resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
     dev: false
 
-  /supports-color@7.2.0:
-    resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
-    engines: {node: '>=8'}
+  /@vue/language-core@2.2.10(typescript@5.7.3):
+    resolution: {integrity: sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      has-flag: 4.0.0
+      '@volar/language-core': 2.4.12
+      '@vue/compiler-dom': 3.5.13
+      '@vue/compiler-vue2': 2.7.16
+      '@vue/shared': 3.5.13
+      alien-signals: 1.0.13
+      minimatch: 9.0.5
+      muggle-string: 0.4.1
+      path-browserify: 1.0.1
+      typescript: 5.7.3
     dev: true
 
-  /supports-preserve-symlinks-flag@1.0.0:
-    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
-    engines: {node: '>= 0.4'}
-    dev: true
+  /@vue/reactivity@3.5.13:
+    resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==}
+    dependencies:
+      '@vue/shared': 3.5.13
 
-  /svg-tags@1.0.0:
-    resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
-    dev: true
+  /@vue/runtime-core@3.5.13:
+    resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==}
+    dependencies:
+      '@vue/reactivity': 3.5.13
+      '@vue/shared': 3.5.13
 
-  /tar-stream@2.2.0:
-    resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
-    engines: {node: '>=6'}
+  /@vue/runtime-dom@3.5.13:
+    resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==}
     dependencies:
-      bl: 4.1.0
-      end-of-stream: 1.4.4
-      fs-constants: 1.0.0
-      inherits: 2.0.4
-      readable-stream: 3.6.2
-    dev: false
+      '@vue/reactivity': 3.5.13
+      '@vue/runtime-core': 3.5.13
+      '@vue/shared': 3.5.13
+      csstype: 3.1.3
 
-  /text-segmentation@1.0.3:
-    resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
+  /@vue/server-renderer@3.5.13(vue@3.5.13):
+    resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==}
+    peerDependencies:
+      vue: 3.5.13
     dependencies:
-      utrie: 1.0.2
-    dev: false
+      '@vue/compiler-ssr': 3.5.13
+      '@vue/shared': 3.5.13
+      vue: 3.5.13(typescript@5.7.3)
 
-  /throttle-debounce@1.1.0:
-    resolution: {integrity: sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg==}
-    engines: {node: '>=4'}
-    dev: false
+  /@vue/shared@3.5.13:
+    resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
 
-  /through2@3.0.2:
-    resolution: {integrity: sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==}
+  /@vue/tsconfig@0.7.0(typescript@5.7.3)(vue@3.5.13):
+    resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==}
+    peerDependencies:
+      typescript: 5.x
+      vue: ^3.4.0
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+      vue:
+        optional: true
     dependencies:
-      inherits: 2.0.4
-      readable-stream: 3.6.2
-    dev: false
+      typescript: 5.7.3
+      vue: 3.5.13(typescript@5.7.3)
+    dev: true
 
-  /through@2.3.8:
-    resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
-    dev: false
+  /alien-signals@1.0.13:
+    resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
+    dev: true
 
-  /tinycolor2@1.6.0:
-    resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
-    dev: false
+  /balanced-match@1.0.2:
+    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+    dev: true
 
-  /tmp@0.0.33:
-    resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
-    engines: {node: '>=0.6.0'}
+  /brace-expansion@2.0.1:
+    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
     dependencies:
-      os-tmpdir: 1.0.2
-    dev: false
+      balanced-match: 1.0.2
+    dev: true
 
-  /tmp@0.2.3:
-    resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==}
-    engines: {node: '>=14.14'}
-    dev: false
+  /csstype@3.1.3:
+    resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
 
-  /traverse@0.3.9:
-    resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==}
-    dev: false
+  /de-indent@1.0.2:
+    resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+    dev: true
+
+  /entities@4.5.0:
+    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+    engines: {node: '>=0.12'}
 
-  /tslib@2.8.1:
-    resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+  /esbuild@0.25.3:
+    resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==}
+    engines: {node: '>=18'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      '@esbuild/aix-ppc64': 0.25.3
+      '@esbuild/android-arm': 0.25.3
+      '@esbuild/android-arm64': 0.25.3
+      '@esbuild/android-x64': 0.25.3
+      '@esbuild/darwin-arm64': 0.25.3
+      '@esbuild/darwin-x64': 0.25.3
+      '@esbuild/freebsd-arm64': 0.25.3
+      '@esbuild/freebsd-x64': 0.25.3
+      '@esbuild/linux-arm': 0.25.3
+      '@esbuild/linux-arm64': 0.25.3
+      '@esbuild/linux-ia32': 0.25.3
+      '@esbuild/linux-loong64': 0.25.3
+      '@esbuild/linux-mips64el': 0.25.3
+      '@esbuild/linux-ppc64': 0.25.3
+      '@esbuild/linux-riscv64': 0.25.3
+      '@esbuild/linux-s390x': 0.25.3
+      '@esbuild/linux-x64': 0.25.3
+      '@esbuild/netbsd-arm64': 0.25.3
+      '@esbuild/netbsd-x64': 0.25.3
+      '@esbuild/openbsd-arm64': 0.25.3
+      '@esbuild/openbsd-x64': 0.25.3
+      '@esbuild/sunos-x64': 0.25.3
+      '@esbuild/win32-arm64': 0.25.3
+      '@esbuild/win32-ia32': 0.25.3
+      '@esbuild/win32-x64': 0.25.3
     dev: true
 
-  /txml@5.1.1:
-    resolution: {integrity: sha512-TwMDLnXQ09enNaxybLVvKZU7rqog8LgnuAs4ZYXM0nV0eu10iLsSFwlX3AEknAXXtH1wT3CYfoiXAjyBexcmuw==}
+  /estree-walker@2.0.2:
+    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+  /fdir@6.4.4(picomatch@4.0.2):
+    resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
+    peerDependencies:
+      picomatch: ^3 || ^4
+    peerDependenciesMeta:
+      picomatch:
+        optional: true
     dependencies:
-      through2: 3.0.2
-    dev: false
+      picomatch: 4.0.2
+    dev: true
 
-  /typescript@5.7.3:
-    resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
-    engines: {node: '>=14.17'}
+  /fsevents@2.3.3:
+    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /he@1.2.0:
+    resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
     hasBin: true
     dev: true
 
-  /undici-types@6.21.0:
-    resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+  /magic-string@0.30.17:
+    resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.5.0
+
+  /minimatch@9.0.5:
+    resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+    engines: {node: '>=16 || 14 >=14.17'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: true
+
+  /muggle-string@0.4.1:
+    resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+    dev: true
+
+  /nanoid@3.3.11:
+    resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+
+  /path-browserify@1.0.1:
+    resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
     dev: true
 
-  /universalify@2.0.1:
-    resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
-    engines: {node: '>= 10.0.0'}
+  /picocolors@1.1.1:
+    resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+  /picomatch@4.0.2:
+    resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+    engines: {node: '>=12'}
     dev: true
 
-  /unzipper@0.10.14:
-    resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==}
+  /postcss@8.5.3:
+    resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
+    engines: {node: ^10 || ^12 || >=14}
     dependencies:
-      big-integer: 1.6.52
-      binary: 0.3.0
-      bluebird: 3.4.7
-      buffer-indexof-polyfill: 1.0.2
-      duplexer2: 0.1.4
-      fstream: 1.0.12
-      graceful-fs: 4.2.11
-      listenercount: 1.0.1
-      readable-stream: 2.3.8
-      setimmediate: 1.0.5
-    dev: false
+      nanoid: 3.3.11
+      picocolors: 1.1.1
+      source-map-js: 1.2.1
 
-  /update-browserslist-db@1.1.3(browserslist@4.24.4):
-    resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
+  /rollup@4.40.0:
+    resolution: {integrity: sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==}
+    engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
-    peerDependencies:
-      browserslist: '>= 4.21.0'
     dependencies:
-      browserslist: 4.24.4
-      escalade: 3.2.0
-      picocolors: 1.1.1
+      '@types/estree': 1.0.7
+    optionalDependencies:
+      '@rollup/rollup-android-arm-eabi': 4.40.0
+      '@rollup/rollup-android-arm64': 4.40.0
+      '@rollup/rollup-darwin-arm64': 4.40.0
+      '@rollup/rollup-darwin-x64': 4.40.0
+      '@rollup/rollup-freebsd-arm64': 4.40.0
+      '@rollup/rollup-freebsd-x64': 4.40.0
+      '@rollup/rollup-linux-arm-gnueabihf': 4.40.0
+      '@rollup/rollup-linux-arm-musleabihf': 4.40.0
+      '@rollup/rollup-linux-arm64-gnu': 4.40.0
+      '@rollup/rollup-linux-arm64-musl': 4.40.0
+      '@rollup/rollup-linux-loongarch64-gnu': 4.40.0
+      '@rollup/rollup-linux-powerpc64le-gnu': 4.40.0
+      '@rollup/rollup-linux-riscv64-gnu': 4.40.0
+      '@rollup/rollup-linux-riscv64-musl': 4.40.0
+      '@rollup/rollup-linux-s390x-gnu': 4.40.0
+      '@rollup/rollup-linux-x64-gnu': 4.40.0
+      '@rollup/rollup-linux-x64-musl': 4.40.0
+      '@rollup/rollup-win32-arm64-msvc': 4.40.0
+      '@rollup/rollup-win32-ia32-msvc': 4.40.0
+      '@rollup/rollup-win32-x64-msvc': 4.40.0
+      fsevents: 2.3.3
     dev: true
 
-  /util-deprecate@1.0.2:
-    resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+  /source-map-js@1.2.1:
+    resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+    engines: {node: '>=0.10.0'}
 
-  /utrie@1.0.2:
-    resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
+  /tinyglobby@0.2.13:
+    resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
+    engines: {node: '>=12.0.0'}
     dependencies:
-      base64-arraybuffer: 1.0.2
-    dev: false
+      fdir: 6.4.4(picomatch@4.0.2)
+      picomatch: 4.0.2
+    dev: true
 
-  /uuid@8.3.2:
-    resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
+  /typescript@5.7.3:
+    resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
+    engines: {node: '>=14.17'}
     hasBin: true
-    dev: false
 
-  /vite-plugin-vue2@2.0.3(vite@2.9.18)(vue-template-compiler@2.7.16)(vue@2.7.16):
-    resolution: {integrity: sha512-t3Tu93GWsMHbpeIv66MTO5e/rRAo8/+/eWoUtFYuAdKDMyEnn1dqsrXh+CfG+SJAlxJvcTP8U0eXkzhLjKNyMg==}
-    peerDependencies:
-      vite: ^2.0.0 || ^3.0.0 || ^4.0.0
-      vue-template-compiler: ^2.2.0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/parser': 7.27.0
-      '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.26.10)
-      '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.26.10)
-      '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.26.10)
-      '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.26.10)
-      '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-block-scoping': 7.27.0(@babel/core@7.26.10)
-      '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-typescript': 7.27.0(@babel/core@7.26.10)
-      '@rollup/pluginutils': 4.2.1
-      '@vue/babel-helper-vue-jsx-merge-props': 1.4.0
-      '@vue/babel-preset-jsx': 1.4.0(@babel/core@7.26.10)(vue@2.7.16)
-      '@vue/component-compiler-utils': 3.3.0
-      consolidate: 0.16.0
-      debug: 4.4.0
-      fs-extra: 10.1.0
-      hash-sum: 2.0.0
-      magic-string: 0.26.7
-      prettier: 2.8.8
-      querystring: 0.2.1
-      rollup: 2.79.2
-      slash: 3.0.0
-      source-map: 0.7.4
-      vite: 2.9.18(less@4.3.0)
-      vue-template-babel-compiler: 1.2.0(vue-template-compiler@2.7.16)
-      vue-template-compiler: 2.7.16
-    transitivePeerDependencies:
-      - arc-templates
-      - atpl
-      - babel-core
-      - bracket-template
-      - coffee-script
-      - dot
-      - dust
-      - dustjs-helpers
-      - dustjs-linkedin
-      - eco
-      - ect
-      - ejs
-      - haml-coffee
-      - hamlet
-      - hamljs
-      - handlebars
-      - hogan.js
-      - htmling
-      - jade
-      - jazz
-      - jqtpl
-      - just
-      - liquid-node
-      - liquor
-      - lodash
-      - marko
-      - mote
-      - mustache
-      - nunjucks
-      - plates
-      - pug
-      - qejs
-      - ractive
-      - razor-tmpl
-      - react
-      - react-dom
-      - slm
-      - squirrelly
-      - supports-color
-      - swig
-      - swig-templates
-      - teacup
-      - templayed
-      - then-jade
-      - then-pug
-      - tinyliquid
-      - toffee
-      - twig
-      - twing
-      - underscore
-      - vash
-      - velocityjs
-      - vue
-      - walrus
-      - whiskers
-    dev: true
-
-  /vite@2.9.18(less@4.3.0):
-    resolution: {integrity: sha512-sAOqI5wNM9QvSEE70W3UGMdT8cyEn0+PmJMTFvTB8wB0YbYUWw3gUbY62AOyrXosGieF2htmeLATvNxpv/zNyQ==}
-    engines: {node: '>=12.2.0'}
+  /vite@6.3.3:
+    resolution: {integrity: sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==}
+    engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
     peerDependencies:
+      '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+      jiti: '>=1.21.0'
       less: '*'
+      lightningcss: ^1.21.0
       sass: '*'
+      sass-embedded: '*'
       stylus: '*'
+      sugarss: '*'
+      terser: ^5.16.0
+      tsx: ^4.8.1
+      yaml: ^2.4.2
     peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      jiti:
+        optional: true
       less:
         optional: true
+      lightningcss:
+        optional: true
       sass:
         optional: true
+      sass-embedded:
+        optional: true
       stylus:
         optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+      tsx:
+        optional: true
+      yaml:
+        optional: true
     dependencies:
-      esbuild: 0.14.54
-      less: 4.3.0
+      esbuild: 0.25.3
+      fdir: 6.4.4(picomatch@4.0.2)
+      picomatch: 4.0.2
       postcss: 8.5.3
-      resolve: 1.22.10
-      rollup: 2.77.3
+      rollup: 4.40.0
+      tinyglobby: 0.2.13
     optionalDependencies:
       fsevents: 2.3.3
     dev: true
 
-  /vue-router@3.6.5(vue@2.7.16):
-    resolution: {integrity: sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==}
-    peerDependencies:
-      vue: ^2
-    dependencies:
-      vue: 2.7.16
-    dev: false
-
-  /vue-template-babel-compiler@1.2.0(vue-template-compiler@2.7.16):
-    resolution: {integrity: sha512-CScBSX1/wCdmmZ/Lvj/63p2CCVTS0FMj0F69VRBo73CuJrjvPAPGmeNJ7D/cwt/VS2PduowRWbO8N4Zh4Z3b0g==}
-    engines: {node: '>=12.0.0'}
-    peerDependencies:
-      vue-template-compiler: ^2.6.0
-    dependencies:
-      '@babel/core': 7.26.10
-      '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.26.10)
-      '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.26.10)
-      '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.26.10)
-      '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-block-scoping': 7.27.0(@babel/core@7.26.10)
-      '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.10)
-      '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.10)
-      '@babel/types': 7.27.0
-      deepmerge: 4.3.1
-      vue-template-compiler: 2.7.16
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /vue-template-compiler@2.7.16:
-    resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==}
-    dependencies:
-      de-indent: 1.0.2
-      he: 1.2.0
-    dev: true
-
-  /vue-template-es2015-compiler@1.9.1:
-    resolution: {integrity: sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==}
+  /vscode-uri@3.1.0:
+    resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
     dev: true
 
-  /vue@2.7.16:
-    resolution: {integrity: sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==}
-    deprecated: Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.
+  /vue-router@4.5.0(vue@3.5.13):
+    resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==}
+    peerDependencies:
+      vue: ^3.2.0
     dependencies:
-      '@vue/compiler-sfc': 2.7.16
-      csstype: 3.1.3
-
-  /wrappy@1.0.2:
-    resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+      '@vue/devtools-api': 6.6.4
+      vue: 3.5.13(typescript@5.7.3)
     dev: false
 
-  /x-data-spreadsheet@1.1.9:
-    resolution: {integrity: sha512-wk7knDBYdHjtWiHUVQryZMy00dsGNCF+6wMb5ykwEFcAtBYkYZakJCOCHpEo8onC0Lb/q2gIynWpbQxA4qakyg==}
-    requiresBuild: true
+  /vue-tsc@2.2.10(typescript@5.7.3):
+    resolution: {integrity: sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==}
+    hasBin: true
+    peerDependencies:
+      typescript: '>=5.0.0'
     dependencies:
-      opencollective: 1.0.3
-      opencollective-postinstall: 2.0.3
-    dev: false
-
-  /xmlchars@2.2.0:
-    resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
-    dev: false
-
-  /yallist@2.1.2:
-    resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
-    dev: true
-
-  /yallist@3.1.1:
-    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+      '@volar/typescript': 2.4.12
+      '@vue/language-core': 2.2.10(typescript@5.7.3)
+      typescript: 5.7.3
     dev: true
 
-  /zip-stream@4.1.1:
-    resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==}
-    engines: {node: '>= 10'}
+  /vue@3.5.13(typescript@5.7.3):
+    resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      archiver-utils: 3.0.4
-      compress-commons: 4.1.2
-      readable-stream: 3.6.2
-    dev: false
+      '@vue/compiler-dom': 3.5.13
+      '@vue/compiler-sfc': 3.5.13
+      '@vue/runtime-dom': 3.5.13
+      '@vue/server-renderer': 3.5.13(vue@3.5.13)
+      '@vue/shared': 3.5.13
+      typescript: 5.7.3

+ 0 - 38
prettier.js

@@ -1,38 +0,0 @@
-
-module.exports = {
-  // 一行最多 100 字符
-  printWidth: 100,
-  // 使用 4 个空格缩进
-  tabWidth: 2,
-  // 不使用缩进符,而使用空格
-  useTabs: false,
-  // 行尾需要有分号
-  semi: false,
-  // 使用单引号
-  singleQuote: true,
-  // 对象的 key 仅在必要时用引号
-  quoteProps: 'as-needed',
-  // jsx 不使用单引号,而使用双引号
-  jsxSingleQuote: false,
-  // 末尾不需要逗号
-  trailingComma: 'es5',
-  // 大括号内的首尾需要空格
-  bracketSpacing: true,
-  // jsx 标签的反尖括号需要换行
-  jsxBracketSameLine: false,
-  // 箭头函数,只有一个参数的时候,也需要括号
-  arrowParens: 'always',
-  // 每个文件格式化的范围是文件的全部内容
-  rangeStart: 0,
-  rangeEnd: Infinity,
-  // 不需要写文件开头的 @prettier
-  requirePragma: false,
-  // 不需要自动在文件开头插入 @prettier
-  insertPragma: false,
-  // 使用默认的折行标准
-  proseWrap: 'never',
-  // 根据显示样式决定 html 要不要折行
-  htmlWhitespaceSensitivity: 'strict',
-  // 换行符使用 lf
-  endOfLine: 'lf'
-}

+ 0 - 12
src/ libs/api.request.ts

@@ -1,12 +0,0 @@
-/*
- * @Author: WangQiBiao
- * @LastEditors: LiZhiWei
- * @Description:
- * @Date: 2019-03-02 14:21:27
- * @LastEditTime: 2025-04-15 15:22:11
- */
-import HttpRequest from './axios'
-
-let baseUrl = '/api/'
-const axios = new HttpRequest(baseUrl)
-export default axios

+ 0 - 62
src/ libs/axios.ts

@@ -1,62 +0,0 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-15 15:24:14
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-15 15:28:58
- * @Description: 
- */
-import axios from 'axios'
-import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios'
-import { Message } from 'element-ui'
-
-class HttpRequest {
-  private baseUrl: string
-
-  constructor (baseUrl: string) {
-    this.baseUrl = baseUrl
-  }
-
-  private getInsideConfig () {
-    const config = {
-      baseURL: this.baseUrl,
-      timeout: 60000,
-      withCredentials: true,
-      headers: {
-        Accept: 'application/json;charset=utf-8'
-      }
-    }
-    return config
-  }
-
-  private interceptors (instance: AxiosInstance) {
-    // 请求拦截
-    instance.interceptors.request.use(
-      (config: AxiosRequestConfig) => {
-        return config
-      },
-      error => {
-        return Promise.reject(error)
-      }
-    )
-
-    // 响应拦截
-    instance.interceptors.response.use(
-      (response: AxiosResponse) => {
-        return response
-      },
-      error => {
-        Message.error(error.response?.data?.message || '请求失败')
-        return Promise.reject(error)
-      }
-    )
-  }
-
-  request<T = any> (options: any): Promise<T> {
-    const instance: AxiosInstance = axios.create()
-    options = Object.assign(this.getInsideConfig(), options)
-    this.interceptors(instance)
-    return instance(options) as unknown as Promise<T>
-  }
-}
-
-export default HttpRequest

+ 0 - 160
src/ libs/file.ts

@@ -1,160 +0,0 @@
-/*
- * @Author: WangJiaCheng
- * @Date: 2021-06-22 17:10:11
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-16 09:53:14
- * @Description: 文件相关工具函数
- */
-import { Notification, Message } from 'element-ui'
-import { saveAs } from 'file-saver'
-
-import axios from './api.request'
-
-type FileInfo = {
-  name: string
-  size: string
-}
-
-/**
- * 文件下载
- * @author WangJiaCheng
- * @param {string} obj  下载地址 | Blob
- * @param {string} url  文件名,可选的
- */
-export function saveDownload (obj: string, fileName?: string) {
-  try {
-    saveAs(obj, fileName)
-  } catch (e) {
-    console.log(e)
-  }
-}
-
-/**
- * 进度条下载,使用Blob类型下载
- * @param {string} url 文件下载地址
- * @param {vnode} $vm 组件实例,使用中即是this
- * @param {name, size} fileInfo 文件信息,包括文件名、文件大小
- */
-export function downloadWithProgress (url: string, _vm, loading: string, fileInfo: FileInfo = { name: '', size: '' }, callBack) {
-  let p = 1
-  let progressTimer
-  const { name, size } = fileInfo
-  const notificationInstance = Notification({
-    title: '文件下载中,请稍候',
-    offset: 50,
-    customClass: 'notification-down-progress',
-    message: _vm.$createElement('el-progress', {
-      style: {
-        width: '280px'
-      },
-      props: {
-        percentage: p,
-        textInside: true,
-        strokeWidth: 18
-      },
-      ref: 'downloadProgressBar'
-    }),
-    duration: 0
-  })
-  const settingProgressBar = (p) => {
-    const progressBar = document.querySelector('.notification-down-progress .el-progress-bar__inner') as HTMLElement
-    const progressBarText = document.querySelector('.notification-down-progress .el-progress-bar__innerText') as HTMLElement
-    if (progressBarText && p) {
-      progressBarText.innerHTML = `${p}%`
-      progressBar.style.width = `${p}%`
-      progressBar.style.backgroundColor = '#409eff'
-    }
-  }
-  // 在等待后端响应blob数据前,创建虚拟的下载百分比,给用户反馈下载进度
-  if (notificationInstance) {
-    progressTimer = setInterval(() => {
-      settingProgressBar(p + 1)
-    }, 800)
-  }
-  axios.request({
-    url,
-    method: 'get',
-    params: { wc: new Date().getTime() }, // 后端默认需要字段
-    responseType: 'blob',
-    headers: {
-      Accept: 'application/json, text/plain, */*'
-    },
-    withCredentials: false,
-    timeout: 1000 * 60 * 10, // 10分钟
-    onDownloadProgress: (event) => {
-      const total = event.total || size
-      if (event) {
-        clearInterval(progressTimer)
-      }
-      if (event.target.status >= 200 && event.target.status < 300) {
-        p = Math.round((event.loaded * 100) / total)
-        if (total) {
-          settingProgressBar(p)
-        }
-        if (p >= 100) {
-          setTimeout(() => {
-            notificationInstance.close()
-          }, 500)
-        }
-      } else {
-        notificationInstance.close()
-      }
-    }
-  }).then((res) => {
-    settingProgressBar(100)
-    if (res.data) {
-      const downFileName = name || res.fileName
-      if (downFileName) {
-        saveDownload(res.data, downFileName)
-        _vm[loading] = false
-      } else {
-        saveDownload(url)
-      }
-      callBack()
-    }
-  }).catch((e) => {
-    notificationInstance.close()
-    _vm[loading] = false
-    const reader = new FileReader()
-    reader.onload = () => {
-      const { result } = reader
-      const errorInfos = JSON.parse(result as string)
-      const message = errorInfos.responseJSON.message || '下载异常,请稍后尝试'
-      Message({
-        type: 'error',
-        message: message
-      })
-    }
-    // reader.readAsText(e)
-  })
-}
-
-/**
- * iframe 下载
- * @param {string} url 下载链接
- */
-export function downloadFile (url: string) {
-  const iframe = document.createElement('iframe')
-  iframe.style.display = 'none'
-  function iframeLoad () {
-    const win = iframe.contentWindow as Window
-    const doc = win.document
-    if (win.location.href === url) {
-      if (doc.body.childNodes.length > 0) {
-        // response is error
-      }
-      if (iframe.parentNode) {
-        iframe.parentNode.removeChild(iframe)
-      }
-    }
-  }
-  if ('onload' in iframe) {
-    iframe.onload = iframeLoad
-  }
-  iframe.src = ''
-  document.body.appendChild(iframe)
-
-  if (iframe.contentWindow) {
-    iframe.contentWindow.location.href = url
-  }
-}

+ 0 - 376
src/ libs/tools.js

@@ -1,376 +0,0 @@
-/*
- * @Author: WangQiBiao
- * @LastEditors: wzh
- * @Description:
- * @Date: 2019-03-12 09:40:46
- * @LastEditTime: 2023-10-25 17:47:28
- */
-export const arrDupliction = (arr) => {
-  return Array.from(new Set(arr))
-}
-export const forEach = (arr, fn) => {
-  if (!arr.length || !fn) return
-  let i = -1
-  let len = arr.length
-  while (++i < len) {
-    let item = arr[i]
-    fn(item, i, arr)
-  }
-}
-
-/**
- * @param {Array} arr1
- * @param {Array} arr2
- * @description 得到两个数组的交集, 两个数组的元素为数值或字符串
- */
-export const getIntersection = (arr1, arr2) => {
-  let len = Math.min(arr1.length, arr2.length)
-  let i = -1
-  let res = []
-  while (++i < len) {
-    const item = arr2[i]
-    if (arr1.indexOf(item) > -1) res.push(item)
-  }
-  return res
-}
-
-/**
- * @param {Array} arr1
- * @param {Array} arr2
- * @description 得到两个数组的并集, 两个数组的元素为数值或字符串
- */
-export const getUnion = (arr1, arr2) => {
-  return Array.from(new Set([...arr1, ...arr2]))
-}
-
-/**
- * @param {Array} target 目标数组
- * @param {Array} arr 需要查询的数组
- * @description 判断要查询的数组是否至少有一个元素包含在目标数组中
- */
-export const hasOneOf = (targetarr, arr) => {
-  return targetarr.some(_ => arr.indexOf(_) > -1)
-}
-
-/**
- * @param {Array} arr1
- * @param {Array} arr2
- * @description 判断两个数组是否相同 (含有相同元素)
- */
-export const getArrayEqual = (arr1, arr2) => {
-  if (!Array.isArray(arr1) || !Array.isArray(arr2) || arr1.length !== arr2.length) {
-    return false
-  }
-  let len = arr1.length
-  let i = -1
-  while (++i < len) {
-    if (arr1[i] !== arr2[i]) { return false }
-  }
-  return true
-}
-
-/**
- * @param {String|Number} value 要验证的字符串或数值
- * @param {*} validList 用来验证的列表
- */
-export function oneOf (value, validList) {
-  for (let i = 0; i < validList.length; i++) {
-    if (value === validList[i]) {
-      return true
-    }
-  }
-  return false
-}
-
-/**
- * @param {Number} timeStamp 判断时间戳格式是否是毫秒
- * @returns {Boolean}
- */
-const isMillisecond = timeStamp => {
-  const timeStr = String(timeStamp)
-  return timeStr.length > 10
-}
-
-/**
- * @param {Number} timeStamp 传入的时间戳
- * @param {Number} currentTime 当前时间时间戳
- * @returns {Boolean} 传入的时间戳是否早于当前时间戳
- */
-const isEarly = (timeStamp, currentTime) => {
-  return timeStamp < currentTime
-}
-
-/**
- * @param {Number} num 数值
- * @returns {String} 处理后的字符串
- * @description 如果传入的数值小于10,即位数只有1位,则在前面补充0
- */
-const getHandledValue = num => {
-  return num < 10 ? '0' + num : num
-}
-
-/**
- * @param {Number} timeStamp 传入的时间戳
- * @param {Number} startType 要返回的时间字符串的格式类型,传入'year'则返回年开头的完整时间
- */
-const getDate = (timeStamp, startType) => {
-  const d = new Date(timeStamp * 1000)
-  const year = d.getFullYear()
-  const month = getHandledValue(d.getMonth() + 1)
-  const date = getHandledValue(d.getDate())
-  const hours = getHandledValue(d.getHours())
-  const minutes = getHandledValue(d.getMinutes())
-  const second = getHandledValue(d.getSeconds())
-  let resStr = ''
-  if (startType === 'year') resStr = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + second
-  else resStr = month + '-' + date + ' ' + hours + ':' + minutes
-  return resStr
-}
-
-/**
- * @param {String|Number} timeStamp 时间戳
- * @returns {String} 相对时间字符串
- */
-export const getRelativeTime = timeStamp => {
-  // 判断当前传入的时间戳是秒格式还是毫秒
-  const IS_MILLISECOND = isMillisecond(timeStamp)
-  // 如果是毫秒格式则转为秒格式
-  if (IS_MILLISECOND) Math.floor(timeStamp /= 1000)
-  // 传入的时间戳可以是数值或字符串类型,这里统一转为数值类型
-  timeStamp = Number(timeStamp)
-  // 获取当前时间时间戳
-  const currentTime = Math.floor(Date.parse(new Date()) / 1000)
-  // 判断传入时间戳是否早于当前时间戳
-  const IS_EARLY = isEarly(timeStamp, currentTime)
-  // 获取两个时间戳差值
-  let diff = currentTime - timeStamp
-  // 如果IS_EARLY为false则差值取反
-  if (!IS_EARLY) diff = -diff
-  let resStr = ''
-  const dirStr = IS_EARLY ? '前' : '后'
-  // 少于等于59秒
-  if (diff <= 59) resStr = diff + '秒' + dirStr
-  // 多于59秒,少于等于59分钟59秒
-  else if (diff > 59 && diff <= 3599) resStr = Math.floor(diff / 60) + '分钟' + dirStr
-  // 多于59分钟59秒,少于等于23小时59分钟59秒
-  else if (diff > 3599 && diff <= 86399) resStr = Math.floor(diff / 3600) + '小时' + dirStr
-  // 多于23小时59分钟59秒,少于等于29天59分钟59秒
-  else if (diff > 86399 && diff <= 2623859) resStr = Math.floor(diff / 86400) + '天' + dirStr
-  // 多于29天59分钟59秒,少于364天23小时59分钟59秒,且传入的时间戳早于当前
-  else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) resStr = getDate(timeStamp)
-  else resStr = getDate(timeStamp, 'year')
-  return resStr
-}
-
-/**
- * @returns {String} 当前浏览器名称
- */
-export const getExplorer = () => {
-  const ua = window.navigator.userAgent
-  const isExplorer = (exp) => {
-    return ua.indexOf(exp) > -1
-  }
-  if (isExplorer('MSIE')) return 'IE'
-  else if (isExplorer('Firefox')) return 'Firefox'
-  else if (isExplorer('Chrome')) return 'Chrome'
-  else if (isExplorer('Opera')) return 'Opera'
-  else if (isExplorer('Safari')) return 'Safari'
-}
-
-/**
- * @description 绑定事件 on(element, event, handler)
- */
-export const on = (function () {
-  if (document.addEventListener) {
-    return function (element, event, handler) {
-      if (element && event && handler) {
-        element.addEventListener(event, handler, false)
-      }
-    }
-  } else {
-    return function (element, event, handler) {
-      if (element && event && handler) {
-        element.attachEvent('on' + event, handler)
-      }
-    }
-  }
-})()
-
-/**
- * @description 解绑事件 off(element, event, handler)
- */
-export const off = (function () {
-  if (document.removeEventListener) {
-    return function (element, event, handler) {
-      if (element && event) {
-        element.removeEventListener(event, handler, false)
-      }
-    }
-  } else {
-    return function (element, event, handler) {
-      if (element && event) {
-        element.detachEvent('on' + event, handler)
-      }
-    }
-  }
-})()
-
-/**
- * 判断一个对象是否存在key,如果传入第二个参数key,则是判断这个obj对象是否存在key这个属性
- * 如果没有传入key这个参数,则判断obj对象是否有键值对
- */
-export const hasKey = (obj, key) => {
-  if (key) return key in obj
-  else {
-    let keysArr = Object.keys(obj)
-    return keysArr.length
-  }
-}
-
-/**
- * @param {*} obj1 对象
- * @param {*} obj2 对象
- * @description 判断两个对象是否相等,这两个对象的值只能是数字或字符串
- */
-export const objEqual = (obj1, obj2) => {
-  const keysArr1 = Object.keys(obj1)
-  const keysArr2 = Object.keys(obj2)
-  if (keysArr1.length !== keysArr2.length) return false
-  else if (keysArr1.length === 0 && keysArr2.length === 0) return true
-  /* eslint-disable-next-line */
-  else return !keysArr1.some(key => obj1[key] != obj2[key])
-}
-/**
- * 输入的值是否合法
- * @只能输入1~9数字
- * @小数点不能超过两个
- * @小数点位数不能超过两个
- */
-export const validateInputLegal = (value) => {
-  const slen = String(value).split('.')
-  if (!(/[\d.]/.test(value))) { // 非数字或者'.'
-    return false
-  } else if ((slen && slen.length > 2) || (slen && slen[1] && slen[1].length > 2)) { // 是否只有一个小数点并且小数点只有后两位
-    return false
-  } else {
-    return true
-  }
-}
-/**
- * 函数 名为节流 实为防抖
- * @param method {function} 防抖函数
- * @param delay {number} 防抖时间
- */
-export const throttle = (method, delay) => {
-  let timer = null
-  return function () {
-    let context = this
-    let args = arguments
-    clearTimeout(timer)
-    timer = setTimeout(function () {
-      method.apply(context, args)
-    }, delay)
-  }
-}
-/**
- * 获取数组中的重复元素
- * @param arr 数组
- */
-export const refrainArr = arr => {
-  let tmp = []
-  if (Array.isArray(arr)) {
-    arr.concat().sort().sort(function (a, b) {
-      if (a === b && tmp.indexOf(a) === -1) tmp.push(a)
-    })
-  }
-  return tmp
-}
-// 导出excle
-export const exportExcle = (url, data) => {
-
-}
-
-/**
- * @param {Number} money 大额数值
- * @param {Number} fiexed 保留几位数
- * @returns {Number} 无单位的数值
- */
-export const getBigNumber = (money, fiexed = 2) => {
-  if (money >= 10000) {
-    return Number((Number(money) / 10000).toFixed(fiexed))
-  } else {
-    return Number(money)
-  }
-}
-
-/**
- * @param {Number} money 大额数值
- * @param {Number} fiexed 保留几位数
- * @returns {String} 单位是万
- */
-export const getBigNumberWithUint = (money, fiexed = 2) => {
-  if (money >= 10000) {
-    return getBigNumber(money, fiexed) + '万'
-  } else {
-    return money
-  }
-}
-/**
- * 深度冻结对象
- * @param obj 数组或对象
- */
-export const deepFreeze = (obj) => {
-  var prop, propKey
-  Object.freeze(obj)
-  for (propKey in obj) {
-    prop = obj[propKey]
-    if (!obj.hasOwnProperty(propKey) || !(typeof prop === 'object') || Object.isFrozen(prop)) {
-      continue
-    }
-    deepFreeze(prop)
-  }
-}
-
-/**
- * 字符串 在指定位置插入新字符串
- * @param str 原字符串
- * @param char 要插入的字符串
- * @param index 要插入的位置,从0开始
- */
-export const insertString = (str, char, index) => {
-  return str.slice(0, index) + char + str.slice(index)
-}
-
-/**
- * 用子树的节点来替换主树的节点,节省内存
- * @param {Array} tree 子树
- * @param {Array} treeMain 主树
- * @param {string} valueKey 节点唯一key,用来比较是否为同一个节点
- */
-export const replaceTreeNode = (tree, treeMain, valueKey = 'id') => {
-  if (!tree && !treeMain) return []
-  if (!tree || (Array.isArray(tree) && tree.length === 0)) return treeMain
-  if (!treeMain || (Array.isArray(treeMain) && treeMain.length === 0)) return tree
-
-  if (!Array.isArray(tree)) tree = [tree]
-  if (!Array.isArray(treeMain)) treeMain = [treeMain]
-
-  const childMap = new Map()
-  treeMain.forEach(child => childMap.set(child[valueKey], child))
-
-  for (let i = 0; i < tree.length; i++) {
-    const el = tree[i]
-    const matchingChild = childMap.get(el[valueKey])
-    if (matchingChild) {
-      if (el.children && matchingChild.children && matchingChild.children.length > 0) {
-        matchingChild.children = replaceTreeNode(el.children, matchingChild.children)
-      } else {
-        treeMain[i] = matchingChild
-      }
-    } else {
-      treeMain.push(el)
-    }
-  }
-
-  return treeMain
-}

+ 0 - 1093
src/ libs/util.js

@@ -1,1093 +0,0 @@
-/*
- * @Author: WangQiBiao
- * @LastEditors: LiZhiWei
- * @Description:
- * @Date: 2019-04-16 11:44:25
- * @LastEditTime: 2025-04-15 15:44:32
- */
-import html2canvas from 'html2canvas'
-import { saveAs } from 'file-saver'
-import Cookies from 'js-cookie'
-// cookie保存的天数
-import config from '@/config'
-import { hasOneOf, objEqual } from './tools'
-
-// import beforeClose from '@/router/before-close'
-
-export * from './file'
-
-export const TOKEN_KEY = 'token'
-
-// 缓存表格列宽
-export const setTableHeaderDragend = (name, newWidth, column) => {
-  const tableHeaderData = JSON.parse(window.localStorage.getItem(name)) || []
-  if (tableHeaderData.length) {
-    if (tableHeaderData.some(h => h.property === column.property)) {
-      tableHeaderData[tableHeaderData.findIndex(i => i.property === column.property)].width = newWidth
-    } else {
-      tableHeaderData.push({ property: column.property, width: newWidth })
-    }
-  } else {
-    tableHeaderData.push({ property: column.property, width: newWidth })
-  }
-  window.localStorage.setItem(name, JSON.stringify(tableHeaderData))
-}
-// 获取表格列宽
-export const getTableHeaderDragend = (name) => {
-  return JSON.parse(window.localStorage.getItem(name)) || []
-}
-
-export const getTableColumnWidth = (name, property) => {
-  const tableHeaderData = JSON.parse(window.localStorage.getItem(name)) || []
-  if (tableHeaderData.some(h => h.property === property)) {
-    return tableHeaderData[tableHeaderData.findIndex(i => i.property === property)].width
-  } else {
-    return 150
-  }
-}
-
-export const setToken = token => {
-  Cookies.set(TOKEN_KEY, token, { expires: config.cookieExpires || 1 })
-}
-
-export const removeToken = () => {
-  Cookies.remove(TOKEN_KEY)
-}
-
-export const getToken = () => {
-  const token = Cookies.get(TOKEN_KEY)
-  if (token) return token
-  else return false
-}
-
-export const getCookie = (key) => {
-  return Cookies.get(key)
-}
-
-export const removeCookie = (key, options = {}) => {
-  Cookies.remove(key, options)
-}
-
-export const removeAllCookie = () => {
-  Object.keys(Cookies.get()).forEach(key => Cookies.remove(key))
-}
-
-export const hasChild = item => {
-  return item.children && item.children.length !== 0
-}
-
-const showThisMenuEle = (item, access) => {
-  if (item.meta && item.meta.access && item.meta.access.length) {
-    if (hasOneOf(item.meta.access, access)) return true
-    else return false
-  } else return true
-}
-
-/**
- * 根据接口返回的路由配置权限路由
- * @param {Array} asyncRouter 本地路由
- * @param {Array} menus 接口返回的经过格式化的路由
- * @returns newMenu 新的权限路由
- */
-export const asyncRouterMap = (asyncRouter = [], menus = []) => {
-  const newMenu = []
-  asyncRouter.forEach(route => {
-    if (route.name && (route && route.meta && (route.meta.hideInMenu || route.meta.authorized))) {
-      // 对于一级路由设置隐藏且没有对应菜单的路由
-      newMenu.push(route)
-    } else {
-      menus.forEach(menu => {
-        if (route.name === menu.name && menu.meta.type !== 'button') {
-          if (route.children && (menu.children && menu.children.length > 0)) {
-            // 经过和菜单比较后得到的菜单路由
-            const compareChild = route.children.filter(item => {
-              const mChild = menu.children.find(mChild => mChild.name === item.name)
-              if (mChild) {
-                return item
-              } else if (item && item.meta && (item.meta.hideInMenu || item.meta.authorized)) {
-                return item
-              }
-            })
-            let newRoute = {}
-            const { children, ...reset } = route
-            newRoute = reset
-            newRoute.children = compareChild
-            newMenu.push(newRoute)
-          } else {
-            // 只有一级路由,没有二级路由
-            const { redirect } = route
-            newMenu.push({ ...menu, redirect })
-          }
-        }
-      })
-    }
-  })
-  return newMenu
-}
-
-/**
- * @param {Array} list 通过路由列表得到菜单列表
- * @returns {Array}
- */
-export const getMenuByRouter = (list = [], access) => {
-  let res = []
-  const getMenus = (l, a) => {
-    l.forEach(item => {
-      if (!item.meta || (item.meta && !item.meta.hideInMenu)) {
-        let obj = {
-          icon: (item.meta && item.meta.icon) || '',
-          name: item.path.replace(/\//, '') || '_', // 过滤 '/'
-          meta: item.meta,
-          path: item.path
-        }
-        if ((hasChild(item) || (item.meta && item.meta.showAlways)) && showThisMenuEle(item, a)) {
-          obj.children = getMenuByRouter(item.children, a)
-        }
-        if (item.meta && item.meta.href) obj.href = item.meta.href
-        if (showThisMenuEle(item, a)) res.push(obj)
-      }
-    })
-  }
-  getMenus(list, access)
-  return res
-}
-/**
- * 根据权限匹配路由
- * @param {Array} permission 权限路由
- * @param {Array} asyncRouter 异步路由
- */
-export const routerByMatch = (permission, asyncRouter) => {
-  permission = JSON.parse(permission)
-  // 菜单路由表
-  const router = []
-  function createRouter (permission) {
-    // 根据路由名称匹配到router对象添加到router中
-    permission && permission.forEach(item => {
-      if (item.children && item.children.length) {
-        createRouter(item.children)
-      }
-      let routerName = item.route
-      // 过滤路由名称为null的情况
-      if (routerName) {
-        // 循环异步路由,将符合权限列表路由加入路由表中
-        asyncRouter.find(s => {
-          if (s.name === routerName) {
-            router.push(s)
-          }
-        })
-      }
-    })
-  }
-  createRouter(permission)
-  return router
-}
-
-/**
- * @param {Array} routeMetched 当前路由metched
- * @returns {Array}
- */
-export const getBreadCrumbList = (route) => {
-  let routeMetched = route.matched
-  let res = routeMetched
-    .filter(item => {
-      return item.meta === undefined || !item.meta.hide
-    })
-    .map(item => {
-      let meta = { ...item.meta }
-      if (meta.title && typeof meta.title === 'function') meta.title = meta.title(route)
-      let obj = {
-        icon: (item.meta && item.meta.icon) || '',
-        name: item.name,
-        meta: meta
-      }
-      return obj
-    })
-  res = res.filter(item => {
-    return !item.meta.hideInMenu
-  })
-  // return [Object.assign(homeRoute, { to: homeRoute.path }), ...res]
-  return res
-}
-
-export const getRouteTitleHandled = route => {
-  let router = { ...route }
-  let meta = { ...route.meta }
-  if (meta.title && typeof meta.title === 'function') meta.title = meta.title(router)
-  router.meta = meta
-  return router
-}
-
-export const showTitle = (item, vm) => {
-  return vm.$config.useI18n ? vm.$t(item.name) : (item.meta && item.meta.title) || item.name
-}
-
-/**
- * @description 本地存储和获取标签导航列表
- */
-export const setTagNavListInLocalstorage = list => {
-  localStorage.tagNavList = JSON.stringify(list)
-}
-/**
- * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项
- */
-export const getTagNavListFromLocalstorage = () => {
-  const list = localStorage.tagNavList
-  return list ? JSON.parse(list) : []
-}
-
-/**
- * @param {Array} routers 路由列表数组
- * @description 用于找到路由列表中name为home的对象
- */
-export const getHomeRoute = routers => {
-  if (!routers) {
-    return
-  }
-  let i = -1
-  let len = routers.length
-  let homeRoute = {}
-  while (++i < len) {
-    let item = routers[i]
-    if (item.children && item.children.length) {
-      let res = getHomeRoute(item.children)
-      if (res.name) return res
-    } else {
-      // if (item.name === 'home') homeRoute = item
-      // 目前没有主页、判断为第一个路由、后期加上主页  把这行去掉  取消上行注释
-      if (item.name === routers[0].name) homeRoute = item
-    }
-  }
-  return homeRoute
-}
-
-/**
- * @param {*} list 现有标签导航列表
- * @param {*} newRoute 新添加的路由原信息对象
- * @description 如果该newRoute已经存在则不再添加
- */
-export const getNewTagList = (list, newRoute) => {
-  const { name, path, meta } = newRoute
-  let newList = [...list]
-  if (newList.findIndex(item => item.name === name) >= 0) return newList
-  else newList.push({ name, path, meta })
-  return newList
-}
-
-/**
- * @param {*} access 用户权限数组,如 ['super_admin', 'admin']
- * @param {*} route 路由列表
- */
-const hasAccess = (access, route) => {
-  if (route.meta && route.meta.access) return hasOneOf(access, route.meta.access)
-  else return true
-}
-
-/**
- * 权鉴
- * @param {*} name 即将跳转的路由name
- * @param {*} access 用户权限数组
- * @param {*} routes 路由列表
- * @description 用户是否可跳转到该页
- */
-export const canTurnTo = (name, access, routes) => {
-  const routePermissionJudge = list => {
-    return list.some(item => {
-      if (item.children && item.children.length) {
-        return routePermissionJudge(item.children)
-      } else if (item.name === name) {
-        return hasAccess(access, item)
-      }
-    })
-  }
-
-  return routePermissionJudge(routes)
-}
-
-/**
- * @param {String} url
- * @description 从URL中解析参数
- */
-export const getParams = url => {
-  const keyValueArr = url.split('?')[1].split('&')
-  let paramObj = {}
-  keyValueArr.forEach(item => {
-    const keyValue = item.split('=')
-    paramObj[keyValue[0]] = keyValue[1]
-  })
-  return paramObj
-}
-
-/**
- * @param {Array} list 标签列表
- * @param {String} name 当前关闭的标签的name
- */
-export const getNextRoute = (list, route) => {
-  let res = {}
-  if (list.length === 2) {
-    res = getHomeRoute(list)
-  } else {
-    const index = list.findIndex(item => routeEqual(item, route))
-    if (index === list.length - 1) res = list[list.length - 2]
-    else res = list[index + 1]
-  }
-  return res
-}
-
-/**
- * @param {Number} times 回调函数需要执行的次数
- * @param {Function} callback 回调函数
- */
-export const doCustomTimes = (times, callback) => {
-  let i = -1
-  while (++i < times) {
-    callback(i)
-  }
-}
-
-/**
- * @param {Object} file 从上传组件得到的文件对象
- * @returns {Promise} resolve参数是解析后的二维数组
- * @description 从Csv文件中解析出表格,解析成二维数组
- */
-export const getArrayFromFile = file => {
-  let nameSplit = file.name.split('.')
-  let format = nameSplit[nameSplit.length - 1]
-  return new Promise((resolve, reject) => {
-    let reader = new FileReader()
-    reader.readAsText(file) // 以文本格式读取
-    let arr = []
-    reader.onload = function (evt) {
-      let data = evt.target.result // 读到的数据
-      let pasteData = data.trim()
-      arr = pasteData
-        .split(/[\n\u0085\u2028\u2029]|\r\n?/g)
-        .map(row => {
-          return row.split('\t')
-        })
-        .map(item => {
-          return item[0].split(',')
-        })
-      if (format === 'csv') resolve(arr)
-      else reject(new Error('[Format Error]:你上传的不是Csv文件'))
-    }
-  })
-}
-
-/**
- * @param {Array} array 表格数据二维数组
- * @returns {Object} { columns, tableData }
- * @description 从二维数组中获取表头和表格数据,将第一行作为表头,用于在iView的表格中展示数据
- */
-export const getTableDataFromArray = array => {
-  let columns = []
-  let tableData = []
-  if (array.length > 1) {
-    let titles = array.shift()
-    columns = titles.map(item => {
-      return {
-        title: item,
-        key: item
-      }
-    })
-    tableData = array.map(item => {
-      let res = {}
-      item.forEach((col, i) => {
-        res[titles[i]] = col
-      })
-      return res
-    })
-  }
-  return {
-    columns,
-    tableData
-  }
-}
-
-export const findNodeUpper = (ele, tag) => {
-  if (ele.parentNode) {
-    if (ele.parentNode.tagName === tag.toUpperCase()) {
-      return ele.parentNode
-    } else {
-      return findNodeUpper(ele.parentNode, tag)
-    }
-  }
-}
-
-export const findNodeUpperByClasses = (ele, classes) => {
-  let parentNode = ele.parentNode
-  if (parentNode) {
-    let classList = parentNode.classList
-    if (classList && classes.every(className => classList.contains(className))) {
-      return parentNode
-    } else {
-      return findNodeUpperByClasses(parentNode, classes)
-    }
-  }
-}
-
-export const findNodeDownward = (ele, tag) => {
-  const tagName = tag.toUpperCase()
-  if (ele.childNodes.length) {
-    let i = -1
-    let len = ele.childNodes.length
-    while (++i < len) {
-      let child = ele.childNodes[i]
-      if (child.tagName === tagName) return child
-      else return findNodeDownward(child, tag)
-    }
-  }
-}
-
-export const showByAccess = (access, canViewAccess) => {
-  return hasOneOf(canViewAccess, access)
-}
-
-/**
- * @description 根据name/params/query判断两个路由对象是否相等
- * @param {*} route1 路由对象
- * @param {*} route2 路由对象
- */
-export const routeEqual = (route1, route2) => {
-  const query1 = route1.query || {}
-  const query2 = route2.query || {}
-  return route1.name === route2.name
-}
-
-/**
- * 判断打开的标签列表里是否已存在这个新添加的路由对象
- */
-export const routeHasExist = (tagNavList, routeItem) => {
-  let len = tagNavList.length
-  let res = false
-  doCustomTimes(len, index => {
-    if (routeEqual(tagNavList[index], routeItem)) res = true
-  })
-  return res
-}
-
-export const showLoadingFunc = (obj, flag) => {
-  let arr = obj.$root.$children
-  if (arr.length > 0) {
-    arr[0].isShowLoading = flag
-  }
-}
-
-export const dateFormat = (obj, fmt) => {
-  if (typeof obj === 'string') {
-    return obj
-  }
-  if (obj && obj.getFullYear) {
-    var o = {
-      'M+': obj.getMonth() + 1, // 月份
-      'd+': obj.getDate(), // 日
-      'H+': obj.getHours(), // 小时
-      'h+': obj.getHours(), // 小时
-      'm+': obj.getMinutes(), // 分
-      's+': obj.getSeconds(), // 秒
-      'q+': Math.floor((obj.getMonth() + 3) / 3), // 季度
-      S: obj.getMilliseconds() // 毫秒
-    }
-    if (/(y+)/.test(fmt)) {
-      fmt = fmt.replace(/(y+)/, (match, p1) => (obj.getFullYear() + '').substring(4 - p1.length))
-    }
-    for (var k in o) {
-      let reg = new RegExp('(' + k + ')')
-      if (reg.test(fmt)) {
-        fmt = fmt.replace(reg, (match, p1) => p1.length === 1 ? o[k] : ('00' + o[k]).substring(('' + o[k]).length))
-      }
-    }
-    return fmt
-  } else {
-    return ''
-  }
-}
-
-export const getYearWeek = (date) => {
-  /*
-      dateNow是当前日期
-      dateFirst是当年第一天
-      dataNumber是当前日期是今年第多少天
-      用dataNumber + 当前年的第一天的周差距的和在除以7就是本年第几周
-  */
-  let dateNow = date instanceof Date ? date : convertDateFromString(date, 'yyyy-MM-dd')
-  let dateFirst = new Date(dateNow.getFullYear(), 0, 1)
-  let dataNumber = Math.round((dateNow.valueOf() - dateFirst.valueOf()) / 86400000)
-  return Math.ceil((dataNumber + ((dateFirst.getDay() + 1) - 1)) / 7)
-}
-
-// 天-小时-分钟
-export const dateRule = (value) => {
-  // 需要转换的时间-秒单位
-  /**
-   * var theTime = parseInt(value);
-   */
-  var theTime1 = 0 // 分
-  var theTime2 = 0 // 小时
-  var theTime3 = 0 // 天
-  if (value > 60) {
-    theTime1 = parseInt(value / 60)
-    /**
-       * theTime = parseInt(theTime % 60);
-       */
-    if (theTime1 > 60) {
-      theTime2 = parseInt(theTime1 / 60)
-      theTime1 = parseInt(theTime1 % 60)
-      if (theTime2 > 24) {
-        // 大于24小时
-        theTime3 = parseInt(theTime2 / 24)
-        theTime2 = parseInt(theTime2 % 24)
-      }
-    }
-  }
-  var result = ''
-  /**
-   *  if (theTime > 0) {
-      result = "" + parseInt(theTime) + "秒";
-      }
-   */
-
-  if (theTime1 > 0) {
-    if (theTime2 > 0 || theTime3 > 0) {
-      result = '' + parseInt(theTime1) + '分' + result
-    } else {
-      result = '' + parseInt(theTime1) + '分钟' + result
-    }
-  }
-  if (theTime2 > 0) {
-    result = '' + parseInt(theTime2) + '小时' + result
-  }
-  if (theTime3 > 0) {
-    result = '' + parseInt(theTime3) + '天' + result
-  }
-  return result
-}
-export const convertDateFromString = (dateString, fmt) => {
-  if (dateString) {
-    if (fmt === 'yyyy-MM-dd' || fmt === 'yyyy-MM-dd hh:mm:ss') {
-      return new Date(dateString.replace(/-/g, '/'))
-    } else {
-      return null
-    }
-  } else {
-    return null
-  }
-}
-
-/**
- * @description 日期去掉时分秒
- * @param string value 日期
- */
-export const dateRemoveTime = dateString => {
-  return dateString && dateString.split(' ')[0]
-}
-
-export const ObjectNone = object => {
-  if (JSON.stringify(object) === '{}') return true
-  else return false
-}
-
-/**
- * @description 校验邮编号码 长度6位数字
- * @param string value 值
- */
-export const testPostal = value => {
-  return !/^\d{6}$/.test(value)
-}
-
-/**
- * @description 校验手机号码
- * @param string value 值
- */
-export const testMobile = value => {
-  return !/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)
-}
-
-/**
- * @description 校验邮箱
- * @param string value 值
- */
-export const checkEmail = value => {
-  return !/^[a-zA-Z0-9]+([a-zA-Z0-9-_.]*)@([a-zA-Z0-9]+[-|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,4}$/g.test(value)
-}
-
-/**
- * @description 校验固定电话
- * @param string value 值
- */
-export const testPhone = value => {
-  return !/^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/.test(value)
-}
-
-/**
- * @description 校验银行卡
- * @param string value 值
- */
-export const testBankNo = value => {
-  // 陈曦说8到30 2020年7月10日
-  return !/^(\d{8,30})$/.test(value)
-}
-/**
- * @description 校验5位数短号 10086、95119
- * @param string value 值
- */
-export const test5ShortPhone = value => {
-  return !/^(1|9){1}\d{4}$/.test(value)
-}
-
-/**
- * @description 校验3位数短号, 110、120
- * @param string value 值
- */
-export const test3ShortPhone = value => {
-  return !/^1\d{2}$/.test(value)
-}
-
-/**
- * @description 校验400虚拟号, 400-600-7709
- * @param string value 值
- */
-export const test400Phone = value => {
-  return !/^(400)-(\d{3})-(\d{4}$)/.test(value)
-}
-
-/**
- * @description 校验800虚拟号, 800-600-7709
- * @param string value 值
- */
-export const test800Phone = value => {
-  return !/^(800)-(\d{3})-(\d{4}$)/.test(value)
-}
-
-/**
- * @description 校验身份证18位
- * @param string value 值
- */
-export const testIdCard = value => {
-  return !/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(value)
-}
-
-/**
- * @description 纳税人识别号 统一社会信用代码
- * @param string value 值
- */
-export const testUniformSocialCreditCode = value => {
-  return /^[^_IOZSVa-z\W]{2}\d{6}[^_IOZSVa-z\W]{10}$|^[1-9][0-9A-Z]{14}$|^[A-Z0-9]{20}$/.test(value)
-}
-
-/**
- * @description 自定义导航标签名
- * @param vm 组件实例
- * @param title 导航名称
- */
-export const customTagNavList = (vm, title) => {
-  vm.$store.state.app.tagNavList.forEach(item => {
-    if (routeEqual(item, vm.$route)) {
-      let { meta } = item
-      vm.$set(
-        meta,
-        'title',
-        title
-      )
-    }
-  })
-  if (vm.$store.state.app.tagNavList.length) {
-    setTagNavListInLocalstorage(vm.$store.state.app.tagNavList)
-  }
-}
-
-/**
- * @description 替换同路由导航标签
- * @param vm 组件实例
- * @param route 当前路由
- */
-export const replaceTagNavItem = (vm, { name, query, params }) => {
-  query = query || {}
-  params = params || {}
-  vm.$store.state.app.tagNavList.forEach(item => {
-    if (item.name === name && (!objEqual(item.query, query) || !objEqual(item.params, params))) {
-      vm.$set(
-        item,
-        'query',
-        query
-      )
-      vm.$set(
-        item,
-        'params',
-        params
-      )
-    }
-  })
-
-  if (vm.$store.state.app.tagNavList.length) {
-    setTagNavListInLocalstorage(vm.$store.state.app.tagNavList)
-  }
-}
-
-/**
- * @description 手动关闭导航标签
- * @param vm 组件实例
- * @param route 当前路由
- * @param callback 回调函数
- */
-// export const handleTagNavClose = (vm, route, callback) => {
-//   let list = JSON.parse(JSON.stringify(vm.$store.state.app.tagNavList))
-//   if (route.meta && route.meta.beforeCloseName && route.meta.beforeCloseName in beforeClose) {
-//     new Promise(beforeClose[route.meta.beforeCloseName]).then(close => {
-//       if (close) {
-//         vm.$store.state.app.tagNavList = list.filter(item => !routeEqual(route, item))
-//       }
-//     })
-//   } else {
-//     vm.$store.state.app.tagNavList = list.filter(item => !routeEqual(route, item))
-//   }
-
-//   if (vm.$store.state.app.tagNavList.length) {
-//     setTagNavListInLocalstorage(vm.$store.state.app.tagNavList)
-//   }
-
-//   callback && callback()
-// }
-
-/**
- * 递归格式化tree
- * 返回满足要的tree结构
- * @param dataArr {array} tree数据
- * @param options.value {string} 值
- * @param options.children {array} 子孙节点
- * @param options.label {string} 显示内容
- * @param expand {boolean} 是否展开
- * @param selected {string} 要选中的元素
- */
-export const recursionFormatTreeJson = (data, opt = { value: 'id', valueKey: 'value', label: 'label', labelKey: 'label', children: 'children', special: true }, selected) => {
-  const res = []
-  let obj = {}
-  data.forEach(row => {
-    const tmp = { ...row }
-    if (tmp.children) {
-      tmp.children = recursionFormatTreeJson(tmp.children, opt, selected)
-      obj = {
-        [opt.valueKey]: opt.special ? tmp[opt.value] : `${tmp[opt.value]},${tmp[opt.label]}`,
-        [opt.labelKey]: tmp[opt.label],
-        label: tmp[opt.label],
-        expand: true,
-        id: tmp[opt.value],
-        type: tmp['type'] || null,
-        selected: (tmp[opt.value] === selected),
-        [opt.children]: tmp[opt.children] && tmp[opt.children].length > 0 ? tmp[opt.children] : null
-      }
-    }
-    res.push(obj)
-  })
-  return res
-}
-
-/**
- * 递归初始化tree
- * 返回初始化tree,默认展开选择selected
- * @param data {array} tree数据
- * @param selected {string} 要选中的元素
- */
-export const recursionInitTreeJson = (data, selected) => {
-  let res = false
-  for (let i = 0, len = data.length; i < len; i++) {
-    if (data[i].value === selected) {
-      data[i].selected = true
-      data[i].expand = true
-      return true
-    }
-
-    if (data[i].children) {
-      if ((i === 0) || (data[i - 1] && !data[i - 1].expand)) {
-        res = recursionInitTreeJson(data[i].children, selected)
-        data[i].expand = res
-      } else {
-        return true
-      }
-    }
-  }
-  return res
-}
-/**
- * 获取当前选中地址单元描述信息
- * @param data {array} 地址单元信息
- * @param row {object} 当前地址信息
- */
-export const getCommunityTitleInfo = (data, row) => {
-  let resInfo = []
-  data.filter(item => {
-    // 小区名称
-    if (item.communityId === row.communityId) {
-      resInfo.push(item.title)
-      // 栋名称
-      item.children.filter(itemBuild => {
-        if (itemBuild.buildId === row.buildId) {
-          resInfo.push(itemBuild.title)
-          // 单元名称
-          itemBuild.children.filter(itemUnit => {
-            if (itemUnit.unitId === row.unitId) {
-              resInfo.push(itemUnit.title)
-              // 房屋号
-              itemUnit.children.filter(itemHouse => {
-                if (itemHouse.houseId === row.houseId) {
-                  resInfo.push(itemHouse.title)
-                }
-              })
-            }
-          })
-        }
-      })
-    }
-  })
-  return resInfo.join(' / ')
-}
-/**
- * 函数节流
- */
-export const throttle = (callback, delay) => {
-  let timer = null
-  let previous = new Date()
-
-  return function () {
-    let now = new Date()
-    let remaining = now - previous
-    let args = arguments
-    let context = this
-
-    if (remaining >= delay) {
-      if (timer) {
-        clearTimeout(timer)
-      }
-
-      callback.apply(context, args)
-      previous = now
-    } else {
-      if (!timer) {
-        timer = setTimeout(function () {
-          callback.apply(context, args)
-          previous = new Date()
-        }, delay - remaining)
-      }
-    }
-  }
-}
-/**
- * 防抖
- */
-export const debounce = (callback, delay) => {
-  let timer = null
-
-  return function () {
-    let args = arguments
-    let context = this
-    if (timer) {
-      clearTimeout(timer)
-    }
-    timer = setTimeout(function () {
-      callback.apply(context, args)
-    }, delay)
-  }
-}
-/**
- * js导出xlsx文件
- * @param data {array} 表头描述;列标题,逗号隔开,每一个逗号(英文逗号)就是隔开一个单元格
- * @param columns {array} 表格内容;数组包含对象,每个对象单元为一个表格单元格
- * @param fileName {string} 表个名称
- */
-export const jsExportXlsxFile = (columns = [], data = [], fileName = '数据表') => {
-  let str = columns.join(',')
-  str += `\n`
-  // 增加\t为了不让表格显示科学计数法或者其他格式、正则是为了去掉回车
-  for (let i = 0; i < data.length; i++) {
-    for (let item in data[i]) {
-      str += `${data[i][item].replace(/[\n\r]/g, '') + '\t'},`
-    }
-    str += '\n'
-  }
-  // encodeURIComponent解决中文乱码
-  let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str)
-  // 通过创建a标签实现
-  let link = document.createElement('a')
-  link.href = uri
-  // 对下载的文件命名
-  link.download = `${fileName}.csv`
-  document.body.appendChild(link)
-  link.click()
-  document.body.removeChild(link)
-}
-/**
- * 文件名称路径拼接
- */
-export function fileToPath () {
-  let baseUrl = '/api/'
-  if (process.env.NODE_ENV === 'production') {
-    baseUrl = config.baseUrl.files
-  }
-  return baseUrl
-}
-// 资产树选择楼栋,单元,房屋
-export const assetTreeFilter = (data, type) => {
-  let result = []
-  let item = {}
-  if (type === 'build') {
-    data.forEach(build => {
-      item = Object.assign({}, build)
-      item.children = []
-      result.push(item)
-    })
-    return result
-  }
-  if (type === 'unit') {
-    let unitItem = {}
-    data.forEach(build => {
-      item = Object.assign({}, build)
-      item.children = []
-      build.children.forEach(unit => {
-        unitItem = Object.assign({}, unit)
-        unitItem.children = []
-        item.children.push(unitItem)
-      })
-      result.push(item)
-    })
-    return result
-  }
-  if (type === 'house') {
-    return data
-  }
-}
-
-/**
- * 将dom转为图片dataUrl 和 blob
- * @param {dom} dom 对象
- * @param {string} type default: 获取dataUrl,blob; image: 获取dataUrl; download 自动下载并获取blob
- * @param {Number} quality 图片质量 0~1
- * @param {string} fileName 保存的图片名称
- * @returns Promise
- */
-export const dom2Image = (dom, type = 'default', quality = 0.9, fileName = '', imagetype = 'image/jpeg', options = {}) => {
-  return new Promise((resolve, reject) => {
-    html2canvas(dom, {
-      backgroundColor: null,
-      dpi: window.devicePixelRatio * 2,
-      scale: 10,
-      useCORS: true,
-      ...options
-    })
-      .then((canvas) => {
-        let dataUrl = canvas.toDataURL(imagetype, quality)
-        if (type === 'image') {
-          resolve(dataUrl)
-        } else {
-          canvas.toBlob((blob) => {
-            if (type === 'download') {
-              saveAs(blob, fileName)
-            }
-            resolve({
-              dataUrl,
-              blob
-            })
-          }, imagetype, quality)
-        }
-      })
-      .catch(err => {
-        reject(err)
-      })
-  })
-}
-
-/* 图片压缩方法-canvas压缩 */
-export const compressPhoto = (image, maxSize = 0, quality = 0.7) => {
-  let canvas = document.createElement('canvas')
-  let ctx = canvas.getContext('2d')
-  // let initSize = image.src.length
-  let { width, height } = image
-  let per = 0
-  if (width > height) {
-    per = maxSize / width
-  } else {
-    per = maxSize / height
-  }
-  canvas.width = width * per || width
-  canvas.height = height * per || height
-  ctx.fillStyle = '#fff'
-  ctx.fillRect(0, 0, canvas.width, canvas.height)
-  ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
-
-  // 进行压缩0.7
-  let compressData = canvas.toDataURL('image/jpeg', quality)
-
-  // 压缩后调用方法进行base64转Blob
-  // let blobImg = dataURItoBlob(compressData)
-  return compressData
-}
-
-/* base64转Blob对象 */
-export const dataURItoBlob = (data) => {
-  let byteString
-  if (data.split(',')[0].indexOf('base64') >= 0) {
-    byteString = atob(data.split(',')[1])
-  } else {
-    byteString = unescape(data.split(',')[1])
-  }
-  let mimeString = data
-    .split(',')[0]
-    .split(':')[1]
-    .split(';')[0]
-  let ia = new Uint8Array(byteString.length)
-  for (let i = 0; i < byteString.length; i += 1) {
-    ia[i] = byteString.charCodeAt(i)
-  }
-  return new Blob([ia], { type: mimeString })
-}
-// 枚举转换
-export const enumForMat = (data) => {
-  let enumArr = []
-  if (data && data.length > 0) {
-    enumArr = data.map(item => {
-      return {
-        text: item.name,
-        value: item.code
-      }
-    })
-  }
-  return enumArr
-}
-
-export function toHump (str = '') {
-  return str.replace(/^\w|_\w/g, (match) => match.toUpperCase()).replace(/_/g, '')
-}
-
-// 表头统计模板数据转换
-export function statisitsChange (data, res) {
-  for (let item of data) {
-    item.value = res[item.key]
-  }
-  return data
-}
-
-// 金额转换大写
-export function priceToUpper (n) {
-  if (Number(n) === 0) {
-    return '零元整'
-  }
-  if (!/^(\+|-)?(0|[1-9]\d*)(\.\d+)?$/.test(n)) { return '数据非法' }
-  let unit = '仟佰拾亿仟佰拾万仟佰拾元角分'
-  let str = ''
-  n += '00'
-  let a = parseFloat(n)
-  if (a < 0) {
-    n = n.substr(1)
-  }
-  let p = n.indexOf('.')
-  if (p >= 0) {
-    n = n.substring(0, p) + n.substr(p + 1, 2)
-  }
-
-  unit = unit.substr(unit.length - n.length)
-
-  for (let i = 0; i < n.length; i++) { str += '零壹贰叁肆伍陆柒捌玖'.charAt(n.charAt(i)) + unit.charAt(i) }
-  if (a > 0) {
-    return str.replace(/零(仟|佰|拾|角)/g, '零').replace(/(零)+/g, '零').replace(/零(万|亿|元)/g, '$1').replace(/(亿)万/g, '$1').replace(/^元零?|零分/g, '').replace(/元$/g, '元整')
-  } else {
-    return '负' + str.replace(/零(仟|佰|拾|角)/g, '零').replace(/(零)+/g, '零').replace(/零(万|亿|元)/g, '$1').replace(/(亿)万|壹(拾)/g, '$1$2').replace(/^元零?|零分/g, '').replace(/元$/g, '元整')
-  }
-}

+ 7 - 30
src/App.vue

@@ -1,38 +1,15 @@
 <!--
  * @Author: LiZhiWei
- * @Date: 2025-04-23 09:33:35
+ * @Date: 2025-04-24 15:20:36
  * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 15:48:07
+ * @LastEditTime: 2025-04-24 15:22:13
  * @Description: 
 -->
 <template>
-  <div id="app">
-    <router-view />
-  </div>
-</template>
+    <div>
+        <router-view/>
+    </div>
+ </template>
 
-<script>
-export default {
-  name: "App",
-  data() {
-    return {}
-  },
-  methods: {},
-}
-</script>
-
-<style lang="less">
-html,
-body {
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-  margin: 0;
-  padding: 0;
-}
-
-#app {
-  width: 100%;
-  height: 100%;
-}
+<style scoped>
 </style>

+ 0 - 83
src/api/module/file.js

@@ -1,83 +0,0 @@
-/*
- * @Author: WangQiBiao
- * @Date: 2019-01-31 09:36:48
- * @Last Modified by: WangQiBiao
- * @Last Modified time: 2019-02-20 16:18:36
- */
-import axios from '../../ libs/api.request'
-export default {
-  /**
-   * 图片查看
-   * @param id {string} 图片id
-   */
-  getFileImages (data) {
-    return axios.request({
-      url: `/file/images/${data.id}`,
-      params: data,
-      method: 'get'
-    })
-  },
-  /**
-   * 文件预览
-   * @param {String} fileId 文件id
-   * @param {Function} progressFunc 下载进度
-   */
-  previewCabinetFile (fileId, onDownloadProgress) {
-    return this.downloadFileByConfig(
-      `/serve/cabinetFile/preview/${fileId}`,
-      {
-        onDownloadProgress: onDownloadProgress,
-        timeout: 1000 * 60 * 10 // 10分钟
-      }
-    )
-  },
-  previewCabinetFileByUrl (url, config) {
-    return this.downloadFileByConfig(
-      url,
-      {
-        ...config,
-        responseType: 'blob'
-      }
-    )
-  },
-  /**
-   * 文件下载
-   * @param {String} fileId 文件id
-   * @param {Function} progressFunc 下载进度
-   */
-  downloadFile (fileId, onDownloadProgress) {
-    return this.downloadFileByConfig(
-      `/file/download/${fileId}`,
-      {
-        onDownloadProgress: onDownloadProgress
-      }
-    )
-  },
-  /**
-   * 文件下载
-   * @param {String} url 文件下载地址
-   * @param {Function} config 配置项
-   */
-  downloadFileByConfig (url, config, params = {}) {
-    let defaultConfig = {
-      url,
-      method: 'get',
-      params: params,
-      responseType: 'blob',
-      withCredentials: false,
-      headers: {
-        Accept: 'application/force-download;application/octet-stream;'
-      }
-    }
-    return axios.request(Object.assign(defaultConfig, config))
-  },
-  postImageByManual (data) {
-    return axios.request({
-      url: '/file/images/upload',
-      data: data,
-      method: 'post',
-      timeout: 1000 * 60 * 10 // 10分钟
-    })
-  }
-
-}

+ 0 - 120
src/comm_js/index.js

@@ -1,120 +0,0 @@
-/*
- * @Author: ChenYaJin
- * @Date: 2021-06-08 16:11:26
- * @LastEditors: ChenYaJin
- * @LastEditTime: 2023-08-03 16:17:46
- * @Description: 文件柜-公用方法
- */
-
-const inventoryCodeName = new Map([
-  ['qualityInspection', '巡查'],
-  ['securityPatrol', '巡逻'],
-  ['deviceInspection', '巡检'],
-  ['deviceCuring', '保养'],
-  ['deviceMaintain', '维修'],
-  ['cleaningWork', '保洁'],
-  ['greeningWork', '绿化']
-])
-
-export { inventoryCodeName }
-
-export default {
-  // 根据子节点id,找出父节点列表
-  getParentList (data, id) {
-    let childList = []
-    data.forEach((item, index) => {
-      if (item.id === id) {
-        childList = [item.label]
-        return false
-      } else {
-        if (item.children) {
-          let newCidList = [item.label]
-          let list = this.nodeFun(item.children, id, newCidList)
-          if (list) {
-            childList = list
-          }
-        }
-      }
-    })
-    return childList
-  },
-  nodeFun (newVal, newId, newCidList) {
-    let flag = false
-    newVal.forEach(j => {
-      if (j.id === newId) {
-        newCidList.push(j.label)
-        flag = true
-      } else {
-        if (j.children) {
-          let childList = JSON.parse(JSON.stringify(newCidList))
-          childList.push(j.label)
-          let list = this.nodeFun(j.children, newId, childList)
-          if (list) {
-            newCidList = list
-            flag = true
-          }
-        }
-      }
-    })
-    if (flag) {
-      return newCidList
-    }
-  },
-  /**
-   * 渲染文字水印背景
-   * @{Element} targetElement 目标元素
-   * @{params} text 水印字符串
-   */
-  addWaterMarker (targetElement, text = '') {
-    var cpyName = text
-    if (text && text.length > 16) {
-      cpyName = text.substring(0, 16)
-    }
-    var can = document.createElement('canvas')
-    can.width = 180
-    can.height = 110
-    can.style.display = 'none'
-    can.style.zIndex = '999999'
-
-    var cans = can.getContext('2d')
-    cans.rotate(-25 * Math.PI / 180)
-    cans.font = '800 16px Microsoft JhengHei'
-    cans.fillStyle = '#dcdee2'
-    cans.textAlign = 'center'
-    cans.textBaseline = 'Middle'
-    if (cans.measureText(cpyName).width > 180) {
-      var size = 180 / cpyName.length
-      cans.font = '600 ' + size + 'px ' + ' Microsoft JhengHei'
-    }
-    cans.fillText(cpyName, 60, 60)
-    targetElement.style.backgroundImage = 'url(' + can.toDataURL('image/png') + ')'
-  },
-  /**
-   * 时间格式转换
-   * @param {string | Date} dateString 时间
-   * @returns {string} yyyy年mm月ddr日
-   */
-  dateFormat (dateString) {
-    const year = new Date(dateString).getFullYear()
-    const month = new Date(dateString).getMonth() + 1
-    const day = new Date(dateString).getDate()
-    return `${year}年${month}月${day}日`
-  },
-  /**
-   * 文件大小【KB】转换
-   * @param {number} size KB大小
-   * @param {string} defaultUnit size=0时,默认的单位
-   * @returns {string}
-   */
-  fileSizeFormat (size, defaultUnit = ' KB') {
-    const kbToGb = 1048576
-    const kbToMb = 1024
-    const isNegative = Number(size) < 0
-    const positiveSize = Math.abs(size)
-    const positiveFormat = Number(positiveSize) >= kbToGb ? Math.floor((Number(positiveSize) / kbToGb * 100)) / 100 + ' GB'
-      : Number(positiveSize) >= kbToMb ? Math.floor((Number(positiveSize) / kbToMb * 100)) / 100 + ' MB'
-        : positiveSize + ' KB'
-    const format = isNegative ? '-' + positiveFormat : positiveFormat
-    return positiveSize ? format : 0 + defaultUnit
-  }
-}

+ 0 - 35
src/components/view_file/assets/excel_icon.svg

@@ -1,35 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="56px" height="56px">
-<defs>
-<filter filterUnits="userSpaceOnUse" id="Filter_0" x="0px" y="8px" width="35px" height="35px"  >
-                <feOffset in="SourceAlpha" dx="0.5" dy="0.866" />
-                <feGaussianBlur result="blurOut" stdDeviation="2" />
-                <feFlood flood-color="rgb(15, 140, 18)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(52, 201, 55)"
- d="M52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,4.000 C8.000,1.791 9.791,-0.000 12.000,-0.000 L41.000,-0.000 L56.000,14.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(40, 182, 42)"
- d="M8.000,14.000 L56.000,14.000 L56.000,28.000 L8.000,28.000 L8.000,14.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(22, 159, 25)"
- d="M8.000,28.000 L56.000,28.000 L56.000,42.000 L8.000,42.000 L8.000,28.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(15, 132, 16)"
- d="M8.000,42.000 L56.000,42.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,42.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(102, 241, 104)"
- d="M41.000,-0.000 L41.000,10.000 C41.000,12.209 42.791,14.000 45.000,14.000 L56.000,14.000 L41.000,-0.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(15, 132, 16)"
- d="M6.000,10.000 L26.000,10.000 C28.209,10.000 30.000,11.791 30.000,14.000 L30.000,34.000 C30.000,36.209 28.209,38.000 26.000,38.000 L6.000,38.000 C3.791,38.000 2.000,36.209 2.000,34.000 L2.000,14.000 C2.000,11.791 3.791,10.000 6.000,10.000 Z"/>
-</g>
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M8.571,31.900 L10.528,31.900 L12.474,31.900 L15.583,26.463 L18.681,31.900 L20.657,31.900 L22.622,31.900 L17.466,23.661 L22.278,16.109 L20.374,16.109 L18.470,16.109 L15.594,21.202 L12.819,16.109 L10.861,16.109 L8.915,16.109 L13.685,23.908 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 L8.571,31.900 Z"/>
-</svg>

+ 0 - 34
src/components/view_file/assets/exe_icon.svg

@@ -1,34 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="56px" height="56px">
-<defs>
-<filter filterUnits="userSpaceOnUse" id="Filter_0" x="0px" y="30px" width="47px" height="23px"  >
-                <feOffset in="SourceAlpha" dx="0.5" dy="0.866" />
-                <feGaussianBlur result="blurOut" stdDeviation="2" />
-                <feFlood flood-color="rgb(17, 148, 160)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(0, 210, 230)"
- d="M52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,4.000 C8.000,1.791 9.791,-0.000 12.000,-0.000 L41.000,-0.000 L56.000,14.000 L56.000,3.999 C56.000,3.999 56.000,4.000 56.000,4.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(141, 245, 255)"
- d="M41.000,-0.000 L41.000,10.000 C41.000,12.209 42.791,14.000 45.000,14.000 L56.000,14.000 L41.000,-0.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(140, 245, 255)"
- d="M31.928,15.193 C31.857,15.568 31.476,15.944 31.088,16.027 L30.813,16.087 C30.122,16.282 29.501,16.721 29.113,17.361 C28.725,17.997 28.637,18.721 28.803,19.384 L28.887,19.652 C29.004,20.018 28.852,20.517 28.545,20.761 C28.545,20.761 28.274,20.983 27.498,21.408 C26.722,21.830 26.383,21.947 26.383,21.947 C26.006,22.078 25.473,21.954 25.202,21.676 L25.008,21.479 C24.486,21.006 23.777,20.714 22.997,20.714 C22.218,20.714 21.512,21.003 20.987,21.475 L20.793,21.673 C20.518,21.951 19.989,22.075 19.611,21.944 C19.611,21.944 19.276,21.830 18.500,21.405 C17.724,20.979 17.449,20.758 17.449,20.758 C17.142,20.510 16.991,20.011 17.107,19.649 L17.188,19.391 C17.357,18.724 17.266,17.997 16.878,17.357 C16.490,16.714 15.869,16.278 15.178,16.084 L14.903,16.024 C14.511,15.940 14.134,15.565 14.064,15.190 C14.064,15.190 14.000,14.854 14.000,14.004 C14.000,13.152 14.064,12.817 14.064,12.817 C14.134,12.442 14.515,12.067 14.903,11.983 L15.185,11.923 C15.876,11.729 16.493,11.293 16.881,10.653 C17.269,10.013 17.358,9.289 17.192,8.623 L17.107,8.358 C16.991,7.993 17.143,7.497 17.449,7.252 C17.449,7.252 17.721,7.031 18.497,6.602 C19.273,6.180 19.611,6.063 19.611,6.063 C19.989,5.932 20.521,6.056 20.793,6.334 L20.990,6.535 C21.512,7.007 22.221,7.296 22.997,7.296 C23.773,7.296 24.475,7.011 24.997,6.542 L25.202,6.334 C25.477,6.056 26.006,5.932 26.383,6.063 C26.383,6.063 26.718,6.180 27.494,6.602 C28.270,7.028 28.545,7.249 28.545,7.249 C28.852,7.497 29.003,7.996 28.887,8.358 L28.795,8.619 C28.626,9.286 28.718,10.013 29.106,10.653 C29.494,11.290 30.104,11.722 30.792,11.919 L31.084,11.983 C31.476,12.067 31.853,12.445 31.924,12.817 C31.924,12.817 31.987,13.152 31.991,14.007 C31.991,14.858 31.928,15.193 31.928,15.193 ZM22.891,10.375 C20.949,10.375 19.375,11.942 19.375,13.875 C19.375,15.808 20.949,17.375 22.891,17.375 C24.832,17.375 26.406,15.808 26.406,13.875 C26.406,11.942 24.832,10.375 22.891,10.375 Z"/>
-<path fill-rule="evenodd"  fill="rgb(140, 245, 255)"
- d="M49.915,32.642 C49.821,33.158 49.313,33.674 48.796,33.789 L48.429,33.872 C47.507,34.139 46.679,34.743 46.162,35.622 C45.644,36.498 45.527,37.492 45.748,38.404 L45.861,38.773 C46.016,39.275 45.814,39.961 45.404,40.297 C45.404,40.297 45.042,40.602 44.008,41.186 C42.973,41.767 42.521,41.928 42.521,41.928 C42.018,42.108 41.308,41.937 40.946,41.555 L40.687,41.283 C39.991,40.633 39.046,40.233 38.006,40.233 C36.967,40.233 36.026,40.629 35.325,41.278 L35.067,41.550 C34.700,41.932 33.994,42.103 33.491,41.923 C33.491,41.923 33.044,41.767 32.009,41.182 C30.975,40.597 30.608,40.293 30.608,40.293 C30.199,39.952 29.996,39.266 30.152,38.768 L30.260,38.413 C30.485,37.497 30.363,36.498 29.846,35.618 C29.329,34.733 28.501,34.135 27.579,33.868 L27.212,33.785 C26.690,33.670 26.187,33.154 26.093,32.638 C26.093,32.638 26.008,32.177 26.008,31.007 C26.008,29.837 26.093,29.377 26.093,29.377 C26.187,28.861 26.695,28.345 27.212,28.230 L27.588,28.147 C28.510,27.880 29.333,27.281 29.851,26.401 C30.368,25.522 30.486,24.527 30.264,23.610 L30.152,23.246 C29.997,22.744 30.199,22.063 30.608,21.727 C30.608,21.727 30.970,21.423 32.005,20.833 C33.040,20.253 33.491,20.091 33.491,20.091 C33.994,19.912 34.704,20.082 35.067,20.465 L35.330,20.741 C36.026,21.390 36.971,21.786 38.006,21.786 C39.041,21.786 39.977,21.395 40.673,20.750 L40.946,20.465 C41.313,20.082 42.018,19.912 42.521,20.091 C42.521,20.091 42.968,20.253 44.003,20.833 C45.038,21.418 45.404,21.722 45.404,21.722 C45.813,22.063 46.016,22.749 45.861,23.246 L45.738,23.606 C45.512,24.522 45.635,25.522 46.152,26.401 C46.669,27.277 47.483,27.871 48.400,28.142 L48.791,28.230 C49.313,28.345 49.816,28.866 49.910,29.377 C49.910,29.377 49.995,29.837 50.000,31.012 C50.000,32.182 49.915,32.642 49.915,32.642 ZM37.719,26.562 C34.940,26.562 32.688,28.752 32.688,31.453 C32.688,34.154 34.940,36.344 37.719,36.344 C40.497,36.344 42.750,34.154 42.750,31.453 C42.750,28.752 40.497,26.562 37.719,26.562 Z"/>
-<path fill-rule="evenodd"  fill="rgb(0, 165, 189)"
- d="M8.000,38.000 L56.000,38.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,38.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(0, 175, 201)"
- d="M5.000,32.000 L39.000,32.000 C40.657,32.000 42.000,33.343 42.000,35.000 L42.000,45.000 C42.000,46.657 40.657,48.000 39.000,48.000 L5.000,48.000 C3.343,48.000 2.000,46.657 2.000,45.000 L2.000,35.000 C2.000,33.343 3.343,32.000 5.000,32.000 Z"/>
-</g>
-<text kerning="auto" font-family="Adobe Heiti Std" fill="rgb(0, 0, 0)" font-size="12px" x="9px" y="45.0619999999999px"><tspan font-size="12px" font-family="Hiragino Sans GB" fill="#FFFFFF">EXE</tspan></text>
-</svg>

+ 0 - 54
src/components/view_file/assets/folder_icon.svg

@@ -1,54 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="52px" height="54px">
-<defs>
-<filter filterUnits="userSpaceOnUse" id="Filter_0" x="7px" y="3px" width="45px" height="45px"  >
-                <feOffset in="SourceAlpha" dx="1" dy="1.732" />
-                <feGaussianBlur result="blurOut" stdDeviation="1.732" />
-                <feFlood flood-color="rgb(255, 189, 32)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-<filter filterUnits="userSpaceOnUse" id="Filter_1" x="5px" y="12px" width="45px" height="37px"  >
-                <feOffset in="SourceAlpha" dx="1" dy="1.732" />
-                <feGaussianBlur result="blurOut" stdDeviation="1.732" />
-                <feFlood flood-color="rgb(255, 189, 32)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-<linearGradient id="PSgrad_0" x1="0%" x2="0%" y1="100%" y2="0%">
-  <stop offset="38%" stop-color="rgb(39,145,255)" stop-opacity="1" />
-  <stop offset="100%" stop-color="rgb(82,167,255)" stop-opacity="1" />
-</linearGradient>
-<linearGradient id="PSgrad_1" x1="0%" x2="0%" y1="100%" y2="0%">
-  <stop offset="0%" stop-color="rgb(255,189,32)" stop-opacity="1" />
-  <stop offset="100%" stop-color="rgb(254,230,149)" stop-opacity="1" />
-</linearGradient>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(255, 189, 32)"
- d="M5.000,-0.000 L41.000,-0.000 C46.523,-0.000 51.000,4.477 51.000,10.000 L51.000,50.000 C51.000,52.209 49.209,54.000 47.000,54.000 L17.000,54.000 C8.163,54.000 1.000,46.836 1.000,38.000 L1.000,4.000 C1.000,1.791 2.791,-0.000 5.000,-0.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(36, 240, 255)"
- d="M18.427,3.922 L39.677,9.616 C45.012,11.045 48.178,16.529 46.748,21.863 L42.089,39.250 C41.518,41.384 39.324,42.650 37.190,42.078 L15.940,36.384 C10.605,34.955 7.440,29.471 8.869,24.137 L13.528,6.750 C14.099,4.616 16.293,3.350 18.427,3.922 Z"/>
-</g>
-<g filter="url(#Filter_1)">
-<path fill-rule="evenodd"  fill="url(#PSgrad_0)"
- d="M10.000,12.000 L36.000,12.000 C41.523,12.000 46.000,16.477 46.000,22.000 L46.000,40.000 C46.000,42.209 44.209,44.000 42.000,44.000 L16.000,44.000 C10.477,44.000 6.000,39.523 6.000,34.000 L6.000,16.000 C6.000,13.791 7.791,12.000 10.000,12.000 Z"/>
-</g>
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M38.500,29.000 L18.500,29.000 C17.672,29.000 17.000,28.328 17.000,27.500 C17.000,26.671 17.672,26.000 18.500,26.000 L38.500,26.000 C39.328,26.000 40.000,26.671 40.000,27.500 C40.000,28.328 39.328,29.000 38.500,29.000 ZM28.500,23.000 L18.500,23.000 C17.672,23.000 17.000,22.328 17.000,21.500 C17.000,20.671 17.672,20.000 18.500,20.000 L28.500,20.000 C29.328,20.000 30.000,20.671 30.000,21.500 C30.000,22.328 29.328,23.000 28.500,23.000 ZM12.500,29.000 C11.672,29.000 11.000,28.328 11.000,27.500 C11.000,26.671 11.672,26.000 12.500,26.000 C13.328,26.000 14.000,26.671 14.000,27.500 C14.000,28.328 13.328,29.000 12.500,29.000 ZM12.500,23.000 C11.672,23.000 11.000,22.328 11.000,21.500 C11.000,20.671 11.672,20.000 12.500,20.000 C13.328,20.000 14.000,20.671 14.000,21.500 C14.000,22.328 13.328,23.000 12.500,23.000 Z"/>
-<path fill-rule="evenodd"  opacity="0.522" fill="rgb(66, 124, 190)"
- d="M4.174,43.000 C3.423,41.146 3.000,39.123 3.000,37.000 L3.000,33.000 L39.000,33.000 C44.523,33.000 49.000,37.477 49.000,43.000 L49.000,43.000 L4.174,43.000 Z"/>
-<path fill-rule="evenodd"  fill="url(#PSgrad_1)"
- d="M1.000,34.000 L41.000,34.000 C46.523,34.000 51.000,38.477 51.000,44.000 L51.000,50.000 C51.000,52.209 49.209,54.000 47.000,54.000 L17.000,54.000 C8.163,54.000 1.000,46.836 1.000,38.000 L1.000,34.000 Z"/>
-</svg>

+ 0 - 13
src/components/view_file/assets/image_icon.svg

@@ -1,13 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="48px" height="50px">
-<path fill-rule="evenodd"  fill="rgb(0, 132, 228)"
- d="M7.990,-0.010 L39.990,-0.010 C44.408,-0.010 47.990,3.572 47.990,7.990 L47.990,39.990 C47.990,45.513 43.513,49.990 37.990,49.990 L9.990,49.990 C4.467,49.990 -0.010,45.513 -0.010,39.990 L-0.010,7.990 C-0.010,3.572 3.572,-0.010 7.990,-0.010 Z"/>
-<path fill-rule="evenodd"  fill="rgb(253, 204, 15)"
- d="M30.994,8.990 C34.857,8.990 37.988,12.124 37.988,15.990 C37.988,19.856 34.857,22.990 30.994,22.990 C27.131,22.990 24.000,19.856 24.000,15.990 C24.000,12.124 27.131,8.990 30.994,8.990 Z"/>
-<path fill-rule="evenodd"  fill="rgb(235, 120, 38)"
- d="M47.990,27.493 L47.990,41.990 C47.990,46.408 44.408,49.990 39.990,49.990 L9.635,49.990 C16.426,44.704 21.485,39.558 21.485,39.558 C36.963,26.952 42.758,27.029 42.758,27.029 C44.861,27.029 46.584,27.222 47.990,27.493 Z"/>
-<path fill-rule="evenodd"  fill="rgb(255, 160, 76)"
- d="M39.990,49.990 L7.990,49.990 C3.572,49.990 -0.010,46.408 -0.010,41.990 L-0.010,23.374 C4.394,22.284 8.236,23.719 11.000,25.029 C15.711,27.263 22.434,34.813 28.000,37.020 C37.289,40.701 47.882,38.048 47.990,38.021 L47.990,41.990 C47.990,46.408 44.408,49.990 39.990,49.990 Z"/>
-</svg>

+ 0 - 29
src/components/view_file/assets/other_icon.svg

@@ -1,29 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="46px" height="56px">
-<defs>
-<linearGradient id="PSgrad_0" x1="57.358%" x2="0%" y1="0%" y2="81.915%">
-  <stop offset="0%" stop-color="rgb(255,255,255)" stop-opacity="1" />
-  <stop offset="100%" stop-color="rgb(237,145,0)" stop-opacity="1" />
-</linearGradient>
-<filter id="Filter_0">
-                <feFlood flood-color="rgb(255, 255, 255)" flood-opacity="1" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="SourceGraphic" result="compOut" />
-                <feBlend mode="normal" in="compOut" in2="SourceGraphic" />
-            </filter>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(255, 225, 179)"
- d="M10.000,0.000 L42.000,0.000 C44.209,0.000 46.000,1.791 46.000,4.000 L46.000,46.000 C46.000,48.209 44.209,50.000 42.000,50.000 L10.000,50.000 C7.791,50.000 6.000,48.209 6.000,46.000 L6.000,4.000 C6.000,1.791 7.791,0.000 10.000,0.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(255, 180, 50)"
- d="M38.000,56.000 L4.000,56.000 C1.791,56.000 -0.000,54.209 -0.000,52.000 L-0.000,9.000 C-0.000,6.791 1.791,5.000 4.000,5.000 L25.000,5.000 L42.000,19.000 L42.000,8.999 C42.000,8.999 42.000,9.000 42.000,9.000 L42.000,52.000 C42.000,54.209 40.209,56.000 38.000,56.000 Z"/>
-<path fill-rule="evenodd"  opacity="0.831" fill="rgb(237, 153, 33)"
- d="M27.000,9.000 L27.000,19.000 C27.000,21.209 28.791,23.000 31.000,23.000 L42.000,23.000 L42.000,19.000 L27.000,9.000 Z"/>
-<path fill-rule="evenodd"  fill="url(#PSgrad_0)"
- d="M25.000,5.000 L25.000,15.000 C25.000,17.209 26.791,19.000 29.000,19.000 L42.000,19.000 L25.000,5.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(215, 154, 47)"
- d="M24.000,32.513 C23.275,33.154 23.000,34.561 23.000,36.000 C23.000,36.762 23.000,36.477 23.000,37.000 L19.000,37.000 C19.031,36.706 19.000,35.000 19.000,35.000 C19.000,33.587 19.284,32.546 19.979,31.630 C20.499,30.950 20.698,30.766 22.310,29.641 C23.897,28.542 24.492,27.705 24.492,26.528 C24.492,24.958 22.959,24.000 21.000,24.000 C18.005,24.000 17.477,26.519 17.306,27.105 C17.056,27.971 16.566,28.850 15.653,28.850 C14.740,28.850 14.000,28.069 14.000,27.105 C14.000,24.216 16.289,21.000 21.439,21.000 C25.509,21.000 28.013,23.720 28.013,26.501 C28.013,29.587 25.449,31.251 24.000,32.513 ZM23.000,43.000 L19.000,43.000 L19.000,39.000 L23.000,39.000 L23.000,43.000 Z"/>
-</g>
-</svg>

+ 0 - 46
src/components/view_file/assets/pdf_icon.svg

@@ -1,46 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="56px" height="56px">
-<defs>
-<filter filterUnits="userSpaceOnUse" id="Filter_0" x="19px" y="4px" width="31px" height="31px"  >
-                <feOffset in="SourceAlpha" dx="0.5" dy="0.866" />
-                <feGaussianBlur result="blurOut" stdDeviation="1.414" />
-                <feFlood flood-color="rgb(195, 0, 0)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-<filter filterUnits="userSpaceOnUse" id="Filter_1" x="0px" y="33px" width="47px" height="23px"  >
-                <feOffset in="SourceAlpha" dx="0.5" dy="0.866" />
-                <feGaussianBlur result="blurOut" stdDeviation="2" />
-                <feFlood flood-color="rgb(160, 17, 17)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(244, 64, 64)"
- d="M52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,4.000 C8.000,1.791 9.791,-0.000 12.000,-0.000 L41.000,-0.000 L56.000,14.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(255, 125, 125)"
- d="M41.000,-0.000 L41.000,10.000 C41.000,12.209 42.791,14.000 45.000,14.000 L56.000,14.000 L41.000,-0.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(160, 7, 7)"
- d="M8.000,42.000 L56.000,42.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,42.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M46.513,22.024 C45.672,21.119 43.991,20.607 41.588,20.607 C40.297,20.607 38.825,20.728 37.203,21.029 C36.303,20.125 35.372,19.070 34.501,17.834 C33.870,16.960 33.329,16.056 32.849,15.152 C33.810,12.168 34.260,9.757 34.260,8.008 C34.260,6.049 33.570,4.000 31.527,4.000 C30.897,4.000 30.296,4.392 29.966,4.934 C29.065,6.592 29.455,10.209 31.047,13.765 C30.446,15.544 29.846,17.261 29.065,19.160 C28.404,20.758 27.623,22.446 26.812,23.953 C22.248,25.821 19.304,27.991 19.034,29.679 C18.914,30.312 19.124,30.915 19.575,31.367 C19.725,31.488 20.325,32.000 21.317,32.000 C24.350,32.000 27.533,26.997 29.155,23.953 C30.386,23.531 31.648,23.139 32.879,22.777 C34.230,22.385 35.612,22.084 36.843,21.873 C40.026,24.796 42.849,25.279 44.261,25.279 C46.003,25.279 46.633,24.555 46.844,23.953 C47.174,23.199 46.934,22.355 46.543,21.903 L46.513,22.024 ZM44.892,23.259 C44.772,23.892 44.141,24.314 43.270,24.314 C43.030,24.314 42.819,24.284 42.579,24.224 C40.988,23.832 39.516,23.018 38.014,21.752 C39.486,21.511 40.717,21.451 41.498,21.451 C42.369,21.451 43.120,21.481 43.600,21.632 C44.171,21.752 45.072,22.144 44.892,23.259 L44.892,23.259 ZM36.092,21.270 C35.011,21.481 33.870,21.752 32.669,22.084 C31.708,22.355 30.717,22.626 29.725,22.988 C30.266,21.933 30.717,20.908 31.137,19.944 C31.648,18.738 32.038,17.533 32.458,16.387 C32.879,17.111 33.329,17.834 33.780,18.467 C34.531,19.462 35.311,20.426 36.092,21.270 L36.092,21.270 ZM30.656,5.447 C30.837,5.115 31.167,4.934 31.437,4.934 C32.308,4.934 32.458,5.959 32.458,6.773 C32.458,8.129 32.038,10.209 31.347,12.590 C30.146,9.274 30.056,6.532 30.656,5.447 L30.656,5.447 ZM26.122,25.249 C24.019,28.805 21.977,31.035 20.746,31.035 C20.506,31.035 20.296,30.945 20.115,30.824 C19.875,30.583 19.755,30.282 19.815,29.920 C20.055,28.654 22.428,26.876 26.122,25.249 L26.122,25.249 Z"/>
-</g>
-<g filter="url(#Filter_1)">
-<path fill-rule="evenodd"  fill="rgb(194, 27, 27)"
- d="M5.000,35.000 L39.000,35.000 C40.657,35.000 42.000,36.343 42.000,38.000 L42.000,48.000 C42.000,49.657 40.657,51.000 39.000,51.000 L5.000,51.000 C3.343,51.000 2.000,49.657 2.000,48.000 L2.000,38.000 C2.000,36.343 3.343,35.000 5.000,35.000 Z"/>
-</g>
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M30.873,39.636 L30.873,41.919 L35.276,41.919 L35.276,42.780 L35.276,43.648 L30.873,43.648 L30.873,47.900 L29.827,47.900 L28.775,47.900 L28.775,37.852 L35.925,37.852 L35.925,38.740 L35.925,39.636 L30.873,39.636 ZM22.793,47.900 L19.710,47.900 L18.664,47.900 L18.664,37.852 L19.710,37.852 L22.964,37.852 C24.345,37.852 25.394,38.257 26.112,39.068 C26.830,39.880 27.189,41.067 27.189,42.630 C27.189,44.352 26.816,45.662 26.071,46.557 C25.326,47.453 24.233,47.900 22.793,47.900 ZM24.495,40.364 C24.099,39.842 23.502,39.581 22.704,39.581 L20.763,39.581 L20.763,46.171 L22.533,46.171 C23.385,46.171 24.025,45.883 24.451,45.306 C24.877,44.730 25.090,43.865 25.090,42.712 C25.090,41.668 24.892,40.886 24.495,40.364 ZM13.530,44.311 C12.719,44.307 12.017,44.311 11.425,44.325 L11.425,47.900 L10.379,47.900 L9.326,47.900 L9.326,37.852 L10.372,37.852 L13.530,37.852 C14.674,37.852 15.545,38.119 16.142,38.655 C16.739,39.190 17.037,39.971 17.037,40.996 C17.037,42.081 16.739,42.904 16.142,43.467 C15.545,44.030 14.674,44.311 13.530,44.311 ZM14.498,39.940 C14.204,39.701 13.763,39.581 13.175,39.581 L11.425,39.581 L11.425,42.582 L13.175,42.582 C13.763,42.582 14.204,42.452 14.498,42.192 C14.792,41.933 14.939,41.541 14.939,41.017 C14.939,40.538 14.792,40.179 14.498,39.940 Z"/>
-</svg>

+ 0 - 35
src/components/view_file/assets/ppt_icon.svg

@@ -1,35 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="56px" height="56px">
-<defs>
-<filter filterUnits="userSpaceOnUse" id="Filter_0" x="0px" y="22px" width="49px" height="29px"  >
-                <feOffset in="SourceAlpha" dx="0.5" dy="0.866" />
-                <feGaussianBlur result="blurOut" stdDeviation="2" />
-                <feFlood flood-color="rgb(160, 68, 17)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(245, 118, 64)"
- d="M52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,4.000 C8.000,1.791 9.791,-0.000 12.000,-0.000 L41.000,-0.000 L56.000,14.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(255, 164, 125)"
- d="M41.000,-0.000 L41.000,10.000 C41.000,12.209 42.791,14.000 45.000,14.000 L56.000,14.000 L41.000,-0.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(222, 101, 49)"
- d="M8.000,14.000 L56.000,14.000 L56.000,28.000 L8.000,28.000 L8.000,14.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(194, 77, 27)"
- d="M8.000,28.000 L56.000,28.000 L56.000,42.000 L8.000,42.000 L8.000,28.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(161, 61, 18)"
- d="M8.000,42.000 L56.000,42.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,42.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(161, 61, 18)"
- d="M6.000,24.000 L40.000,24.000 C42.209,24.000 44.000,25.791 44.000,28.000 L44.000,42.000 C44.000,44.209 42.209,46.000 40.000,46.000 L6.000,46.000 C3.791,46.000 2.000,44.209 2.000,42.000 L2.000,28.000 C2.000,25.791 3.791,24.000 6.000,24.000 Z"/>
-</g>
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M34.697,31.455 L34.697,40.900 L33.502,40.900 L32.299,40.900 L32.299,31.455 L28.830,31.455 L28.830,30.439 L28.830,29.416 L38.166,29.416 L38.166,30.432 L38.166,31.455 L34.697,31.455 ZM23.955,36.799 C23.028,36.794 22.226,36.799 21.549,36.814 L21.549,40.900 L20.354,40.900 L19.151,40.900 L19.151,29.416 L20.346,29.416 L23.955,29.416 C25.262,29.416 26.257,29.722 26.940,30.334 C27.622,30.946 27.963,31.838 27.963,33.010 C27.963,34.249 27.622,35.191 26.940,35.834 C26.257,36.477 25.262,36.799 23.955,36.799 ZM25.061,31.803 C24.725,31.529 24.221,31.393 23.549,31.393 L21.549,31.393 L21.549,34.822 L23.549,34.822 C24.221,34.822 24.725,34.674 25.061,34.377 C25.397,34.080 25.565,33.632 25.565,33.033 C25.565,32.486 25.397,32.076 25.061,31.803 ZM13.283,36.799 C12.356,36.794 11.554,36.799 10.877,36.814 L10.877,40.900 L9.682,40.900 L8.479,40.900 L8.479,29.416 L9.674,29.416 L13.283,29.416 C14.591,29.416 15.585,29.722 16.268,30.334 C16.950,30.946 17.291,31.838 17.291,33.010 C17.291,34.249 16.950,35.191 16.268,35.834 C15.585,36.477 14.591,36.799 13.283,36.799 ZM14.389,31.803 C14.053,31.529 13.549,31.393 12.877,31.393 L10.877,31.393 L10.877,34.822 L12.877,34.822 C13.549,34.822 14.053,34.674 14.389,34.377 C14.725,34.080 14.893,33.632 14.893,33.033 C14.893,32.486 14.725,32.076 14.389,31.803 Z"/>
-</svg>

+ 0 - 11
src/components/view_file/assets/video_icon.svg

@@ -1,11 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="50px" height="40px">
-<path fill-rule="evenodd"  fill="rgb(45, 140, 240)"
- d="M8.000,-0.000 L32.000,-0.000 C36.418,-0.000 40.000,3.582 40.000,8.000 L40.000,32.000 C40.000,36.418 36.418,40.000 32.000,40.000 L8.000,40.000 C3.582,40.000 -0.000,36.418 -0.000,32.000 L-0.000,8.000 C-0.000,3.582 3.582,-0.000 8.000,-0.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(241, 208, 80)"
- d="M16.193,9.993 C15.052,9.993 14.000,10.919 14.000,12.225 L14.000,27.774 C14.000,29.080 15.053,30.006 16.193,30.006 C16.486,30.006 16.785,29.945 17.073,29.814 L28.866,22.387 C29.620,21.782 29.997,20.891 29.997,20.000 C29.997,19.108 29.620,18.217 28.866,17.612 L17.073,10.186 C16.785,10.054 16.486,9.993 16.193,9.993 "/>
-<path fill-rule="evenodd"  fill="rgb(126, 189, 255)"
- d="M44.920,33.767 L40.000,31.127 L40.000,9.872 L44.920,7.232 C47.218,5.999 50.000,7.663 50.000,10.269 L50.000,30.730 C50.000,33.337 47.218,35.000 44.920,33.767 Z"/>
-</svg>

+ 0 - 1
src/components/view_file/assets/view_off.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1623827680993" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6860" width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M971.232 41.216l0.768 0.768a32 32 0 0 1 0 44.96L88.512 982.496a31.808 31.808 0 0 1-41.952 2.944l-3.808-3.424a32 32 0 0 1 0-44.96l169.12-171.36c-58.08-49.28-112.256-114.4-162.592-195.36l-7.84-12.8a65.664 65.664 0 0 1 0-67.84c130.176-215.392 286.656-323.104 469.44-323.104 81.312 0 157.6 21.312 228.8 64l186.56-189.088a31.808 31.808 0 0 1 44.992-0.32zM828.576 297.28c51.584 47.04 100.16 106.72 145.728 179.104l8.096 13.024c12.8 20.96 12.8 47.488 0 68.448-131.68 215.2-288.864 322.784-471.52 322.784-73.152 0-142.08-17.248-206.784-51.712l47.84-48.48a369.888 369.888 0 0 0 158.944 35.296c158.144 0 296.192-94.528 417.088-292.096l-7.68-12.352c-43.424-69.056-89.088-124.96-137.024-168.128l45.312-45.888z m-317.696-65.792c-158.112 0-295.392 94.496-414.848 292.16l7.424 12.064c48.32 77.76 99.552 138.88 153.856 183.904l91.008-92.256a195.776 195.776 0 0 1-29.504-103.744c0-107.552 86.016-194.752 192.128-194.752 37.6 0 72.704 10.976 102.336 29.92l79.424-80.544a373.76 373.76 0 0 0-181.824-46.72z m174.656 210.784c11.264 24.768 17.504 52.32 17.504 81.344 0 107.552-85.984 194.752-192.096 194.752a189.248 189.248 0 0 1-80.256-17.76l50.08-50.784c9.696 2.368 19.776 3.616 30.176 3.616 70.72 0 128.064-58.112 128.064-129.824a131.84 131.84 0 0 0-3.552-30.56l50.08-50.784z m-174.592-48.48c-70.72 0-128.096 58.112-128.096 129.824 0 20.064 4.48 39.04 12.48 56l170.88-173.152a126.144 126.144 0 0 0-55.264-12.672z" fill="#bfbfbf" p-id="6861"></path></svg>

+ 0 - 35
src/components/view_file/assets/word_icon.svg

@@ -1,35 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="56px" height="56px">
-<defs>
-<filter filterUnits="userSpaceOnUse" id="Filter_0" x="0px" y="8px" width="35px" height="35px"  >
-                <feOffset in="SourceAlpha" dx="0.5" dy="0.866" />
-                <feGaussianBlur result="blurOut" stdDeviation="2" />
-                <feFlood flood-color="rgb(15, 66, 140)" result="floodOut" />
-                <feComposite operator="atop" in="floodOut" in2="blurOut" />
-                <feComponentTransfer><feFuncA type="linear" slope="0.75"/></feComponentTransfer>
-                <feMerge>
-    <feMergeNode/>
-    <feMergeNode in="SourceGraphic"/>
-  </feMerge>
-            </filter>
-
-</defs>
-<path fill-rule="evenodd"  fill="rgb(63, 167, 240)"
- d="M52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,4.000 C8.000,1.791 9.791,-0.000 12.000,-0.000 L41.000,-0.000 L56.000,14.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(125, 201, 255)"
- d="M41.000,-0.000 L41.000,10.000 C41.000,12.209 42.791,14.000 45.000,14.000 L56.000,14.000 L41.000,-0.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(45, 121, 207)"
- d="M8.000,14.000 L56.000,14.000 L56.000,28.000 L8.000,28.000 L8.000,14.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(26, 90, 187)"
- d="M8.000,28.000 L56.000,28.000 L56.000,42.000 L8.000,42.000 L8.000,28.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(15, 66, 140)"
- d="M8.000,42.000 L56.000,42.000 L56.000,52.000 C56.000,54.209 54.209,56.000 52.000,56.000 L12.000,56.000 C9.791,56.000 8.000,54.209 8.000,52.000 L8.000,42.000 Z"/>
-<g filter="url(#Filter_0)">
-<path fill-rule="evenodd"  fill="rgb(22, 76, 178)"
- d="M6.000,10.000 L26.000,10.000 C28.209,10.000 30.000,11.791 30.000,14.000 L30.000,34.000 C30.000,36.209 28.209,38.000 26.000,38.000 L6.000,38.000 C3.791,38.000 2.000,36.209 2.000,34.000 L2.000,14.000 C2.000,11.791 3.791,10.000 6.000,10.000 Z"/>
-</g>
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M12.920,30.900 L14.631,30.900 L16.641,21.408 L16.633,21.408 L18.592,30.900 L20.315,30.900 L22.026,30.900 L25.717,18.150 L24.015,18.150 L22.325,18.150 L20.255,27.537 L20.255,27.537 L18.369,18.150 L16.682,18.150 L15.006,18.150 L13.108,27.514 L13.094,27.514 L11.058,18.150 L9.276,18.150 L7.494,18.150 L11.197,30.900 L11.197,30.900 L11.197,30.900 L11.197,30.900 L11.197,30.900 L11.197,30.900 L11.197,30.900 L11.197,30.900 L12.920,30.900 Z"/>
-</svg>

+ 0 - 24
src/components/view_file/assets/zip_icon.svg

@@ -1,24 +0,0 @@
-<svg 
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="52px" height="48px">
-<defs>
-<linearGradient id="PSgrad_0" x1="0%" x2="0%" y1="100%" y2="0%">
-  <stop offset="0%" stop-color="rgb(0,72,185)" stop-opacity="1" />
-  <stop offset="100%" stop-color="rgb(3,92,232)" stop-opacity="1" />
-</linearGradient>
-
-</defs>
-<path fill-rule="evenodd"  fill="url(#PSgrad_0)"
- d="M44.000,48.000 L8.000,48.000 C3.582,48.000 -0.000,44.418 -0.000,40.000 L-0.000,8.000 C-0.000,3.582 3.582,0.000 8.000,0.000 L21.254,-0.000 C26.007,-0.000 27.360,4.000 27.360,4.000 L44.000,4.000 C48.418,4.000 52.000,7.582 52.000,12.000 L52.000,40.000 C52.000,44.418 48.418,48.000 44.000,48.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(246, 98, 71)"
- d="M10.990,8.990 L40.990,8.990 C42.095,8.990 42.990,9.885 42.990,10.990 L42.990,40.990 L8.990,40.990 L8.990,10.990 C8.990,9.885 9.885,8.990 10.990,8.990 Z"/>
-<path fill-rule="evenodd"  fill="rgb(244, 209, 74)"
- d="M7.990,14.990 L43.990,14.990 C45.095,14.990 45.990,15.885 45.990,16.990 L45.990,37.990 L5.990,37.990 L5.990,16.990 C5.990,15.885 6.885,14.990 7.990,14.990 Z"/>
-<path fill-rule="evenodd"  fill="rgb(82, 221, 234)"
- d="M5.000,21.000 L47.000,21.000 C48.105,21.000 49.000,21.895 49.000,23.000 L49.000,44.000 L3.000,44.000 L3.000,23.000 C3.000,21.895 3.895,21.000 5.000,21.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(255, 255, 255)"
- d="M33.000,45.000 L27.000,45.000 L27.000,39.000 L33.000,39.000 L33.000,45.000 ZM21.000,39.000 L21.000,33.000 L27.000,33.000 L27.000,39.000 L21.000,39.000 ZM21.000,21.000 L27.000,21.000 L27.000,27.000 L21.000,27.000 L21.000,21.000 ZM21.000,9.000 L27.000,9.000 L27.000,15.000 L21.000,15.000 L21.000,9.000 ZM33.000,15.000 L33.000,21.000 L27.000,21.000 L27.000,15.000 L33.000,15.000 ZM33.000,27.000 L33.000,33.000 L27.000,33.000 L27.000,27.000 L33.000,27.000 Z"/>
-<path fill-rule="evenodd"  fill="rgb(22, 136, 255)"
- d="M51.878,26.000 L44.582,26.000 C41.168,26.000 38.103,28.090 36.857,31.268 L36.174,33.006 C35.466,34.812 33.724,36.000 31.784,36.000 L20.216,36.000 C18.276,36.000 16.534,34.812 15.825,33.006 L15.143,31.268 C13.897,28.090 10.831,26.000 7.418,26.000 L-0.000,26.000 L-0.000,40.000 C-0.000,44.400 3.600,48.000 8.000,48.000 L44.000,48.000 C48.400,48.000 52.000,44.400 52.000,40.000 L52.000,26.122 C52.000,26.055 51.945,26.000 51.878,26.000 Z"/>
-</svg>

+ 0 - 34
src/components/view_file/index.less

@@ -1,34 +0,0 @@
-.preview-wrapper {
-  padding: 20px 40px;
-  height: ~"calc(100vh - 320px)";
-  width: 100%;
-  overflow: scroll;
-  .loading-process {
-    width: 50%;
-    position: absolute;
-    top: 50%;
-    transform: translate(-50%, -50%);
-    left: 50%;
-    .load-text {
-      line-height: 28px;
-    }
-  }
-  .preview-inner {
-    width: 100%;
-    height: fit-content;
-    position: relative;
-    .preview-mark {
-      position: fixed;
-      inset: 0;
-      width: 100%;
-      height: 100%;
-      z-index: 999;
-      opacity: 0.7;
-      pointer-events: none;
-      user-select: none;
-    }
-  }
-  .error-wrapper {
-    height: 100%;
-  }
-}

+ 0 - 180
src/components/view_file/index.vue

@@ -1,180 +0,0 @@
-<template>
-  <div class="container">
-    <div class="modal-height">
-      <div class="file-box">
-        <p class="file-name" v-show="!renderLoading">{{ file.filename }}</p>
-        <div class="view-wrapper">
-          <div class="preview-wrapper" ref="wrapper" v-if="isAbleView">
-            <div class="preview-inner" ref="preview-inner">
-              <div class="preview-mark" ref="bg-mark" id="bg-mark"></div>
-              <div class="output" v-show="!renderLoading" ref="output"></div>
-              <div class="loading" v-if="renderLoading">
-                <el-spinner>
-                  <template #default>
-                    <div class="spinner">
-                      <div class="bounce1"></div>
-                      <div class="bounce2"></div>
-                      <div class="bounce3"></div>
-                    </div>
-                  </template>
-                </el-spinner>
-              </div>
-            </div>
-          </div>
-          <view-other-component
-            v-else-if="file.type && !isAbleView"
-            :file="file"
-          />
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-<script>
-import commJs from "@/comm_js"
-import { render } from "@/components/view_file/util"
-import ViewOtherComponent from "@/components/view_file/vendors/other/index"
-export default {
-  name: "ViewFileComponent",
-  components: {
-    ViewOtherComponent,
-  },
-  props: {
-    file: {
-      type: Object,
-      default: () => {
-        return {}
-      },
-    },
-  },
-  data() {
-    return {
-      reFreshFlag: false,
-      renderLoading: false,
-    }
-  },
-  computed: {
-    // 可在在线预览文件类型
-    isAbleView() {
-      const lowType = (this.file.type || "").toLowerCase()
-      const typeObject = {
-        doc: ["docx"],
-        xlsx: ["xlsx"],
-        pdf: ["pdf"],
-        ppt: ["pptx"],
-        image: ["gif", "jpg", "jpeg", "bmp", "tiff", "tif", "png", "svg"],
-        text: [
-          "txt",
-          "json",
-          "js",
-          "css",
-          "java",
-          "py",
-          "html",
-          "jsx",
-          "ts",
-          "tsx",
-          "xml",
-          "md",
-          "log",
-        ],
-      }
-      const ablePreviewTypes = Object.values(typeObject).flat()
-      return ablePreviewTypes.includes(lowType)
-    },
-  },
-  methods: {
-    /**
-     * @{params} buffer 文件字节流
-     * @{params} extend 文件扩展名
-     */
-    renderResult(buffer, extend) {
-      const { output } = this.$refs
-      output.innerHTML = ""
-      const node = document.createElement("div")
-      const child = output.appendChild(node)
-      return new Promise((resolve, reject) =>
-        render(buffer, extend, child).then(resolve).catch(reject)
-      )
-    },
-  },
-  watch: {
-    file: {
-      handler(newFile) {
-        if (newFile && newFile.type) {
-          try {
-            this.renderLoading = true
-            this.renderResult(newFile.fileBuffer, newFile.type).finally(() => {
-              this.renderLoading = false
-            })
-          } catch (error) {
-            console.warn(error)
-          }
-        }
-      },
-      immediate: true,
-      deep: true,
-    },
-  },
-}
-</script>
-<style lang="less">
-.container {
-  width: 100%;
-  height: 100%;
-  .docx-wrapper {
-    background: unset !important;
-    padding: 0 !important;
-
-    & > section.docx {
-      background: unset !important;
-    }
-  }
-}
-</style>
-<style lang="less" scoped>
-@import url("./index.less");
-@deep: ~">>>";
-
-@{deep} .header-rewrite {
-  margin-bottom: 0 !important;
-}
-
-.modal-height {
-  display: flex;
-  justify-content: space-between;
-  height: 100%;
-  .file-box {
-    flex: 1;
-    padding: 15px 40px;
-    overflow: scroll;
-    text-align: center;
-
-    .file-name {
-      line-height: 36px;
-      text-align: center;
-      font-size: 16px;
-      font-weight: 500;
-    }
-
-    .view-wrapper {
-      position: relative;
-      width: 100%;
-      height: ~"calc(100% - 36px)";
-      overflow: hidden;
-      .preview-inner {
-        position: relative;
-        width: 100%;
-        height: 100%;
-        .loading {
-          position: absolute;
-          top: 50%;
-          left: 50%;
-          transform: translate(-50%, -50%);
-          z-index: 999;
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 102
src/components/view_file/renders.js

@@ -1,102 +0,0 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-09 08:10:23
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-15 14:47:12
- * @Description:
- */
-import { defaultOptions, renderAsync } from "docx-preview"
-import renderPdf from "./vendors/pdf"
-import renderImage from "./vendors/image"
-import renderText from "./vendors/text"
-import renderPptx from "./vendors/pptx"
-import renderSheet from "./vendors/xlsx"
-// 假装构造一个vue的包装,让上层统一处理销毁和替换节点
-const VueWrapper = (el) => ({
-  $el: el,
-  $destroy() {
-    // 什么也不需要 nothing to do
-  },
-})
-
-const handlers = [
-  // 使用docxjs支持,目前效果最好的渲染器
-  {
-    accepts: ["docx"],
-    handler: async (buffer, target) => {
-      const docxOptions = {
-        ...defaultOptions,
-        ...{
-          debug: true,
-          experimental: true,
-        },
-      }
-      await renderAsync(buffer, target, null, docxOptions)
-      return VueWrapper(target)
-    },
-  },
-  // 使用pptx2html,已通过默认值更替
-  {
-    accepts: ["pptx"],
-    handler: async (buffer, target) => {
-      return renderPptx(buffer, target)
-    },
-  },
-  // 使用sheetjs + handsontable,无样式
-  {
-    accepts: ["xlsx"],
-    handler: async (buffer, target) => {
-      return renderSheet(buffer, target)
-    },
-  },
-  // 使用pdfjs,渲染pdf,效果最好
-  {
-    accepts: ["pdf"],
-    handler: async (buffer, target) => {
-      return renderPdf(buffer, target)
-    },
-  },
-  // 图片过滤器
-  {
-    accepts: ["gif", "jpg", "jpeg", "bmp", "tiff", "tif", "png", "svg"],
-    handler: async (buffer, target) => {
-      return renderImage(buffer, target)
-    },
-  },
-  // 纯文本预览
-  {
-    accepts: [
-      "txt",
-      "json",
-      "js",
-      "css",
-      "java",
-      "py",
-      "html",
-      "jsx",
-      "ts",
-      "tsx",
-      "xml",
-      "md",
-      "log",
-    ],
-    handler: async (buffer, target) => {
-      return renderText(buffer, target)
-    },
-  },
-  // 错误处理
-  {
-    accepts: ["error"],
-    handler: async (buffer, target, type) => {
-      target.innerHTML = `<div style="text-align: center margin-top: 80px">不支持.${type}格式的在线预览,请下载后预览或转换为支持的格式</div>
-<div style="text-align: center">支持docx, xlsx, pptx, pdf, 以及纯文本格式和各种图片格式的在线预览</div>`
-      return VueWrapper(target)
-    },
-  },
-]
-
-// 匹配
-export default handlers.reduce((result, { accepts, handler }) => {
-  accepts.forEach((type) => (result[type] = handler))
-  return result
-}, {})

+ 0 - 41
src/components/view_file/util.js

@@ -1,41 +0,0 @@
-import renders from "./renders"
-
-export async function readBuffer(file) {
-  return new Promise((resolve, reject) => {
-    const reader = new FileReader()
-    reader.onload = (loadEvent) => resolve(loadEvent.target.result)
-    reader.onerror = (e) => reject(e)
-    reader.readAsArrayBuffer(file)
-  })
-}
-
-export async function readDataURL(buffer) {
-  return new Promise((resolve, reject) => {
-    const reader = new FileReader()
-    reader.onload = (loadEvent) => resolve(loadEvent.target.result)
-    reader.onerror = (e) => reject(e)
-    reader.readAsDataURL(new Blob([buffer]))
-  })
-}
-
-export async function readText(buffer) {
-  return new Promise((resolve, reject) => {
-    const reader = new FileReader()
-    reader.onload = (loadEvent) => resolve(loadEvent.target.result)
-    reader.onerror = (e) => reject(e)
-    reader.readAsText(new Blob([buffer]), "utf-8")
-  })
-}
-
-export function getExtend(name) {
-  const dot = name.lastIndexOf(".")
-  return name.substr(dot + 1)
-}
-
-export async function render(buffer, type, target) {
-  const handler = renders[type]
-  if (handler) {
-    return handler(buffer, target)
-  }
-  return renders.error(buffer, target, type)
-}

+ 0 - 470
src/components/view_file/vendors/colz/index.js

@@ -1,470 +0,0 @@
-/**
- * Colorz (or Colz) is a Javascript "library" to help
- * in color conversion between the usual color-spaces
- * Hex - Rgb - Hsl / Hsv - Hsb
- *
- * It provides some helpers to output Canvas / CSS
- * color strings.
- *
- * by Carlos Cabo 2013
- * http://carloscabo.com
- *
- * Some formulas borrowed from Wikipedia or other authors.
- */
-
-const round = Math.round
-
-/*
- ==================================
- Color constructors
- ==================================
-*/
-
-export class Rgb {
-  constructor (col) {
-    this.r = col[0]
-    this.g = col[1]
-    this.b = col[2]
-  }
-
-  toString () {
-    return `rgb(${this.r},${this.g},${this.b})`
-  }
-}
-
-export class Rgba extends Rgb {
-  constructor (col) {
-    super(col)
-    this.a = col[3]
-  }
-
-  toString () {
-    return `rgba(${this.r},${this.g},${this.b},${this.a})`
-  }
-}
-
-export class Hsl {
-  constructor (col) {
-    this.h = col[0]
-    this.s = col[1]
-    this.l = col[2]
-  }
-
-  toString () {
-    return `hsl(${this.h},${this.s}%,${this.l}%)`
-  }
-}
-
-export class Hsla extends Hsl {
-  constructor (col) {
-    super(col)
-    this.a = col[3]
-  }
-
-  toString () {
-    return `hsla(${this.h},${this.s}%,${this.l}%,${this.a})`
-  }
-}
-
-/*
- ==================================
- Main Colz color object
- ==================================
-*/
-export class Color {
-  constructor (r, g, b, a = 1.0) {
-    // If args are not given in (r, g, b, [a]) format, convert
-    if (typeof r === 'string') {
-      let str = r
-      // Add initial '#' if missing
-      if (str.charAt(0) !== '#') { str = '#' + str }
-      // If Hex in #fff format convert to #ffffff
-      if (str.length < 7) {
-        str = '#' + str[1] + str[1] + str[2] + str[2] + str[3] + str[3]
-      }
-      ([r, g, b] = hexToRgb(str))
-    } else if (r instanceof Array) {
-      a = r[3] || a
-      b = r[2]
-      g = r[1]
-      r = r[0]
-    }
-
-    this.r = r
-    this.g = g
-    this.b = b
-    this.a = a
-
-    this.rgb = new Rgb([this.r, this.g, this.b])
-    this.rgba = new Rgba([this.r, this.g, this.b, this.a])
-    this.hex = rgbToHex(this.r, this.g, this.b)
-
-    this.hsl = new Hsl(rgbToHsl(this.r, this.g, this.b))
-    this.h = this.hsl.h
-    this.s = this.hsl.s
-    this.l = this.hsl.l
-    this.hsla = new Hsla([this.h, this.s, this.l, this.a])
-  }
-
-  setHue (newHue) {
-    this.h = newHue
-    this.hsl.h = newHue
-    this.hsla.h = newHue
-    this.updateFromHsl()
-  }
-
-  setSat (newSat) {
-    this.s = newSat
-    this.hsl.s = newSat
-    this.hsla.s = newSat
-    this.updateFromHsl()
-  }
-
-  setLum (newLum) {
-    this.l = newLum
-    this.hsl.l = newLum
-    this.hsla.l = newLum
-    this.updateFromHsl()
-  }
-
-  setAlpha (newAlpha) {
-    this.a = newAlpha
-    this.hsla.a = newAlpha
-    this.rgba.a = newAlpha
-  }
-
-  updateFromHsl () {
-    // Updates Rgb
-    this.rgb = null
-    this.rgb = new Rgb(hslToRgb(this.h, this.s, this.l))
-
-    this.r = this.rgb.r
-    this.g = this.rgb.g
-    this.b = this.rgb.b
-    this.rgba.r = this.rgb.r
-    this.rgba.g = this.rgb.g
-    this.rgba.b = this.rgb.b
-
-    // Updates Hex
-    this.hex = null
-    this.hex = rgbToHex([this.r, this.g, this.b])
-  }
-}
-
-/*
- ==================================
- Public Methods
- ==================================
-*/
-
-export const randomColor = function () {
-  const r = '#' + Math.random().toString(16).slice(2, 8)
-  return new Color(r)
-}
-
-export const hexToRgb = function (hex) {
-  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
-  return result ? [
-    parseInt(result[1], 16),
-    parseInt(result[2], 16),
-    parseInt(result[3], 16)
-  ] : null
-}
-
-export const componentToHex = function (c) {
-  const hex = c.toString(16)
-  return hex.length === 1 ? '0' + hex : hex
-}
-
-// You can pass 3 numeric values or 1 Array
-export const rgbToHex = function (r, g, b) {
-  if (r instanceof Array) {
-    b = r[2]
-    g = r[1]
-    r = r[0]
-  }
-  return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b)
-}
-
-/**
- * Converts an RGB color value to HSL. Conversion formula
- * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
- *
- * @param {Number} r The red color value
- * @param {Number} g The green color value
- * @param {Number} b The blue color value
- * @return {Array} The HSL representation
- */
-export const rgbToHsl = function (r, g, b) {
-  if (r instanceof Array) {
-    b = r[2]
-    g = r[1]
-    r = r[0]
-  }
-
-  let h, s, l, d, max, min
-
-  r /= 255
-  g /= 255
-  b /= 255
-
-  max = Math.max(r, g, b)
-  min = Math.min(r, g, b)
-  l = (max + min) / 2
-
-  if (max === min) {
-    h = s = 0 // achromatic
-  } else {
-    d = max - min
-    s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
-
-    switch (max) {
-      case r:
-        h = (g - b) / d + (g < b ? 6 : 0)
-        break
-      case g:
-        h = (b - r) / d + 2
-        break
-      case b:
-        h = (r - g) / d + 4
-        break
-    }
-
-    h /= 6
-  }
-
-  // CARLOS
-  h = round(h * 360)
-  s = round(s * 100)
-  l = round(l * 100)
-
-  return [h, s, l]
-}
-
-export const hue2rgb = function (p, q, t) {
-  if (t < 0) { t += 1 }
-  if (t > 1) { t -= 1 }
-  if (t < 1 / 6) { return p + (q - p) * 6 * t }
-  if (t < 1 / 2) { return q }
-  if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6 }
-  return p
-}
-
-/**
- * Converts an HSL color value to RGB. Conversion formula
- * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
- *
- * @param {Number} h The hue
- * @param {Number} s The saturation
- * @param {Number} l The lightness
- * @return {Array} The RGB representation
- */
-
-export const hslToRgb = function (h, s, l) {
-  if (h instanceof Array) {
-    l = h[2]
-    s = h[1]
-    h = h[0]
-  }
-  h = h / 360
-  s = s / 100
-  l = l / 100
-
-  let r, g, b, q, p
-
-  if (s === 0) {
-    r = g = b = l // achromatic
-  } else {
-    q = l < 0.5 ? l * (1 + s) : l + s - l * s
-    p = 2 * l - q
-    r = hue2rgb(p, q, h + 1 / 3)
-    g = hue2rgb(p, q, h)
-    b = hue2rgb(p, q, h - 1 / 3)
-  }
-  return [round(r * 255), round(g * 255), round(b * 255)]
-}
-
-/**
- * Converts an RGB color value to HSB / HSV. Conversion formula
- * adapted from http://en.wikipedia.org/wiki/HSV_color_space.
- *
- * @param {Number} r The red color value
- * @param {Number} g The green color value
- * @param {Number} b The blue color value
- * @return {Array} The HSB representation
- */
-export const rgbToHsb = function (r, g, b) {
-  let max, min, h, s, v, d
-
-  r = r / 255
-  g = g / 255
-  b = b / 255
-
-  max = Math.max(r, g, b)
-  min = Math.min(r, g, b)
-  v = max
-
-  d = max - min
-  s = max === 0 ? 0 : d / max
-
-  if (max === min) {
-    h = 0 // achromatic
-  } else {
-    switch (max) {
-      case r:
-        h = (g - b) / d + (g < b ? 6 : 0)
-        break
-      case g:
-        h = (b - r) / d + 2
-        break
-      case b:
-        h = (r - g) / d + 4
-        break
-    }
-    h /= 6
-  }
-
-  // map top 360,100,100
-  h = round(h * 360)
-  s = round(s * 100)
-  v = round(v * 100)
-
-  return [h, s, v]
-}
-
-/**
- * Converts an HSB / HSV color value to RGB. Conversion formula
- * adapted from http://en.wikipedia.org/wiki/HSV_color_space.
- *
- * @param {Number} h The hue
- * @param {Number} s The saturation
- * @param {Number} v The value
- * @return {Array} The RGB representation
- */
-export const hsbToRgb = function (h, s, v) {
-  let r, g, b, i, f, p, q, t
-
-  // h = h / 360;
-  if (v === 0) { return [0, 0, 0] }
-
-  s = s / 100
-  v = v / 100
-  h = h / 60
-
-  i = Math.floor(h)
-  f = h - i
-  p = v * (1 - s)
-  q = v * (1 - (s * f))
-  t = v * (1 - (s * (1 - f)))
-
-  if (i === 0) {
-    r = v
-    g = t
-    b = p
-  } else if (i === 1) {
-    r = q
-    g = v
-    b = p
-  } else if (i === 2) {
-    r = p
-    g = v
-    b = t
-  } else if (i === 3) {
-    r = p
-    g = q
-    b = v
-  } else if (i === 4) {
-    r = t
-    g = p
-    b = v
-  } else if (i === 5) {
-    r = v
-    g = p
-    b = q
-  }
-
-  r = Math.floor(r * 255)
-  g = Math.floor(g * 255)
-  b = Math.floor(b * 255)
-
-  return [r, g, b]
-}
-
-export const hsvToRgb = hsbToRgb // alias
-
-/* Convert from Hsv */
-export const hsbToHsl = function (h, s, b) {
-  return rgbToHsl(hsbToRgb(h, s, b))
-}
-
-export const hsvToHsl = hsbToHsl // alias
-
-/*
- ==================================
- Color Scheme Builder
- ==================================
-*/
-export class ColorScheme {
-  constructor (colorVal, angleArray) {
-    this.palette = []
-
-    if (angleArray === undefined && colorVal instanceof Array) {
-      // Asume you passing a color array ['#f00','#0f0'...]
-      this.createFromColors(colorVal)
-    } else {
-      // Create scheme from color + hue angles
-      this.createFromAngles(colorVal, angleArray)
-    }
-  }
-
-  createFromColors (colorVal) {
-    for (let i in colorVal) {
-      if (colorVal.hasOwn(i)) {
-        this.palette.push(new Color(colorVal[i]))
-      }
-    }
-    return this.palette
-  }
-
-  createFromAngles (colorVal, angleArray) {
-    this.palette.push(new Color(colorVal))
-
-    for (let i in angleArray) {
-      if (angleArray.hasOwn(i)) {
-        const tempHue = (this.palette[0].h + angleArray[i]) % 360
-        this.palette.push(new Color(hslToRgb(tempHue, this.palette[0].s, this.palette[0].l)))
-      }
-    }
-    return this.palette
-  }
-
-  /* Complementary colors constructors */
-  static Compl (colorVal) {
-    return new this(colorVal, [180])
-  }
-
-  /* Triad */
-  static Triad (colorVal) {
-    return new this(colorVal, [120, 240])
-  }
-
-  /* Tetrad */
-  static Tetrad (colorVal) {
-    return new this(colorVal, [60, 180, 240])
-  }
-
-  /* Analogous */
-  static Analog (colorVal) {
-    return new this(colorVal, [-45, 45])
-  }
-
-  /* Split complementary */
-  static Split (colorVal) {
-    return new this(colorVal, [150, 210])
-  }
-
-  /* Accented Analogous */
-  static Accent (colorVal) {
-    return new this(colorVal, [-45, 45, 180])
-  }
-}

+ 0 - 42
src/components/view_file/vendors/image/ImageViewer.vue

@@ -1,42 +0,0 @@
-<!--
- * @Author: LiZhiWei
- * @Date: 2025-04-09 08:10:23
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 16:16:22
- * @Description:
--->
-<template>
-  <div>
-    <!-- <img v-for="item in images" alt="图片" :src="item.src" :key="item.index" class="image" /> -->
-    <el-image
-      :src="images[0]"
-      :preview-src-list="images"
-      width="100%"
-      height="100%"
-      :preview="true"
-    />
-  </div>
-</template>
-
-<script>
-export default {
-  name: "ImageViewer",
-  props: {
-    image: String,
-  },
-  computed: {
-    images() {
-      return this.image ? [this.image] : []
-    },
-  },
-}
-</script>
-
-<style scoped>
-.image {
-  display: block;
-  width: auto;
-  height: 100%;
-  margin: 0 auto;
-}
-</style>

+ 0 - 13
src/components/view_file/vendors/image/index.js

@@ -1,13 +0,0 @@
-import Vue from 'vue'
-import ImageViewer from './ImageViewer'
-import { readDataURL } from '../../util'
-
-/**
- * 图片渲染
- */
-export default async function renderImage (buffer, target) {
-  const url = await readDataURL(buffer)
-  return new Vue({
-    render: h => h(ImageViewer, { props: { image: url } })
-  }).$mount(target)
-}

+ 0 - 63
src/components/view_file/vendors/other/index.vue

@@ -1,63 +0,0 @@
-<!--
- * @Author: ChenYaJin
- * @Date: 2021-06-16 14:46:07
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 15:32:26
- * @Description: 文件柜-预览其他
--->
-<template>
-  <div class="view-other">
-    <el-image :src="viewOffImage" class="view-off-icon">
-      <div slot="error" class="image-slot">
-        <i class="el-icon-picture-outline"></i>
-      </div>
-    </el-image>
-    <p>
-      {{ file.name }}.{{ file.type
-      }}<span class="size-item">{{ getFileSize }}</span>
-    </p>
-    <p>
-      <big><strong>该类型文件不支持在线预览,请下载后查看。</strong></big>
-    </p>
-  </div>
-</template>
-<script>
-import commJs from "@/comm_js/index"
-import viewOffImage from "../../assets/view_off.svg"
-
-export default {
-  name: "ViewOtherComponent",
-  props: {
-    file: {
-      type: Object,
-      default: () => {
-        return {}
-      },
-    },
-  },
-  data() {
-    return {
-      viewOffImage,
-    }
-  },
-  computed: {
-    getFileSize() {
-      return commJs.fileSizeFormat(this.file.size, "KB")
-    },
-  },
-  methods: {},
-  mounted() {},
-}
-</script>
-<style lang="less" scoped>
-.view-other {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  height: 100%;
-  .size-item {
-    margin-left: 10px;
-  }
-}
-</style>

+ 0 - 165
src/components/view_file/vendors/pdf/PdfView.vue

@@ -1,165 +0,0 @@
-<template>
-  <div class="home_wrap">
-    <div class="pdf_down">
-      <div class="pdf_set_left" @click="scaleD()">➕</div>
-      <div class="pdf_set_middle" @click="scaleX()">➖</div>
-      <!-- <div class="pdf-pre" @click="prePage">上一页</div> -->
-      <!-- <div class="pdf-next" @click="nextPage">下一页</div> -->
-    </div>
-    <div :style="{ width: pdf_div_width, margin: '0 auto' }">
-      <!-- <canvas id="the_canvas"></canvas> -->
-      <canvas
-        v-for="page in pdf_pages"
-        :id="'the_canvas' + page"
-        :key="page"
-      ></canvas>
-    </div>
-  </div>
-</template>
-
-<script>
-import PDFJS from 'pdfjs-dist'
-import workerSrc from 'pdfjs-dist/build/pdf.worker.entry'
-// const PDFJS = { GlobalWorkerOptions: {} }
-
-PDFJS.GlobalWorkerOptions.workerSrc = workerSrc
-
-export default {
-  name: 'PdfView',
-  props: {
-    data: ArrayBuffer
-  },
-  data () {
-    return {
-      pdf_scale: 1.0,
-      pdf_pages: [],
-      pdf_div_width: '',
-      currentPage: 1
-    }
-  },
-  mounted () {
-    this.loadFile()
-  },
-  methods: {
-    scaleD () {
-      let max = 0
-      if (window.screen.width > 1440) {
-        max = 1.4
-      } else {
-        max = 1.2
-      }
-      if (this.pdf_scale >= max) {
-        return
-      }
-      this.pdf_scale = this.pdf_scale + 0.1
-      this.loadFile()
-    },
-    scaleX () {
-      let min = 1.0
-      if (this.pdf_scale <= min) {
-        return
-      }
-      this.pdf_scale = this.pdf_scale - 0.1
-      this.loadFile()
-    },
-    async loadFile () {
-      this.pdfDoc = await PDFJS.getDocument(this.data).promise
-      this.pdf_pages = this.pdfDoc.numPages
-      this.$nextTick(() => this.renderPage())
-    },
-    async renderPage (num = 1) {
-      this.currentPage = num
-      const page = await this.pdfDoc.getPage(num)
-      const canvas = document.getElementById('the_canvas' + num)
-      // const canvas = document.getElementById("the_canvas")
-      const ctx = canvas.getContext('2d')
-      const dpr = window.devicePixelRatio || 1
-      const bsr =
-        ctx.webkitBackingStorePixelRatio ||
-        ctx.mozBackingStorePixelRatio ||
-        ctx.msBackingStorePixelRatio ||
-        ctx.oBackingStorePixelRatio ||
-        ctx.backingStorePixelRatio ||
-        1
-      const ratio = dpr / bsr
-      const viewport = page.getViewport({ scale: this.pdf_scale })
-      canvas.width = viewport.width * ratio
-      canvas.height = viewport.height * ratio
-      canvas.style.width = viewport.width + 'px'
-      this.pdf_div_width = viewport.width + 'px'
-      canvas.style.height = viewport.height + 'px'
-      ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
-      const renderContext = {
-        canvasContext: ctx,
-        viewport: viewport
-      }
-      page.render(renderContext)
-      if (this.pdf_pages > num) {
-        setTimeout(() => {
-          return this.renderPage(num + 1)
-        })
-      }
-    },
-    nextPage () {
-      if (this.pdf_pages > this.currentPage) {
-        this.renderPage(this.currentPage + 1)
-      }
-    },
-    prePage () {
-      if (this.currentPage > 1) {
-        this.renderPage(this.currentPage - 1)
-      }
-    }
-  }
-}
-</script>
-
-<style scoped>
-.home_wrap {
-  width: 100%;
-  height: 100%;
-}
-.home_wrap .pdf_down {
-  position: fixed;
-  display: flex;
-  z-index: 20;
-  right: 26px;
-  bottom: 7%;
-  cursor: pointer;
-}
-.home_wrap .pdf-pre {
-  position: fixed;
-  display: flex;
-  z-index: 20;
-  right: 160px;
-  bottom: 9%;
-  cursor: pointer;
-}
-.home_wrap .pdf-next {
-  position: fixed;
-  display: flex;
-  z-index: 20;
-  right: 100px;
-  bottom: 9%;
-}
-.home_wrap .pdf_down .pdf_set_left {
-  width: 30px;
-  height: 40px;
-  color: #408fff;
-  font-size: 15px;
-  padding-top: 25px;
-  text-align: center;
-  margin-right: 5px;
-  cursor: pointer;
-}
-.home_wrap .pdf_down .pdf_set_middle {
-  width: 30px;
-  height: 40px;
-  color: #408fff;
-  font-size: 15px;
-  padding-top: 25px;
-  text-align: center;
-  margin-right: 5px;
-  cursor: pointer;
-}
-</style>

+ 0 - 8
src/components/view_file/vendors/pdf/index.js

@@ -1,8 +0,0 @@
-import Vue from 'vue'
-import PdfView from './PdfView'
-
-export default async function renderPdf (buffer, target) {
-  return new Vue({
-    render: h => h(PdfView, { props: { data: buffer } })
-  }).$mount(target)
-}

+ 0 - 5051
src/components/view_file/vendors/pptx/PPT.vue

@@ -1,5051 +0,0 @@
-<!--
- * @Author: LiZhiWei
- * @Date: 2025-04-10 14:38:27
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 17:48:31
- * @Description:
--->
-<template>
-  <div id="pptx-container" ref="pptxContainer" class="pptx-container"></div>
-</template>
-<script>
-export default {
-  name: "PPT",
-  props: {
-    pptxJson: Object,
-  },
-  data() {
-    return {}
-  },
-  mounted() {
-    this.renderSlides()
-  },
-  computed: {},
-  watch: {
-    pptxJson: {
-      handler() {
-        this.renderSlides()
-      },
-      deep: true,
-    },
-  },
-  methods: {
-    renderSlides() {
-      if (!this.$refs.pptxContainer || !this.pptxJson) return
-
-      this.$refs.pptxContainer.innerHTML = ""
-      const { size, slides } = this.pptxJson
-
-      slides.forEach((slide, index) => {
-        const slideElement = this.createSlideElement(size.width, size.height)
-        this.applySlideBackground(slideElement, slide.fill)
-        if (slide.layoutElements && Array.isArray(slide.layoutElements)) {
-          this.processElements(slide.layoutElements, index + 1)
-          slide.layoutElements.forEach((element) => {
-            const el = this.createElementByType(element)
-            if (!el) return
-            slideElement.appendChild(el)
-          })
-        }
-
-        // 渲染幻灯片元素
-        if (slide.elements && Array.isArray(slide.elements)) {
-          this.processElements(slide.elements, index + 1)
-          slide.elements.forEach((element) => {
-            const el = this.createElementByType(element)
-            if (!el) return
-            slideElement.appendChild(el)
-          })
-        }
-
-        // 添加幻灯片到容器
-        this.$refs.pptxContainer.appendChild(slideElement)
-      })
-      // 为所有p标签应用样式
-      const pTags = this.$refs.pptxContainer.querySelectorAll("p")
-      pTags.forEach((p) => {
-        p.style.margin = "0px"
-        p.style.padding = "0px"
-        p.style.wordBreak = "break-word"
-        p.style.lineHeight = "1"
-      })
-      const ulTags = this.$refs.pptxContainer.querySelectorAll("ul")
-      ulTags.forEach((ul) => {
-        ul.style.wordBreak = "break-word"
-        ul.style.lineHeight = "1"
-        ul.style.padding = "auto 0px"
-        ul.style.margin = "0px"
-      })
-      const olTags = this.$refs.pptxContainer.querySelectorAll("ol")
-      olTags.forEach((ol) => {
-        ol.style.margin = "0px"
-        ol.style.padding = "auto 0px"
-        ol.style.wordBreak = "break-word"
-        ol.style.lineHeight = "1"
-      })
-    },
-    // 创建幻灯片元素
-    createSlideElement(width, height) {
-      const slideElement = document.createElement("div")
-      slideElement.className = "slide"
-      slideElement.style.position = "relative"
-      slideElement.style.width = width + "px"
-      slideElement.style.height = height + "px"
-      slideElement.style.border = "1px solid #ccc"
-      slideElement.style.margin = "0px auto"
-      slideElement.style.marginBottom = "20px"
-      slideElement.style.overflow = "hidden"
-      return slideElement
-    },
-
-    // 应用幻灯片背景
-    applySlideBackground(slideElement, fill) {
-      if (!fill) return
-
-      if (fill.type === "gradient") {
-        const { colors, path, rot } = fill.value
-
-        if (colors && colors.length >= 2) {
-          const gradientType = path === "rect" ? "linear" : "radial"
-          const gradientAngle =
-            gradientType === "linear" ? (90 - (rot || 0)) % 360 : rot || 0
-
-          let gradientString = `${gradientType}-gradient(`
-          if (gradientType === "linear") {
-            gradientString += `${gradientAngle}deg, `
-          }
-
-          colors.forEach((color, i) => {
-            gradientString += `${color.color} ${color.pos}${
-              i < colors.length - 1 ? ", " : ""
-            }`
-          })
-
-          gradientString += ")"
-          slideElement.style.background = gradientString
-        }
-      } else if (fill.type === "color") {
-        slideElement.style.backgroundColor = fill.value || "#FFFFFF"
-      } else if (fill.type === "image" && fill.value.picBase64) {
-        // 设置背景图片
-        slideElement.style.backgroundImage = `url(${fill.value.picBase64})`
-        slideElement.style.backgroundSize = "cover"
-        slideElement.style.backgroundPosition = "center"
-        slideElement.style.backgroundRepeat = "no-repeat"
-
-        // 如果有背景图片的混合模式
-        if (fill.value.blendMode) {
-          slideElement.style.backgroundBlendMode = fill.value.blendMode
-        }
-
-        // 如果有透明度设置
-        if (fill.value.opacity !== undefined) {
-          slideElement.style.opacity = fill.value.opacity
-        }
-      }
-    },
-
-    // 根据元素类型创建DOM元素
-    createElementByType(element) {
-      switch (element.type) {
-        case "image":
-          return this.createImageElement(element)
-        case "video":
-          return this.createVideoElement(element)
-        case "audio":
-          return this.createAudioElement(element)
-        case "shape":
-          return this.createShapeElement(element)
-        case "table":
-          return this.createTableElement(element)
-        case "chart":
-          return this.createChartElement(element)
-        case "diagram":
-          return this.createDiagramElement(element)
-        case "math":
-          return this.createMathElement(element)
-        case "group":
-          return this.createGroupElement(element)
-        default:
-          return this.createTextElement(element)
-      }
-    },
-    createGroupElement(element) {
-      // 创建组合容器
-      const groupContainer = document.createElement("div")
-      groupContainer.className = "group-element"
-      groupContainer.style.position = "absolute"
-      groupContainer.style.top = element.top + "px"
-      groupContainer.style.left = element.left + "px"
-      groupContainer.style.width = element.width + "px"
-      groupContainer.style.height = element.height + "px"
-      groupContainer.style.zIndex = element.order
-      groupContainer.style.transformOrigin = "center center"
-
-      // 创建内部容器来处理子元素
-      const innerContainer = document.createElement("div")
-      innerContainer.style.position = "relative"
-      innerContainer.style.width = "100%"
-      innerContainer.style.height = "100%"
-
-      // 应用旋转变换
-      if (element.rotate) {
-        groupContainer.style.transform = `rotate(${element.rotate}deg)`
-      }
-
-      // 应用其他样式属性
-      if (element.opacity !== undefined) {
-        groupContainer.style.opacity = element.opacity
-      }
-
-      // 递归渲染组内的所有子元素
-      if (element.elements && Array.isArray(element.elements)) {
-        element.elements.forEach((childElement) => {
-          const childCopy = JSON.parse(JSON.stringify(childElement))
-          const childEl = this.createElementByType(childCopy)
-          if (childEl) {
-            innerContainer.appendChild(childEl)
-          }
-        })
-      }
-
-      groupContainer.appendChild(innerContainer)
-      return groupContainer
-    },
-    // 递归调整元素位置
-    adjustElementPosition(element, parentElement) {
-      // 创建深拷贝,但保留特殊属性的引用
-      const adjustedElement = JSON.parse(JSON.stringify(element))
-
-      // 调整位置为相对于父组合元素的位置
-      adjustedElement.top = element.top - parentElement.top
-      adjustedElement.left = element.left - parentElement.left
-
-      // 恢复特殊属性的引用
-      const specialProps = [
-        "src",
-        "blob",
-        "fill",
-        "text",
-        "path",
-        "elements",
-        "borderColor",
-        "borderWidth",
-        "borderType",
-      ]
-      specialProps.forEach((prop) => {
-        if (element[prop] !== undefined) {
-          adjustedElement[prop] = element[prop]
-        }
-      })
-
-      // 如果是组合元素,递归处理其子元素
-      if (element.type === "group" && element.elements) {
-        adjustedElement.elements = element.elements.map((childElement) =>
-          this.adjustElementPosition(childElement, {
-            top: element.top,
-            left: element.left,
-          })
-        )
-      }
-
-      return adjustedElement
-    },
-    // 创建图像元素
-    createImageElement(element) {
-      const img = document.createElement("img")
-      img.src = element.src
-      img.style.width = element.width + "px"
-      img.style.height = element.height + "px"
-      img.style.objectFit = "cover" // 保持图像的宽高比并填充容器
-      img.style.position = "absolute"
-      img.style.top = `${element.top}px`
-      img.style.left = `${element.left}px`
-      img.style.zIndex = element.order
-
-      return img
-    },
-
-    // 创建视频元素
-    createVideoElement(element) {
-      const el = document.createElement("video")
-      el.src = element.blob
-      el.controls = true
-      el.style.width = element.width + "px"
-      el.style.height = element.height + "px"
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.zIndex = element.order
-      return el
-    },
-
-    // 创建音频元素
-    createAudioElement(element) {
-      const el = document.createElement("audio")
-      el.src = element.blob
-      el.controls = true
-      el.style.height = element.height + "px"
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.zIndex = element.order
-      return el
-    },
-
-    // 创建形状元素
-    createShapeElement(element) {
-      const el = document.createElement("div")
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.width = element.width + "px"
-      el.style.height = element.height + "px"
-      el.style.zIndex = element.order
-      el.style.overflow = "visible"
-      if (element.height === 0) {
-        // 如果高度为0,直接在div上绘制边框
-        el.style.borderTop = `${element.borderWidth || 1}px ${
-          element.borderType || "solid"
-        } ${element.borderColor || "#000"}`
-      }
-      // 使用SVG绘制形状
-      const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg")
-      svg.setAttribute("width", "100%")
-      svg.setAttribute("height", "100%")
-      svg.setAttribute("viewBox", `0 0 ${element.width} ${element.height}`)
-      svg.style.overflow = "visible"
-      const setBackground = (element, shape) => {
-        if (element.fill && element.fill.type) {
-          // 设置填充色
-          if (element.fill.type === "color") {
-            shape.setAttribute("fill", element.fill.value || "transparent")
-          } else if (element.fill.type === "gradient") {
-            // 渐变填充
-            const { colors, path, rot } = element.fill.value
-
-            if (colors && colors.length >= 2) {
-              const gradientType = path === "rect" ? "linear" : "radial"
-              const gradientAngle =
-                gradientType === "linear" ? (90 - (rot || 0)) % 360 : rot || 0
-
-              let gradientString = `${gradientType}-gradient(`
-              if (gradientType === "linear") {
-                gradientString += `${gradientAngle}deg, `
-              }
-
-              colors.forEach((color, i) => {
-                gradientString += `${color.color} ${color.pos}${
-                  i < colors.length - 1 ? ", " : ""
-                }`
-              })
-              gradientString += ")"
-
-              // 创建渐变定义
-              const gradientDef = document.createElementNS(
-                "http://www.w3.org/2000/svg",
-                "defs"
-              )
-              const gradientEl = document.createElementNS(
-                "http://www.w3.org/2000/svg",
-                gradientType === "linear" ? "linearGradient" : "radialGradient"
-              )
-              const gradientId = `gradient-${Date.now()}-${Math.random()
-                .toString(36)
-                .substr(2, 9)}`
-              gradientEl.setAttribute("id", gradientId)
-
-              // 设置渐变属性
-              if (gradientType === "linear") {
-                gradientEl.setAttribute(
-                  "gradientTransform",
-                  `rotate(${gradientAngle})`
-                )
-              }
-
-              // 添加渐变色标
-              colors.forEach((color) => {
-                const stop = document.createElementNS(
-                  "http://www.w3.org/2000/svg",
-                  "stop"
-                )
-                stop.setAttribute("offset", color.pos)
-                stop.setAttribute("stop-color", color.color)
-                gradientEl.appendChild(stop)
-              })
-
-              gradientDef.appendChild(gradientEl)
-              svg.appendChild(gradientDef)
-
-              // 应用渐变
-              shape.setAttribute("fill", `url(#${gradientId})`)
-            }
-          } else if (element.fill.type === "image") {
-            // 创建图案填充
-            const pattern = document.createElementNS(
-              "http://www.w3.org/2000/svg",
-              "pattern"
-            )
-            const patternId = `pattern-${Date.now()}-${Math.random()
-              .toString(36)
-              .substr(2, 9)}`
-            pattern.setAttribute("id", patternId)
-            pattern.setAttribute("patternUnits", "userSpaceOnUse")
-            pattern.setAttribute("width", "100%")
-            pattern.setAttribute("height", "100%")
-
-            // 创建图片元素
-            const image = document.createElementNS(
-              "http://www.w3.org/2000/svg",
-              "image"
-            )
-            image.setAttribute("width", "100%")
-            image.setAttribute("height", "100%")
-            image.setAttribute("preserveAspectRatio", "xMidYMid slice")
-            image.setAttributeNS(
-              "http://www.w3.org/1999/xlink",
-              "href",
-              element.fill.value.picBase64
-            )
-
-            pattern.appendChild(image)
-
-            // 添加pattern到defs
-            const defs = document.createElementNS(
-              "http://www.w3.org/2000/svg",
-              "defs"
-            )
-            defs.appendChild(pattern)
-            svg.appendChild(defs)
-
-            // 应用图案填充
-            shape.setAttribute("fill", `url(#${patternId})`)
-          } else {
-            shape.setAttribute("fill", "transparent")
-          }
-        } else {
-          shape.setAttribute("fill", "#ffffff00")
-        }
-      }
-      // 根据形状类型创建不同的SVG元素
-      switch (element.shapType) {
-        case "roundRect":
-          const radius = Math.min(element.width, element.height) * 0.1
-          const roundRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "rect"
-          )
-          roundRect.setAttribute("x", 0)
-          roundRect.setAttribute("y", 0)
-          roundRect.setAttribute("width", element.width)
-          roundRect.setAttribute("height", element.height)
-          roundRect.setAttribute("rx", radius)
-          roundRect.setAttribute("ry", radius)
-
-          // 设置填充色
-          setBackground(element, roundRect)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            roundRect.setAttribute("stroke", element.borderColor || "#000")
-            roundRect.setAttribute("stroke-width", element.borderWidth || 1)
-            roundRect.setAttribute("stroke-linejoin", "round") // 设置连接处为圆角
-            roundRect.setAttribute("vector-effect", "non-scaling-stroke") // 防止边框宽度变形
-            roundRect.setAttribute("shape-rendering", "geometricPrecision") // 提高渲染精度
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                roundRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                roundRect.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                roundRect.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(roundRect)
-          break
-        case "snip1Rect":
-          // 使用path元素绘制剪去单角的矩形
-          const snip1Rect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算剪角的大小,通常为矩形较短边的20%
-          const snipSize = Math.min(element.width, element.height) * 0.35
-
-          // 绘制路径:从左上角开始,顺时针方向,右上角被剪去
-          snip1Rect.setAttribute(
-            "d",
-            `M0,0 ` +
-              `L${element.width - snipSize},0 ` +
-              `L${element.width},${snipSize} ` +
-              `L${element.width},${element.height} ` +
-              `L0,${element.height} ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, snip1Rect)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            snip1Rect.setAttribute("stroke", element.borderColor || "#000")
-            snip1Rect.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                snip1Rect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                snip1Rect.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                snip1Rect.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-          svg.appendChild(snip1Rect)
-          break
-        case "snip2SameRect":
-          // 使用path元素绘制剪去四个角的矩形
-          const snip2SameRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算剪角的大小,通常为矩形较短边的20%
-          const snip2Size = Math.min(element.width, element.height) * 0.35
-
-          // 绘制路径:从左上角开始,顺时针方向,剪去四个角
-          snip2SameRect.setAttribute(
-            "d",
-            `M${snip2Size},0 ` +
-              `L${element.width - snip2Size},0 ` +
-              `L${element.width},${snip2Size} ` +
-              `L${element.width},${element.height - snip2Size} ` +
-              `L${element.width - snip2Size},${element.height} ` +
-              `L${snip2Size},${element.height} ` +
-              `L0,${element.height - snip2Size} ` +
-              `L0,${snip2Size} ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, snip2SameRect)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            snip2SameRect.setAttribute("stroke", element.borderColor || "#000")
-            snip2SameRect.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                snip2SameRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                snip2SameRect.setAttribute("stroke-dasharray", "2, 2")
-                snip2SameRect.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                snip2SameRect.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            // 添加这些属性以确保边框正确渲染
-            snip2SameRect.setAttribute("vector-effect", "non-scaling-stroke")
-            snip2SameRect.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(snip2SameRect)
-          break
-        case "line":
-          // 创建直线连接符
-          const line = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "line"
-          )
-          // 设置SVG的最小高度为1px
-          const svgHeight = element.height > 0 ? element.height : 1
-          svg.setAttribute("height", svgHeight + "px")
-
-          // 设置线条的起点和终点
-          line.setAttribute("x1", 0)
-          line.setAttribute("y1", 0)
-          line.setAttribute("x2", element.width)
-          line.setAttribute("y2", svgHeight)
-
-          // 确保边框颜色和宽度被正确设置
-          line.setAttribute("stroke", element.borderColor || "#000")
-          line.setAttribute("stroke-width", element.borderWidth || 1)
-
-          // 处理虚线样式
-          if (
-            element.borderType === "dotted" ||
-            element.borderType === "dashed"
-          ) {
-            if (element.borderStrokeDasharray) {
-              line.setAttribute(
-                "stroke-dasharray",
-                element.borderStrokeDasharray
-              )
-            } else if (element.borderType === "dotted") {
-              line.setAttribute("stroke-dasharray", "2, 2")
-              line.setAttribute("stroke-linecap", "round") // 添加圆角端点使点线更明显
-            } else if (element.borderType === "dashed") {
-              line.setAttribute("stroke-dasharray", "6, 3")
-            }
-          }
-
-          // 确保线条正确渲染
-          line.setAttribute("vector-effect", "non-scaling-stroke") // 防止缩放影响线条宽度
-          svg.appendChild(line)
-          break
-        case "snip2DiagRect":
-          // 使用path元素绘制剪去右上角和左下角的矩形
-          const snip2DiagRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算剪角的大小,通常为矩形较短边的35%
-          const snipDiagSize = Math.min(element.width, element.height) * 0.35
-
-          // 绘制路径:从左上角开始,顺时针方向,右上角和左下角被剪去
-          snip2DiagRect.setAttribute(
-            "d",
-            `M0,0 ` +
-              `L${element.width - snipDiagSize},0 ` +
-              `L${element.width},${snipDiagSize} ` +
-              `L${element.width},${element.height} ` +
-              `L${snipDiagSize},${element.height} ` +
-              `L0,${element.height - snipDiagSize} ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, snip2DiagRect)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            snip2DiagRect.setAttribute("stroke", element.borderColor || "#000")
-            snip2DiagRect.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                snip2DiagRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                snip2DiagRect.setAttribute("stroke-dasharray", "2, 2")
-                snip2DiagRect.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                snip2DiagRect.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            // 添加这些属性以确保边框正确渲染
-            snip2DiagRect.setAttribute("vector-effect", "non-scaling-stroke")
-            snip2DiagRect.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(snip2DiagRect)
-          break
-        case "snipRoundRect":
-          const snipRoundRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          // 计算剪切大小和圆角大小
-          const snipSize2 = Math.min(element.width, element.height) * 0.4
-          const roundSize = Math.min(element.width, element.height) * 0.5
-
-          // 绘制路径:从左上角开始,顺时针方向,左上为圆角,右上为剪切角
-          snipRoundRect.setAttribute(
-            "d",
-            `M${roundSize},0 ` +
-              `L${element.width - snipSize2},0 ` +
-              `L${element.width},${snipSize2} ` +
-              `L${element.width},${element.height} ` +
-              `L0,${element.height} ` +
-              `L0,${roundSize} ` +
-              `A${roundSize},${roundSize} 0 0,1 ${roundSize},0 ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, snipRoundRect)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            snipRoundRect.setAttribute("stroke", element.borderColor || "#000")
-            snipRoundRect.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                snipRoundRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                snipRoundRect.setAttribute("stroke-dasharray", "2, 2")
-                snipRoundRect.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                snipRoundRect.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            snipRoundRect.setAttribute("vector-effect", "non-scaling-stroke")
-            snipRoundRect.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(snipRoundRect)
-          break
-        case "round1Rect":
-          const round1Rect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          // 计算圆角大小
-          const round1Size = Math.min(element.width, element.height) * 0.5
-
-          // 绘制路径:从左上角开始,顺时针方向,右上角为圆角
-          round1Rect.setAttribute(
-            "d",
-            `M0,0 ` +
-              `L${element.width - round1Size},0 ` +
-              `Q${element.width},0 ${element.width},${round1Size} ` +
-              `L${element.width},${element.height} ` +
-              `L0,${element.height} ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, round1Rect)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            round1Rect.setAttribute("stroke", element.borderColor || "#000")
-            round1Rect.setAttribute("stroke-width", element.borderWidth || 1)
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                round1Rect.setAttribute("stroke-dasharray", "40,15,5,15")
-              } else if (element.borderType === "dotted") {
-                round1Rect.setAttribute("stroke-dasharray", "2, 2")
-                round1Rect.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                round1Rect.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            round1Rect.setAttribute("vector-effect", "non-scaling-stroke")
-            round1Rect.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(round1Rect)
-          break
-        case "ellipse":
-        case "circle":
-          const ellipse = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "ellipse"
-          )
-          ellipse.setAttribute("cx", element.width / 2)
-          ellipse.setAttribute("cy", element.height / 2)
-          ellipse.setAttribute("rx", element.width / 2)
-          ellipse.setAttribute("ry", element.height / 2)
-
-          // 设置填充色
-          setBackground(element, ellipse)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            ellipse.setAttribute("stroke", element.borderColor || "#000")
-            ellipse.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                ellipse.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                ellipse.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                ellipse.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(ellipse)
-          break
-        case "round2SameRect":
-          const round2SameRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          // 计算圆角大小
-          const round2Size = Math.min(element.width, element.height) * 0.5
-
-          // 绘制路径:从左上角开始,顺时针方向,左上和右上为圆角
-          round2SameRect.setAttribute(
-            "d",
-            `M${round2Size},0 ` +
-              `L${element.width - round2Size},0 ` +
-              `Q${element.width},0 ${element.width},${round2Size} ` +
-              `L${element.width},${element.height} ` +
-              `L0,${element.height} ` +
-              `L0,${round2Size} ` +
-              `Q0,0 ${round2Size},0 ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, round2SameRect)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            round2SameRect.setAttribute("stroke", element.borderColor || "#000")
-            round2SameRect.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                round2SameRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                round2SameRect.setAttribute("stroke-dasharray", "2, 2")
-                round2SameRect.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                round2SameRect.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            round2SameRect.setAttribute("vector-effect", "non-scaling-stroke")
-            round2SameRect.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(round2SameRect)
-          break
-        case "round2DiagRect":
-          const round2DiagRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          // 计算圆角大小
-          const round2DiagSize = Math.min(element.width, element.height) * 0.5
-
-          // 绘制路径:从左上角开始,顺时针方向,左上和右下为圆角
-          round2DiagRect.setAttribute(
-            "d",
-            `M${round2DiagSize},0 ` +
-              `L${element.width},0 ` +
-              `L${element.width},${element.height - round2DiagSize} ` +
-              `Q${element.width},${element.height} ${
-                element.width - round2DiagSize
-              },${element.height} ` +
-              `L0,${element.height} ` +
-              `L0,${round2DiagSize} ` +
-              `Q0,0 ${round2DiagSize},0 ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, round2DiagRect)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            round2DiagRect.setAttribute("stroke", element.borderColor || "#000")
-            round2DiagRect.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                round2DiagRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                round2DiagRect.setAttribute("stroke-dasharray", "2, 2")
-                round2DiagRect.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                round2DiagRect.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            round2DiagRect.setAttribute("vector-effect", "non-scaling-stroke")
-            round2DiagRect.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(round2DiagRect)
-          break
-        case "triangle":
-          const triangle = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          triangle.setAttribute(
-            "points",
-            `${element.width / 2},0 ${element.width},${element.height} 0,${
-              element.height
-            }`
-          )
-
-          // 设置填充色
-          setBackground(element, triangle)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            triangle.setAttribute("stroke", element.borderColor || "#000")
-            triangle.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                triangle.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                triangle.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                triangle.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(triangle)
-          break
-        case "arc":
-          const arc = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算弧形的参数
-          const arcRadius = Math.min(element.width, element.height) / 2
-
-          // 绘制弧形路径
-          arc.setAttribute(
-            "d",
-            `M${arcRadius},0 ` +
-              `A${arcRadius},${arcRadius} 0 1 1 ${arcRadius * 0.15},${
-                arcRadius * 0.5
-              }`
-          )
-
-          // 设置填充色
-          arc.setAttribute("fill", "transparent")
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            arc.setAttribute("stroke", element.borderColor || "#000")
-            arc.setAttribute("stroke-width", element.borderWidth || 0.5)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                arc.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                arc.setAttribute("stroke-dasharray", "2, 2")
-                arc.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                arc.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            arc.setAttribute("vector-effect", "non-scaling-stroke")
-            arc.setAttribute("shape-rendering", "geometricPrecision")
-          } else {
-            arc.setAttribute("stroke", element.borderColor || "#000")
-            arc.setAttribute("stroke-width", 0.5)
-          }
-
-          svg.appendChild(arc)
-          break
-        case "custom":
-          const customPath = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 直接使用传入的 path 数据
-          customPath.setAttribute("d", element.path || "")
-
-          // 设置填充色
-          setBackground(element, customPath)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            customPath.setAttribute("stroke", element.borderColor || "#000")
-            customPath.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                customPath.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                customPath.setAttribute("stroke-dasharray", "2, 2")
-                customPath.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                customPath.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            customPath.setAttribute("vector-effect", "non-scaling-stroke")
-            customPath.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(customPath)
-          break
-        case "teardrop":
-          const teardrop = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算泪珠形状的参数
-          const tdCenterX = element.width / 2
-          const tdCenterY = element.height / 2
-          const tdRadiusX = element.width / 2
-          const tdRadiusY = element.height / 2
-
-          // 使用相对比例计算控制点
-          teardrop.setAttribute(
-            "d",
-            `M${tdCenterX * 2} ${tdCenterY} ` +
-              `A ${tdRadiusX} ${tdRadiusY} 0 1 1 ${tdCenterX} 0 ` +
-              `Q${tdCenterX * 1.7},0 ${tdCenterX * 2.1},${-tdCenterY * 0.1} ` +
-              `Q${tdCenterX * 2},${tdCenterY * 0.29} ${
-                tdCenterX * 2
-              },${tdCenterY}`
-          )
-
-          // 设置填充色
-          setBackground(element, teardrop)
-
-          // 设置边框样式
-          if (element.borderWidth > 0) {
-            teardrop.setAttribute("stroke", element.borderColor || "#000")
-            teardrop.setAttribute("stroke-width", element.borderWidth || 1)
-            teardrop.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              // ... 原有的虚线边框处理代码 ...
-            }
-          }
-
-          svg.appendChild(teardrop)
-          break
-        case "decagon":
-          const decagon = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-
-          // 计算十边形的顶点
-          let decagonPoints = ""
-          for (let i = 0; i < 10; i++) {
-            const angle = (i * 2 * Math.PI) / 10 - Math.PI / 2 // 从顶部开始
-            const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
-            const y =
-              element.height / 2 + (element.height / 2) * Math.sin(angle)
-            decagonPoints += `${x},${y} `
-          }
-          decagon.setAttribute("points", decagonPoints.trim())
-
-          // 设置填充色
-          setBackground(element, decagon)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            decagon.setAttribute("stroke", element.borderColor || "#000")
-            decagon.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                decagon.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                decagon.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                decagon.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(decagon)
-          break
-        case "pentagon":
-          const pentagon = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          pentagon.setAttribute(
-            "points",
-            `${element.width / 2},0 ${element.width},${
-              element.height * 0.38
-            } ` +
-              `${element.width * 0.82},${element.height} ${
-                element.width * 0.18
-              },${element.height} ` +
-              `0,${element.height * 0.38}`
-          )
-
-          // 设置填充色
-          setBackground(element, pentagon)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            pentagon.setAttribute("stroke", element.borderColor || "#000")
-            pentagon.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                pentagon.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                pentagon.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                pentagon.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(pentagon)
-          break
-        case "pie":
-          const pie = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 使用提供的路径数据,但保留元素的宽高比例
-          const centerX = element.width / 2
-          const centerY = element.height / 2
-          const radius2 = Math.min(element.width, element.height) / 2
-
-          // 绘制饼图,使用类似提供的路径数据
-          pie.setAttribute(
-            "d",
-            `M${centerX},${centerY} ` +
-              `L${centerX * 1.85},${centerY * 1.52} ` +
-              `A${radius2},${radius2} 0 1,1 ${centerX * 1.56},${
-                centerY * 0.17
-              } ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, pie)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            pie.setAttribute("stroke", element.borderColor || "#000")
-            pie.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                pie.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                pie.setAttribute("stroke-dasharray", "2, 2")
-                pie.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                pie.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            pie.setAttribute("vector-effect", "non-scaling-stroke")
-            pie.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(pie)
-          break
-        case "chord":
-          const chord = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算弦形的参数
-          const chordRadiusX = element.width * 0.4
-          const chordRadiusY = element.height * 0.4
-          // 绘制弦形 - 使用更大的圆弧和不同的起始/结束点
-          chord.setAttribute(
-            "d",
-            `M${element.width * 0.4},${element.height * 0.9} ` +
-              `A ${chordRadiusX} ${chordRadiusY} 0 1 1 ${element.width * 0.8},${
-                element.height * 0.5
-              } ` +
-              `Z`
-          )
-
-          // 设置填充色
-          setBackground(element, chord)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            chord.setAttribute("stroke", element.borderColor || "#000")
-            chord.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                chord.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                chord.setAttribute("stroke-dasharray", "2, 2")
-                chord.setAttribute("stroke-linecap", "round")
-              } else if (element.borderType === "dashed") {
-                chord.setAttribute("stroke-dasharray", "6, 3")
-              }
-            }
-
-            chord.setAttribute("vector-effect", "non-scaling-stroke")
-            chord.setAttribute("shape-rendering", "geometricPrecision")
-          }
-
-          svg.appendChild(chord)
-          break
-        case "heptagon":
-          const heptagon = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-
-          // 计算七边形的顶点
-          let heptagonPoints = ""
-          for (let i = 0; i < 7; i++) {
-            const angle = (i * 2 * Math.PI) / 7 - Math.PI / 2 // 从顶部开始
-            const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
-            const y =
-              element.height / 2 + (element.height / 2) * Math.sin(angle)
-            heptagonPoints += `${x},${y} `
-          }
-          heptagon.setAttribute("points", heptagonPoints.trim())
-
-          // 设置填充色
-          setBackground(element, heptagon)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            heptagon.setAttribute("stroke", element.borderColor || "#000")
-            heptagon.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                heptagon.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                heptagon.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                heptagon.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(heptagon)
-          break
-        case "hexagon":
-          const hexagon = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          hexagon.setAttribute(
-            "points",
-            `${element.width * 0.25},0 ${element.width * 0.75},0 ${
-              element.width
-            },${element.height * 0.5} ` +
-              `${element.width * 0.75},${element.height} ${
-                element.width * 0.25
-              },${element.height} 0,${element.height * 0.5}`
-          )
-
-          // 设置填充色
-          setBackground(element, hexagon)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            hexagon.setAttribute("stroke", element.borderColor || "#000")
-            hexagon.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                hexagon.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                hexagon.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                hexagon.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(hexagon)
-          break
-
-        case "octagon":
-          const octagon = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          octagon.setAttribute(
-            "points",
-            `${element.width * 0.3},0 ${element.width * 0.7},0 ${
-              element.width
-            },${element.height * 0.3} ` +
-              `${element.width},${element.height * 0.7} ${
-                element.width * 0.7
-              },${element.height} ` +
-              `${element.width * 0.3},${element.height} 0,${
-                element.height * 0.7
-              } 0,${element.height * 0.3}`
-          )
-
-          // 设置填充色
-          setBackground(element, octagon)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            octagon.setAttribute("stroke", element.borderColor || "#000")
-            octagon.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                octagon.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                octagon.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                octagon.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(octagon)
-          break
-
-        case "trapezoid":
-          const trapezoid = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          trapezoid.setAttribute(
-            "points",
-            `${element.width * 0.2},0 ${element.width * 0.8},0 ${
-              element.width
-            },${element.height} 0,${element.height}`
-          )
-
-          // 设置填充色
-          setBackground(element, trapezoid)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            trapezoid.setAttribute("stroke", element.borderColor || "#000")
-            trapezoid.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                trapezoid.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                trapezoid.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                trapezoid.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(trapezoid)
-          break
-
-        case "diamond":
-          const diamond = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          diamond.setAttribute(
-            "points",
-            `${element.width / 2},0 ${element.width},${element.height / 2} ${
-              element.width / 2
-            },${element.height} 0,${element.height / 2}`
-          )
-
-          // 设置填充色
-          setBackground(element, diamond)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            diamond.setAttribute("stroke", element.borderColor || "#000")
-            diamond.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                diamond.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                diamond.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                diamond.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(diamond)
-          break
-        case "dodecagon":
-          const dodecagon = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-
-          // 计算十二边形的顶点
-          let dodecagonPoints = ""
-          for (let i = 0; i < 12; i++) {
-            const angle = (i * 2 * Math.PI) / 12 - Math.PI / 2 // 从顶部开始
-            const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
-            const y =
-              element.height / 2 + (element.height / 2) * Math.sin(angle)
-            dodecagonPoints += `${x},${y} `
-          }
-          dodecagon.setAttribute("points", dodecagonPoints.trim())
-
-          // 设置填充色
-          setBackground(element, dodecagon)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            dodecagon.setAttribute("stroke", element.borderColor || "#000")
-            dodecagon.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                dodecagon.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                dodecagon.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                dodecagon.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(dodecagon)
-          break
-        case "halfFrame":
-          // 创建外框和内框
-          const outerRect2 = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          const innerRect2 = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算内框的边距
-          const frameWidth2 = element.width / 9
-
-          // 绘制外框的左边和上边
-          outerRect2.setAttribute(
-            "d",
-            `M0,${element.height} L0,0 L${element.width},0`
-          )
-
-          // 绘制内框的左边和上边,注意起点位置调整
-          innerRect2.setAttribute(
-            "d",
-            `M${frameWidth2},${element.height - frameWidth2} ` +
-              `L${frameWidth2},${frameWidth2} ` +
-              `L${element.width - frameWidth2},${frameWidth2}`
-          )
-
-          // 设置填充色
-          if (element.fill && element.fill.type === "color") {
-            // 创建一个填充用的路径
-            const fillPath = document.createElementNS(
-              "http://www.w3.org/2000/svg",
-              "path"
-            )
-            fillPath.setAttribute(
-              "d",
-              `M${frameWidth2},${frameWidth2} ` +
-                `L${element.width - frameWidth2},${frameWidth2} ` +
-                `L${element.width},0 ` +
-                `L0,0 ` +
-                `L0,${element.height} ` +
-                `L${frameWidth2},${element.height - frameWidth2} Z`
-            )
-            fillPath.setAttribute("fill", element.fill.value || "transparent")
-            svg.appendChild(fillPath)
-
-            outerRect2.setAttribute("fill", "none")
-            innerRect2.setAttribute("fill", "none")
-          } else {
-            outerRect2.setAttribute("fill", "none")
-            innerRect2.setAttribute("fill", "none")
-          }
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            const borderColor = element.borderColor || "#000"
-            const borderWidth = element.borderWidth || 1
-
-            outerRect2.setAttribute("stroke", borderColor)
-            outerRect2.setAttribute("stroke-width", borderWidth)
-            innerRect2.setAttribute("stroke", borderColor)
-            innerRect2.setAttribute("stroke-width", borderWidth)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                const dashArray = element.borderStrokeDasharray
-                outerRect2.setAttribute("stroke-dasharray", dashArray)
-                innerRect2.setAttribute("stroke-dasharray", dashArray)
-              } else if (element.borderType === "dotted") {
-                outerRect2.setAttribute("stroke-dasharray", "1, 3")
-                innerRect2.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                outerRect2.setAttribute("stroke-dasharray", "5, 5")
-                innerRect2.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(outerRect2)
-          svg.appendChild(innerRect2)
-          break
-        case "corner":
-          const corner = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          corner.setAttribute(
-            "d",
-            `M0,0 ` +
-              `L0,${element.height} ` +
-              `L${element.width},${element.height} ` +
-              `L${element.width},${element.height * 0.6} ` +
-              `L${element.width * 0.4},${element.height * 0.6} ` +
-              `L${element.width * 0.4},0 Z`
-          )
-
-          // 设置填充色
-          setBackground(element, corner)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            corner.setAttribute("stroke", element.borderColor || "#000")
-            corner.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                corner.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                corner.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                corner.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(corner)
-          break
-        case "diagStripe":
-          const diagStripe = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 绘制斜纹路径
-          diagStripe.setAttribute(
-            "d",
-            `M${element.width * 0.4},0 ` +
-              `L${element.width},0 ` +
-              `L0,${element.height} ` +
-              `L0,${element.height * 0.4} Z`
-          )
-
-          // 设置填充色
-          setBackground(element, diagStripe)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            diagStripe.setAttribute("stroke", element.borderColor || "#000")
-            diagStripe.setAttribute("stroke-width", element.borderWidth || 1)
-            diagStripe.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                diagStripe.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                diagStripe.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                diagStripe.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(diagStripe)
-          break
-        case "plus":
-          const plus = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          plus.setAttribute(
-            "points",
-            `${element.width * 0.4},0 ` +
-              `${element.width * 0.6},0 ` +
-              `${element.width * 0.6},${element.height * 0.4} ` +
-              `${element.width},${element.height * 0.4} ` +
-              `${element.width},${element.height * 0.6} ` +
-              `${element.width * 0.6},${element.height * 0.6} ` +
-              `${element.width * 0.6},${element.height} ` +
-              `${element.width * 0.4},${element.height} ` +
-              `${element.width * 0.4},${element.height * 0.6} ` +
-              `0,${element.height * 0.6} ` +
-              `0,${element.height * 0.4} ` +
-              `${element.width * 0.4},${element.height * 0.4}`
-          )
-
-          // 设置填充色
-          setBackground(element, plus)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            plus.setAttribute("stroke", element.borderColor || "#000")
-            plus.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                plus.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                plus.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                plus.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(plus)
-          break
-        case "can":
-          const can = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "g"
-          )
-
-          // 创建圆柱体的主体部分
-          const cylinderBody = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          cylinderBody.setAttribute(
-            "d",
-            `M0,${element.height * 0.15} ` +
-              `A${element.width / 2},${element.height * 0.15} 0 0 1 ${
-                element.width
-              },${element.height * 0.15} ` +
-              `V${element.height * 0.85} ` +
-              `A${element.width / 2},${element.height * 0.15} 0 0 1 0,${
-                element.height * 0.85
-              } Z`
-          )
-
-          // 创建顶部椭圆
-          const topEllipse = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "ellipse"
-          )
-          topEllipse.setAttribute("cx", element.width / 2)
-          topEllipse.setAttribute("cy", element.height * 0.15)
-          topEllipse.setAttribute("rx", element.width / 2)
-          topEllipse.setAttribute("ry", element.height * 0.15)
-
-          // 设置填充色
-          setBackground(element, cylinderBody)
-          setBackground(element, topEllipse)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            const borderColor = element.borderColor || "#000"
-            const borderWidth = element.borderWidth || 1
-
-            cylinderBody.setAttribute("stroke", borderColor)
-            cylinderBody.setAttribute("stroke-width", borderWidth)
-            topEllipse.setAttribute("stroke", borderColor)
-            topEllipse.setAttribute("stroke-width", borderWidth)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                const dashArray = element.borderStrokeDasharray
-                cylinderBody.setAttribute("stroke-dasharray", dashArray)
-                topEllipse.setAttribute("stroke-dasharray", dashArray)
-              } else if (element.borderType === "dotted") {
-                cylinderBody.setAttribute("stroke-dasharray", "1, 3")
-                topEllipse.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                cylinderBody.setAttribute("stroke-dasharray", "5, 5")
-                topEllipse.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          can.appendChild(cylinderBody)
-          can.appendChild(topEllipse)
-          svg.appendChild(can)
-          break
-        case "cube":
-          const cube = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "g"
-          )
-
-          // 计算关键点坐标
-          const offset = element.width * 0.2
-          const frontX = offset
-          const frontY = offset
-          const frontW = element.width - offset
-          const frontH = element.height
-
-          // 设置立方体的三个面的路径
-          const frontFace = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          frontFace.setAttribute(
-            "d",
-            `M${frontX},${frontY} ` +
-              `L${frontW},${frontY} ` +
-              `L${frontW},${frontH} ` +
-              `L${frontX},${frontH} Z`
-          )
-
-          const rightFace = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          rightFace.setAttribute(
-            "d",
-            `M${frontW},${frontY} ` +
-              `L${element.width},0 ` +
-              `L${element.width},${element.height - offset} ` +
-              `L${frontW},${frontH} Z`
-          )
-
-          const topFace = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          topFace.setAttribute(
-            "d",
-            `M${frontX},${frontY} ` +
-              `L${frontW - offset - frontX},0 ` + // 修改这里:改为从(0,0)开始
-              `L${element.width - offset},0 ` + // 修改这里:使用 offset 来计算右上角的位置
-              `L${element.width},0 ` +
-              `L${frontW},${frontY} Z`
-          )
-
-          // 设置填充色
-          if (element.fill && element.fill.type === "color") {
-            const fillColor = element.fill.value || "transparent"
-            frontFace.setAttribute("fill", fillColor)
-            rightFace.setAttribute(
-              "fill",
-              this.adjustBrightness(fillColor, 0.8)
-            )
-            topFace.setAttribute("fill", this.adjustBrightness(fillColor, 1.2))
-          } else {
-            frontFace.setAttribute("fill", "transparent")
-            rightFace.setAttribute("fill", "transparent")
-            topFace.setAttribute("fill", "transparent")
-          }
-          // 设置边框
-          if (element.borderWidth > 0) {
-            const borderColor = element.borderColor || "#000"
-            const borderWidth = element.borderWidth || 1
-
-            frontFace.setAttribute("stroke", borderColor)
-            frontFace.setAttribute("stroke-width", borderWidth)
-            rightFace.setAttribute("stroke", borderColor)
-            rightFace.setAttribute("stroke-width", borderWidth)
-            topFace.setAttribute("stroke", borderColor)
-            topFace.setAttribute("stroke-width", borderWidth)
-
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              const dashArray =
-                element.borderStrokeDasharray ||
-                (element.borderType === "dotted" ? "1, 3" : "5, 5")
-              frontFace.setAttribute("stroke-dasharray", dashArray)
-              rightFace.setAttribute("stroke-dasharray", dashArray)
-              topFace.setAttribute("stroke-dasharray", dashArray)
-            }
-          }
-
-          // 按正确的顺序添加面(从后到前)
-          cube.appendChild(rightFace)
-          cube.appendChild(topFace)
-          cube.appendChild(frontFace)
-          svg.appendChild(cube)
-          break
-        case "bevel":
-          const bevel = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "g"
-          )
-
-          // 计算关键点坐标
-          const bevelOffset = element.width * 0.2
-          const smallRectX = bevelOffset
-          const smallRectY = bevelOffset
-          const smallRectW = element.width - 2 * bevelOffset
-          const smallRectH = element.height - 2 * bevelOffset
-
-          // 绘制顶部小矩形
-          const topRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "rect"
-          )
-          topRect.setAttribute("x", smallRectX)
-          topRect.setAttribute("y", smallRectY)
-          topRect.setAttribute("width", smallRectW)
-          topRect.setAttribute("height", smallRectH)
-
-          // 绘制四个梯形
-          const topTrapezoid = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          topTrapezoid.setAttribute(
-            "d",
-            `M0,0 L${element.width},0 L${
-              element.width - bevelOffset
-            },${bevelOffset} L${bevelOffset},${bevelOffset} Z`
-          )
-
-          const bottomTrapezoid = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          bottomTrapezoid.setAttribute(
-            "d",
-            `M${bevelOffset},${element.height - bevelOffset} L${
-              element.width - bevelOffset
-            },${element.height - bevelOffset} L${element.width},${
-              element.height
-            } L0,${element.height} Z`
-          )
-
-          const leftTrapezoid = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          leftTrapezoid.setAttribute(
-            "d",
-            `M0,0 L${bevelOffset},${bevelOffset} L${bevelOffset},${
-              element.height - bevelOffset
-            } L0,${element.height} Z`
-          )
-
-          const rightTrapezoid = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          rightTrapezoid.setAttribute(
-            "d",
-            `M${element.width},0 L${element.width},${element.height} L${
-              element.width - bevelOffset
-            },${element.height - bevelOffset} L${
-              element.width - bevelOffset
-            },${bevelOffset} Z`
-          )
-
-          // 设置填充色
-          if (element.fill && element.fill.type === "color") {
-            const fillColor = element.fill.value || "transparent"
-            topRect.setAttribute("fill", fillColor)
-            topTrapezoid.setAttribute(
-              "fill",
-              this.adjustBrightness(fillColor, 1.2)
-            )
-            bottomTrapezoid.setAttribute(
-              "fill",
-              this.adjustBrightness(fillColor, 0.8)
-            )
-            leftTrapezoid.setAttribute(
-              "fill",
-              this.adjustBrightness(fillColor, 0.9)
-            )
-            rightTrapezoid.setAttribute(
-              "fill",
-              this.adjustBrightness(fillColor, 0.7)
-            )
-          } else {
-            topRect.setAttribute("fill", "transparent")
-            topTrapezoid.setAttribute("fill", "transparent")
-            bottomTrapezoid.setAttribute("fill", "transparent")
-            leftTrapezoid.setAttribute("fill", "transparent")
-            rightTrapezoid.setAttribute("fill", "transparent")
-          }
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            const borderColor = element.borderColor || "#000"
-            const borderWidth = element.borderWidth || 1
-            const parts = [
-              topRect,
-              topTrapezoid,
-              bottomTrapezoid,
-              leftTrapezoid,
-              rightTrapezoid,
-            ]
-
-            parts.forEach((part) => {
-              part.setAttribute("stroke", borderColor)
-              part.setAttribute("stroke-width", borderWidth)
-
-              if (
-                element.borderType === "dotted" ||
-                element.borderType === "dashed"
-              ) {
-                const dashArray =
-                  element.borderStrokeDasharray ||
-                  (element.borderType === "dotted" ? "1, 3" : "5, 5")
-                part.setAttribute("stroke-dasharray", dashArray)
-              }
-            })
-          }
-
-          // 按正确的顺序添加面(从后到前)
-          bevel.appendChild(bottomTrapezoid)
-          bevel.appendChild(leftTrapezoid)
-          bevel.appendChild(rightTrapezoid)
-          bevel.appendChild(topTrapezoid)
-          bevel.appendChild(topRect)
-          svg.appendChild(bevel)
-          break
-        case "donut":
-          const donut = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "g"
-          )
-
-          // 外圆
-          const outerCircle = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "circle"
-          )
-          outerCircle.setAttribute("cx", element.width / 2)
-          outerCircle.setAttribute("cy", element.height / 2)
-          outerCircle.setAttribute(
-            "r",
-            Math.min(element.width, element.height) / 2
-          )
-
-          // 内圆
-          const innerCircle = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "circle"
-          )
-          innerCircle.setAttribute("cx", element.width / 2)
-          innerCircle.setAttribute("cy", element.height / 2)
-          innerCircle.setAttribute(
-            "r",
-            Math.min(element.width, element.height) / 4
-          )
-
-          // 设置填充色
-          setBackground(element, outerCircle)
-          innerCircle.setAttribute("fill", "white")
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            const borderColor = element.borderColor || "#000"
-            const borderWidth = element.borderWidth || 1
-
-            outerCircle.setAttribute("stroke", borderColor)
-            outerCircle.setAttribute("stroke-width", borderWidth)
-            innerCircle.setAttribute("stroke", borderColor)
-            innerCircle.setAttribute("stroke-width", borderWidth)
-
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              const dashArray =
-                element.borderStrokeDasharray ||
-                (element.borderType === "dotted" ? "1, 3" : "5, 5")
-              outerCircle.setAttribute("stroke-dasharray", dashArray)
-              innerCircle.setAttribute("stroke-dasharray", dashArray)
-            }
-          }
-
-          donut.appendChild(outerCircle)
-          donut.appendChild(innerCircle)
-          svg.appendChild(donut)
-          break
-        case "noSmoking":
-          const noSmoking = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "g"
-          )
-
-          // 创建路径
-          const path = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          path.setAttribute(
-            "d",
-            "M0,70 A77,70 0 1,1 0,71 Z M123.80284467265982,99.39738105155146 A57.5386,50.5386 0 0 0 45.160427644134444,27.90427466198293 Z M30.197155327340184,40.602618948448544 A57.5386,50.5386 0 0 0 108.83957235586556,112.09572533801708 Z"
-          )
-          path.setAttribute("fill", "rgba(255,217,102,1)")
-          path.setAttribute("stroke", "rgba(23,44,81,1)")
-          path.setAttribute("stroke-width", "1px")
-          path.setAttribute("stroke-dasharray", "")
-          path.setAttribute("stroke-linecap", "butt")
-          path.setAttribute("stroke-linejoin", "round")
-
-          noSmoking.appendChild(path)
-          svg.appendChild(noSmoking)
-          break
-        case "rightArrow":
-          const rightArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          rightArrow.setAttribute(
-            "points",
-            `0,${element.height * 0.3} ${element.width * 0.7},${
-              element.height * 0.3
-            } ` +
-              `${element.width * 0.7},0 ${element.width},${
-                element.height * 0.5
-              } ` +
-              `${element.width * 0.7},${element.height} ${
-                element.width * 0.7
-              },${element.height * 0.7} ` +
-              `0,${element.height * 0.7}`
-          )
-
-          // 设置填充色
-          setBackground(element, rightArrow)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            rightArrow.setAttribute("stroke", element.borderColor || "#000")
-            rightArrow.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                rightArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                rightArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                rightArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(rightArrow)
-          break
-        case "leftArrow":
-          const leftArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          leftArrow.setAttribute(
-            "points",
-            `${element.width},${element.height * 0.3} ${element.width * 0.3},${
-              element.height * 0.3
-            } ` +
-              `${element.width * 0.3},0 0,${element.height * 0.5} ` +
-              `${element.width * 0.3},${element.height} ${
-                element.width * 0.3
-              },${element.height * 0.7} ` +
-              `${element.width},${element.height * 0.7}`
-          )
-
-          // 设置填充色
-          setBackground(element, leftArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            leftArrow.setAttribute("stroke", element.borderColor || "#000")
-            leftArrow.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                leftArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                leftArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                leftArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(leftArrow)
-          break
-        case "upArrow":
-          const upArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          upArrow.setAttribute(
-            "points",
-            `${element.width * 0.3},${element.height} ${element.width * 0.3},${
-              element.height * 0.3
-            } ` +
-              `0,${element.height * 0.3} ${element.width * 0.5},0 ` +
-              `${element.width},${element.height * 0.3} ${
-                element.width * 0.7
-              },${element.height * 0.3} ` +
-              `${element.width * 0.7},${element.height}`
-          )
-
-          // 设置填充色
-          setBackground(element, upArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            upArrow.setAttribute("stroke", element.borderColor || "#000")
-            upArrow.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                upArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                upArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                upArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(upArrow)
-          break
-        case "downArrow":
-          const downArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          downArrow.setAttribute(
-            "points",
-            `${element.width * 0.3},0 ${element.width * 0.3},${
-              element.height * 0.7
-            } ` +
-              `0,${element.height * 0.7} ${element.width * 0.5},${
-                element.height
-              } ` +
-              `${element.width},${element.height * 0.7} ${
-                element.width * 0.7
-              },${element.height * 0.7} ` +
-              `${element.width * 0.7},0`
-          )
-
-          // 设置填充色
-          setBackground(element, downArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            downArrow.setAttribute("stroke", element.borderColor || "#000")
-            downArrow.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                downArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                downArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                downArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(downArrow)
-          break
-        case "leftRightArrow":
-          const leftRightArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          leftRightArrow.setAttribute(
-            "points",
-            `0,${element.height * 0.5} ${element.width * 0.2},${
-              element.height * 0.2
-            } ` +
-              `${element.width * 0.2},${element.height * 0.4} ${
-                element.width * 0.8
-              },${element.height * 0.4} ` +
-              `${element.width * 0.8},${element.height * 0.2} ${
-                element.width
-              },${element.height * 0.5} ` +
-              `${element.width * 0.8},${element.height * 0.8} ${
-                element.width * 0.8
-              },${element.height * 0.6} ` +
-              `${element.width * 0.2},${element.height * 0.6} ${
-                element.width * 0.2
-              },${element.height * 0.8}`
-          )
-
-          // 设置填充色
-          setBackground(element, leftRightArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            leftRightArrow.setAttribute("stroke", element.borderColor || "#000")
-            leftRightArrow.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                leftRightArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                leftRightArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                leftRightArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(leftRightArrow)
-          break
-        case "upDownArrow":
-          const upDownArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          upDownArrow.setAttribute(
-            "points",
-            `${element.width * 0.5},0 ${element.width * 0.3},${
-              element.height * 0.2
-            } ` +
-              `${element.width * 0.4},${element.height * 0.2} ${
-                element.width * 0.4
-              },${element.height * 0.8} ` +
-              `${element.width * 0.3},${element.height * 0.8} ${
-                element.width * 0.5
-              },${element.height} ` +
-              `${element.width * 0.7},${element.height * 0.8} ${
-                element.width * 0.6
-              },${element.height * 0.8} ` +
-              `${element.width * 0.6},${element.height * 0.2} ${
-                element.width * 0.7
-              },${element.height * 0.2}`
-          )
-
-          // 设置填充色
-          setBackground(element, upDownArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            upDownArrow.setAttribute("stroke", element.borderColor || "#000")
-            upDownArrow.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                upDownArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                upDownArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                upDownArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(upDownArrow)
-          break
-        case "quadArrow":
-          const quadArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算缩放比例
-          const scale = Math.min(element.width / 167, element.height / 121)
-          const offsetX = (element.width - 167 * scale) / 2
-          const offsetY = (element.height - 121 * scale) / 2
-
-          // 构建路径数据
-          const pathData = `
-            M${offsetX},${60.5 * scale + offsetY}
-            L${27.225 * scale + offsetX},${33.275 * scale + offsetY}
-            L${27.225 * scale + offsetX},${46.8875 * scale + offsetY}
-            L${69.8875 * scale + offsetX},${46.8875 * scale + offsetY}
-            L${69.8875 * scale + offsetX},${27.225 * scale + offsetY}
-            L${56.275 * scale + offsetX},${27.225 * scale + offsetY}
-            L${83.5 * scale + offsetX},${offsetY}
-            L${110.725 * scale + offsetX},${27.225 * scale + offsetY}
-            L${97.1125 * scale + offsetX},${27.225 * scale + offsetY}
-            L${97.1125 * scale + offsetX},${46.8875 * scale + offsetY}
-            L${139.775 * scale + offsetX},${46.8875 * scale + offsetY}
-            L${139.775 * scale + offsetX},${33.275 * scale + offsetY}
-            L${167 * scale + offsetX},${60.5 * scale + offsetY}
-            L${139.775 * scale + offsetX},${87.725 * scale + offsetY}
-            L${139.775 * scale + offsetX},${74.1125 * scale + offsetY}
-            L${97.1125 * scale + offsetX},${74.1125 * scale + offsetY}
-            L${97.1125 * scale + offsetX},${93.775 * scale + offsetY}
-            L${110.725 * scale + offsetX},${93.775 * scale + offsetY}
-            L${83.5 * scale + offsetX},${121 * scale + offsetY}
-            L${56.275 * scale + offsetX},${93.775 * scale + offsetY}
-            L${69.8875 * scale + offsetX},${93.775 * scale + offsetY}
-            L${69.8875 * scale + offsetX},${74.1125 * scale + offsetY}
-            L${27.225 * scale + offsetX},${74.1125 * scale + offsetY}
-            L${27.225 * scale + offsetX},${87.725 * scale + offsetY}
-            Z`
-
-          quadArrow.setAttribute("d", pathData)
-
-          // 设置填充色
-          setBackground(element, quadArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            quadArrow.setAttribute("stroke", element.borderColor || "#000")
-            quadArrow.setAttribute("stroke-width", element.borderWidth || 1)
-            quadArrow.setAttribute("stroke-linecap", "butt")
-            quadArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                quadArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                quadArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                quadArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(quadArrow)
-          break
-        case "leftRightUpArrow":
-          const leftRightUpArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算缩放比例
-          const scale2 = Math.min(element.width / 167, element.height / 121)
-          const offsetX2 = (element.width - 167 * scale2) / 2
-          const offsetY2 = (element.height - 121 * scale2) / 2
-
-          // 构建路径数据
-          const pathData2 = `
-            M${offsetX2},${60.5 * scale2 + offsetY2}
-            L${27.225 * scale2 + offsetX2},${33.275 * scale2 + offsetY2}
-            L${27.225 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
-            L${69.8875 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
-            L${69.8875 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
-            L${56.275 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
-            L${83.5 * scale2 + offsetX2},${offsetY2}
-            L${110.725 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
-            L${97.1125 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
-            L${97.1125 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
-            L${139.775 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
-            L${139.775 * scale2 + offsetX2},${33.275 * scale2 + offsetY2}
-            L${167 * scale2 + offsetX2},${60.5 * scale2 + offsetY2}
-            L${139.775 * scale2 + offsetX2},${87.725 * scale2 + offsetY2}
-            L${139.775 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
-            L${97.1125 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
-            L${69.8875 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
-            L${27.225 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
-            L${27.225 * scale2 + offsetX2},${87.725 * scale2 + offsetY2}
-            Z`
-
-          leftRightUpArrow.setAttribute("d", pathData2)
-
-          // 设置填充色
-          setBackground(element, leftRightUpArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            leftRightUpArrow.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            leftRightUpArrow.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            leftRightUpArrow.setAttribute("stroke-linecap", "butt")
-            leftRightUpArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                leftRightUpArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                leftRightUpArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                leftRightUpArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(leftRightUpArrow)
-          break
-        case "bentArrow":
-          const bentArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 构建路径数据
-          const pathData3 = `
-            M0,${element.height * 0.88}
-            L0,${element.height * 0.495}
-            A${element.width * 0.385} ${element.height * 0.385} 0 0 1 ${
-            element.width * 0.385
-          } ${element.height * 0.11}
-            L${element.width * 0.67},${element.height * 0.11}
-            L${element.width * 0.67},0
-            L${element.width * 0.89},${element.height * 0.22}
-            L${element.width * 0.67},${element.height * 0.44}
-            L${element.width * 0.67},${element.height * 0.33}
-            L${element.width * 0.385},${element.height * 0.33}
-            A${element.width * 0.165} ${element.height * 0.165} 0 0 0 ${
-            element.width * 0.22
-          } ${element.height * 0.495}
-            L${element.width * 0.22},${element.height * 0.88}
-            Z`
-
-          bentArrow.setAttribute("d", pathData3)
-
-          // 设置填充色
-          setBackground(element, bentArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            bentArrow.setAttribute("stroke", element.borderColor || "#000")
-            bentArrow.setAttribute("stroke-width", element.borderWidth || 1)
-            bentArrow.setAttribute("stroke-linecap", "butt")
-            bentArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                bentArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                bentArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                bentArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(bentArrow)
-          break
-        case "parallelogram":
-          const parallelogram = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          parallelogram.setAttribute(
-            "points",
-            `${element.width * 0.25},0 ${element.width},0 ${
-              element.width * 0.75
-            },${element.height} 0,${element.height}`
-          )
-
-          // 设置填充色
-          setBackground(element, parallelogram)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            parallelogram.setAttribute("stroke", element.borderColor || "#000")
-            parallelogram.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                parallelogram.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                parallelogram.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                parallelogram.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(parallelogram)
-          break
-        case "uturnArrow":
-          const uturnArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 构建路径数据
-          const pathDataUturn = `
-            M0,${element.height * 0.745}
-            L0,${element.height * 0.179375}
-            A${element.width * 0.179375} ${element.height * 0.179375} 0 0 1 ${
-            element.width * 0.179375
-          },0
-            L${element.width * 0.179375},0
-            A${element.width * 0.179375} ${element.height * 0.179375} 0 0 1 ${
-            element.width * 0.359375
-          },${element.height * 0.179375}
-            L${element.width * 0.359375},${element.height * 0.205}
-            L${element.width * 0.41},${element.height * 0.205}
-            L${element.width * 0.3075},${element.height * 0.3075}
-            L${element.width * 0.205},${element.height * 0.205}
-            L${element.width * 0.25625},${element.height * 0.205}
-            L${element.width * 0.25625},${element.height * 0.179375}
-            A${element.width * 0.076875} ${element.height * 0.076875} 0 0 0 ${
-            element.width * 0.179375
-          },${element.height * 0.1025}
-            L${element.width * 0.179375},${element.height * 0.1025}
-            A${element.width * 0.076875} ${element.height * 0.076875} 0 0 0 ${
-            element.width * 0.1025
-          },${element.height * 0.179375}
-            L${element.width * 0.1025},${element.height * 0.745}
-            Z`
-
-          uturnArrow.setAttribute("d", pathDataUturn)
-
-          // 设置填充色
-          setBackground(element, uturnArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            uturnArrow.setAttribute("stroke", element.borderColor || "#000")
-            uturnArrow.setAttribute("stroke-width", element.borderWidth || 1)
-            uturnArrow.setAttribute("stroke-linecap", "butt")
-            uturnArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                uturnArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                uturnArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                uturnArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(uturnArrow)
-          break
-        case "leftUpArrow":
-          const leftUpArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 使用提供的路径数据
-          const pathDataLeftUp = `
-            M0,${element.height * 0.65}
-            L${element.width * 0.15},${element.height * 0.4}
-            L${element.width * 0.15},${element.height * 0.55}
-            L${element.width * 0.5},${element.height * 0.55}
-            L${element.width * 0.5},${element.height * 0.1}
-            L${element.width * 0.35},${element.height * 0.1}
-            L${element.width * 0.65},0
-            L${element.width * 0.85},${element.height * 0.1}
-            L${element.width * 0.75},${element.height * 0.1}
-            L${element.width * 0.75},${element.height * 0.85}
-            L${element.width * 0.15},${element.height * 0.85}
-            L${element.width * 0.15},${element.height * 1}
-            Z`
-
-          leftUpArrow.setAttribute("d", pathDataLeftUp)
-
-          // 设置填充色
-          setBackground(element, leftUpArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            leftUpArrow.setAttribute("stroke", element.borderColor || "#000")
-            leftUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
-            leftUpArrow.setAttribute("stroke-linecap", "butt")
-            leftUpArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                leftUpArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                leftUpArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                leftUpArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(leftUpArrow)
-          break
-        case "bentUpArrow":
-          const bentUpArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 构建路径数据,去掉左侧箭头
-          // 使用提供的路径数据
-          const pathDataBentUp = `
-            M0,${element.height * 0.89}
-            L0,${element.height * 0.7}
-            L${element.width * 0.575},${element.height * 0.7}
-            L${element.width * 0.575},${element.height * 0.2}
-            L${element.width * 0.46},${element.height * 0.2}
-            L${element.width * 0.69},0
-            L${element.width * 0.92},${element.height * 0.2}
-            L${element.width * 0.805},${element.height * 0.2}
-            L${element.width * 0.805},${element.height * 0.89}
-            Z`
-
-          bentUpArrow.setAttribute("d", pathDataBentUp)
-
-          // 设置填充色
-          setBackground(element, bentUpArrow)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            bentUpArrow.setAttribute("stroke", element.borderColor || "#000")
-            bentUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
-            bentUpArrow.setAttribute("stroke-linecap", "butt")
-            bentUpArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                bentUpArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                bentUpArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                bentUpArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(bentUpArrow)
-          break
-        case "curvedRightArrow":
-          const curvedRightArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 使用提供的路径数据
-          const pathDataCurvedRight = `
-            M${element.width},0
-            A${element.width} ${element.height * 0.4} 0 0 0 0 ${
-            element.height * 0.4
-          }
-            L0,${element.height * 0.5}
-            A${element.width} ${element.height * 0.4} 0 0 1 ${element.width} ${
-            element.height * 0.15
-          }
-            Z
-            M0,${element.height * 0.4}
-            A${element.width} ${element.height * 0.4} 0 0 0 ${
-            element.width * 0.8
-          } ${element.height * 0.8}
-            L${element.width * 0.8},${element.height * 0.75}
-            L${element.width},${element.height * 0.875}
-            L${element.width * 0.8},${element.height * 1}
-            L${element.width * 0.8},${element.height * 0.95}
-            A${element.width} ${element.height * 0.4} 0 0 1 0 ${
-            element.height * 0.5
-          }
-            Z`
-
-          curvedRightArrow.setAttribute("d", pathDataCurvedRight)
-
-          // 设置填充色
-          setBackground(element, curvedRightArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            curvedRightArrow.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            curvedRightArrow.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            curvedRightArrow.setAttribute("stroke-linecap", "butt")
-            curvedRightArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                curvedRightArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                curvedRightArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                curvedRightArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(curvedRightArrow)
-          break
-        case "curvedLeftArrow":
-          const curvedLeftArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 定义左弧形箭头的路径数据
-          const pathDataCurvedLeft = `
-            M0,0
-            A${element.width} ${element.height * 0.4} 0 0 1 ${element.width} ${
-            element.height * 0.4
-          }
-            L${element.width},${element.height * 0.55}
-            A${element.width} ${element.height * 0.4} 0 0 0 0 ${
-            element.height * 0.15
-          }
-            Z
-            M0,${element.height * 0.85}
-            L${element.width * 0.25},${element.height * 0.65}
-            L${element.width * 0.25},${element.height * 0.75}
-            A${element.width} ${element.height * 0.4} 0 0 0 ${element.width} ${
-            element.height * 0.4
-          }
-            L${element.width},${element.height * 0.5}
-            L${element.width},${element.height * 0.5}
-            A${element.width} ${element.height * 0.4} 0 0 1 ${
-            element.width * 0.25
-          } ${element.height * 0.9}
-            L${element.width * 0.25},${element.height}
-            Z`
-
-          curvedLeftArrow.setAttribute("d", pathDataCurvedLeft)
-
-          // 设置填充色
-          setBackground(element, curvedLeftArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            curvedLeftArrow.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            curvedLeftArrow.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            curvedLeftArrow.setAttribute("stroke-linecap", "butt")
-            curvedLeftArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                curvedLeftArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                curvedLeftArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                curvedLeftArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(curvedLeftArrow)
-          break
-        case "curvedUpArrow":
-          const curvedUpArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 定义上弧形箭头的路径数据
-          const pathDataCurvedUp = `
-            M${element.width * 0.905},0
-            L${element.width * 0.81},${element.height * 0.25}
-            L${element.width * 0.857},${element.height * 0.25}
-            A${element.width * 0.428} ${element.height} 0 0 1 ${
-            element.width * 0.428
-          },${element.height}
-            L${element.width * 0.522},${element.height}
-            A${element.width * 0.428} ${element.height} 0 0 0 ${
-            element.width * 0.952
-          },${element.height * 0.25}
-            L${element.width},${element.height * 0.25}
-            Z
-            M${element.width * 0.094},0
-            L0,0
-            A${element.width * 0.428} ${element.height} 0 0 0 ${
-            element.width * 0.428
-          },${element.height}
-            L${element.width * 0.522},${element.height}
-            A${element.width * 0.428} ${element.height} 0 0 1 ${
-            element.width * 0.094
-          },0
-            Z`
-
-          curvedUpArrow.setAttribute("d", pathDataCurvedUp)
-
-          // 设置填充色
-          setBackground(element, curvedUpArrow)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            curvedUpArrow.setAttribute("stroke", element.borderColor || "#000")
-            curvedUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
-            curvedUpArrow.setAttribute("stroke-linecap", "butt")
-            curvedUpArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                curvedUpArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                curvedUpArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                curvedUpArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(curvedUpArrow)
-          break
-        case "curvedDownArrow":
-          const curvedDownArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 定义下弧形箭头的路径数据
-          const pathDataCurvedDown = `
-            M0,${element.height}
-            L${element.width * 0.16},${element.height}
-            A${element.width * 0.46} ${element.height} 0 0 1 ${
-            element.width * 0.62
-          },0
-            L${element.width * 0.46},0
-            A${element.width * 0.46} ${element.height} 0 0 0 0,${element.height}
-            Z
-            M${element.width},${element.height}
-            L${element.width * 0.84},${element.height * 0.75}
-            L${element.width * 0.92},${element.height * 0.75}
-            A${element.width * 0.46} ${element.height} 0 0 0 ${
-            element.width * 0.46
-          },0
-            L${element.width * 0.62},0
-            A${element.width * 0.46} ${element.height} 0 0 1 ${
-            element.width * 1.08
-          },${element.height * 0.75}
-            L${element.width * 1.16},${element.height * 0.75}
-            Z`
-
-          curvedDownArrow.setAttribute("d", pathDataCurvedDown)
-
-          // 设置填充色
-          setBackground(element, curvedDownArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            curvedDownArrow.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            curvedDownArrow.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            curvedDownArrow.setAttribute("stroke-linecap", "butt")
-            curvedDownArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                curvedDownArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                curvedDownArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                curvedDownArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(curvedDownArrow)
-          break
-        case "stripedRightArrow":
-          const stripedRightArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "g"
-          )
-
-          // 主箭头部分
-          const mainArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          mainArrow.setAttribute(
-            "d",
-            `M${element.width * 0.062},${element.height * 0.25}
-            L${element.width * 0.8},${element.height * 0.25}
-            L${element.width * 0.8},0
-            L${element.width},${element.height * 0.5}
-            L${element.width * 0.8},${element.height}
-            L${element.width * 0.8},${element.height * 0.75}
-            L${element.width * 0.062},${element.height * 0.75}
-            Z`
-          )
-
-          // 第一条尾部条纹
-          const stripe1 = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          stripe1.setAttribute(
-            "d",
-            `M0,${element.height * 0.25}
-            L${element.width * 0.012},${element.height * 0.25}
-            L${element.width * 0.012},${element.height * 0.75}
-            L0,${element.height * 0.75}
-            Z`
-          )
-
-          // 第二条尾部条纹
-          const stripe2 = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          stripe2.setAttribute(
-            "d",
-            `M${element.width * 0.025},${element.height * 0.25}
-            L${element.width * 0.049},${element.height * 0.25}
-            L${element.width * 0.049},${element.height * 0.75}
-            L${element.width * 0.025},${element.height * 0.75}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, mainArrow)
-          setBackground(element, stripe1)
-          setBackground(element, stripe2)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            ;[mainArrow, stripe1, stripe2].forEach((path) => {
-              path.setAttribute("stroke", element.borderColor || "#000")
-              path.setAttribute("stroke-width", element.borderWidth || 1)
-              path.setAttribute("stroke-linecap", "butt")
-              path.setAttribute("stroke-linejoin", "round")
-
-              // 处理虚线边框
-              if (
-                element.borderType === "dotted" ||
-                element.borderType === "dashed"
-              ) {
-                if (element.borderStrokeDasharray) {
-                  path.setAttribute(
-                    "stroke-dasharray",
-                    element.borderStrokeDasharray
-                  )
-                } else if (element.borderType === "dotted") {
-                  path.setAttribute("stroke-dasharray", "1, 3")
-                } else if (element.borderType === "dashed") {
-                  path.setAttribute("stroke-dasharray", "5, 5")
-                }
-              }
-            })
-          }
-
-          stripedRightArrow.appendChild(mainArrow)
-          stripedRightArrow.appendChild(stripe1)
-          stripedRightArrow.appendChild(stripe2)
-          svg.appendChild(stripedRightArrow)
-          break
-        case "rightArrowCallout":
-          const rightArrowCallout = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          rightArrowCallout.setAttribute(
-            "d",
-            `M0,0
-            L${element.width * 0.44},0
-            L${element.width * 0.44},${element.height * 0.375}
-            L${element.width * 0.79},${element.height * 0.375}
-            L${element.width * 0.79},${element.height * 0.25}
-            L${element.width},${element.height * 0.5}
-            L${element.width * 0.79},${element.height * 0.75}
-            L${element.width * 0.79},${element.height * 0.625}
-            L${element.width * 0.44},${element.height * 0.625}
-            L${element.width * 0.44},${element.height}
-            L0,${element.height}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, rightArrowCallout)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            rightArrowCallout.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            rightArrowCallout.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            rightArrowCallout.setAttribute("stroke-linecap", "butt")
-            rightArrowCallout.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                rightArrowCallout.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                rightArrowCallout.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                rightArrowCallout.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(rightArrowCallout)
-          break
-        case "leftRightArrowCallout":
-          const leftRightArrowCallout = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          leftRightArrowCallout.setAttribute(
-            "d",
-            `M0,${element.height * 0.5}
-            L${element.width * 0.139},${element.height * 0.25}
-            L${element.width * 0.139},${element.height * 0.375}
-            L${element.width * 0.364},${element.height * 0.375}
-            L${element.width * 0.364},0
-            L${element.width * 0.636},0
-            L${element.width * 0.636},${element.height * 0.375}
-            L${element.width * 0.861},${element.height * 0.375}
-            L${element.width * 0.861},${element.height * 0.25}
-            L${element.width},${element.height * 0.5}
-            L${element.width * 0.861},${element.height * 0.75}
-            L${element.width * 0.861},${element.height * 0.625}
-            L${element.width * 0.636},${element.height * 0.625}
-            L${element.width * 0.636},${element.height}
-            L${element.width * 0.364},${element.height}
-            L${element.width * 0.364},${element.height * 0.625}
-            L${element.width * 0.139},${element.height * 0.625}
-            L${element.width * 0.139},${element.height * 0.75}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, leftRightArrowCallout)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            leftRightArrowCallout.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            leftRightArrowCallout.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            leftRightArrowCallout.setAttribute("stroke-linecap", "butt")
-            leftRightArrowCallout.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                leftRightArrowCallout.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                leftRightArrowCallout.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                leftRightArrowCallout.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(leftRightArrowCallout)
-          break
-        case "quadArrowCallout":
-          const quadArrowCallout = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          quadArrowCallout.setAttribute(
-            "d",
-            `M0,${element.height * 0.5}
-            L${element.width * 0.096},${element.height * 0.315}
-            L${element.width * 0.096},${element.height * 0.407}
-            L${element.width * 0.26},${element.height * 0.407}
-            L${element.width * 0.26},${element.height * 0.259}
-            L${element.width * 0.453},${element.height * 0.259}
-            L${element.width * 0.453},${element.height * 0.185}
-            L${element.width * 0.405},${element.height * 0.185}
-            L${element.width * 0.5},0
-            L${element.width * 0.595},${element.height * 0.185}
-            L${element.width * 0.547},${element.height * 0.185}
-            L${element.width * 0.547},${element.height * 0.259}
-            L${element.width * 0.74},${element.height * 0.259}
-            L${element.width * 0.74},${element.height * 0.407}
-            L${element.width * 0.904},${element.height * 0.407}
-            L${element.width * 0.904},${element.height * 0.315}
-            L${element.width},${element.height * 0.5}
-            L${element.width * 0.904},${element.height * 0.685}
-            L${element.width * 0.904},${element.height * 0.593}
-            L${element.width * 0.74},${element.height * 0.593}
-            L${element.width * 0.74},${element.height * 0.741}
-            L${element.width * 0.547},${element.height * 0.741}
-            L${element.width * 0.547},${element.height * 0.815}
-            L${element.width * 0.595},${element.height * 0.815}
-            L${element.width * 0.5},${element.height}
-            L${element.width * 0.405},${element.height * 0.815}
-            L${element.width * 0.453},${element.height * 0.815}
-            L${element.width * 0.453},${element.height * 0.741}
-            L${element.width * 0.26},${element.height * 0.741}
-            L${element.width * 0.26},${element.height * 0.593}
-            L${element.width * 0.096},${element.height * 0.593}
-            L${element.width * 0.096},${element.height * 0.685}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, quadArrowCallout)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            quadArrowCallout.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            quadArrowCallout.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            quadArrowCallout.setAttribute("stroke-linecap", "butt")
-            quadArrowCallout.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                quadArrowCallout.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                quadArrowCallout.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                quadArrowCallout.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(quadArrowCallout)
-          break
-        case "leftArrowCallout":
-          const leftArrowCallout = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          leftArrowCallout.setAttribute(
-            "d",
-            `M0,${element.height * 0.5}
-            L${element.width * 0.183},${element.height * 0.25}
-            L${element.width * 0.183},${element.height * 0.375}
-            L${element.width * 0.35},${element.height * 0.375}
-            L${element.width * 0.35},0
-            L${element.width},0
-            L${element.width},${element.height}
-            L${element.width * 0.35},${element.height}
-            L${element.width * 0.35},${element.height * 0.625}
-            L${element.width * 0.183},${element.height * 0.625}
-            L${element.width * 0.183},${element.height * 0.75}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, leftArrowCallout)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            leftArrowCallout.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            leftArrowCallout.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            leftArrowCallout.setAttribute("stroke-linecap", "butt")
-            leftArrowCallout.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                leftArrowCallout.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                leftArrowCallout.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                leftArrowCallout.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(leftArrowCallout)
-          break
-        case "upArrowCallout":
-          const upArrowCallout = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          upArrowCallout.setAttribute(
-            "d",
-            `M0,${element.height * 0.35}
-            L${element.width * 0.41},${element.height * 0.35}
-            L${element.width * 0.41},${element.height * 0.25}
-            L${element.width * 0.32},${element.height * 0.25}
-            L${element.width * 0.5},0
-            L${element.width * 0.68},${element.height * 0.25}
-            L${element.width * 0.59},${element.height * 0.25}
-            L${element.width * 0.59},${element.height * 0.35}
-            L${element.width},${element.height * 0.35}
-            L${element.width},${element.height}
-            L0,${element.height}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, upArrowCallout)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            upArrowCallout.setAttribute("stroke", element.borderColor || "#000")
-            upArrowCallout.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            upArrowCallout.setAttribute("stroke-linecap", "butt")
-            upArrowCallout.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                upArrowCallout.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                upArrowCallout.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                upArrowCallout.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(upArrowCallout)
-          break
-        case "notchedRightArrow":
-          const notchedRightArrow = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          notchedRightArrow.setAttribute(
-            "d",
-            `M0,${element.height * 0.25}
-            L${element.width * 0.83},${element.height * 0.25}
-            L${element.width * 0.83},0
-            L${element.width},${element.height * 0.5}
-            L${element.width * 0.83},${element.height}
-            L${element.width * 0.83},${element.height * 0.75}
-            L0,${element.height * 0.75}
-            L${element.width * 0.086},${element.height * 0.5}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, notchedRightArrow)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            notchedRightArrow.setAttribute(
-              "stroke",
-              element.borderColor || "#000"
-            )
-            notchedRightArrow.setAttribute(
-              "stroke-width",
-              element.borderWidth || 1
-            )
-            notchedRightArrow.setAttribute("stroke-linecap", "butt")
-            notchedRightArrow.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                notchedRightArrow.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                notchedRightArrow.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                notchedRightArrow.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(notchedRightArrow)
-          break
-        case "homePlate":
-          const homePlate = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          homePlate.setAttribute(
-            "d",
-            `M0,0
-            L${element.width * 0.925},0
-            L${element.width},${element.height * 0.5}
-            L${element.width * 0.925},${element.height}
-            L0,${element.height}
-            Z`
-          )
-
-          // 设置填充色
-          setBackground(element, homePlate)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            homePlate.setAttribute("stroke", element.borderColor || "#000")
-            homePlate.setAttribute("stroke-width", element.borderWidth || 1)
-            homePlate.setAttribute("stroke-linecap", "butt")
-            homePlate.setAttribute("stroke-linejoin", "round")
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                homePlate.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                homePlate.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                homePlate.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(homePlate)
-          break
-        case "rightTriangle":
-          const rightTriangle = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          rightTriangle.setAttribute(
-            "points",
-            `0,0 ${element.width},${element.height} 0,${element.height}`
-          )
-
-          // 设置填充色
-          setBackground(element, rightTriangle)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            rightTriangle.setAttribute("stroke", element.borderColor || "#000")
-            rightTriangle.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                rightTriangle.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                rightTriangle.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                rightTriangle.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(rightTriangle)
-          break
-        case "semiCircle":
-          const semiCircle = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          semiCircle.setAttribute(
-            "d",
-            `M0,${element.height} A${element.width / 2},${
-              element.height
-            } 0 0,1 ${element.width},${element.height} Z`
-          )
-
-          // 设置填充色
-          setBackground(element, semiCircle)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            semiCircle.setAttribute("stroke", element.borderColor || "#000")
-            semiCircle.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                semiCircle.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                semiCircle.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                semiCircle.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(semiCircle)
-          break
-
-        case "star":
-          const star = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          const cx = element.width / 2
-          const cy = element.height / 2
-          const outerRadius = Math.min(element.width, element.height) / 2
-          const innerRadius = outerRadius * 0.4
-          let starPoints = ""
-
-          for (let i = 0; i < 10; i++) {
-            const radius = i % 2 === 0 ? outerRadius : innerRadius
-            const angle = (Math.PI * i) / 5
-            const x = cx + radius * Math.sin(angle)
-            const y = cy - radius * Math.cos(angle)
-            starPoints += `${x},${y} `
-          }
-
-          star.setAttribute("points", starPoints.trim())
-
-          // 设置填充色
-          setBackground(element, star)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            star.setAttribute("stroke", element.borderColor || "#000")
-            star.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                star.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                star.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                star.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(star)
-          break
-
-        case "cross":
-          const cross = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-          cross.setAttribute(
-            "points",
-            `${element.width * 0.35},0 ${element.width * 0.65},0 ${
-              element.width * 0.65
-            },${element.height * 0.35} ` +
-              `${element.width},${element.height * 0.35} ${element.width},${
-                element.height * 0.65
-              } ` +
-              `${element.width * 0.65},${element.height * 0.65} ${
-                element.width * 0.65
-              },${element.height} ` +
-              `${element.width * 0.35},${element.height} ${
-                element.width * 0.35
-              },${element.height * 0.65} ` +
-              `0,${element.height * 0.65} 0,${element.height * 0.35} ${
-                element.width * 0.35
-              },${element.height * 0.35}`
-          )
-
-          // 设置填充色
-          setBackground(element, cross)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            cross.setAttribute("stroke", element.borderColor || "#000")
-            cross.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                cross.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                cross.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                cross.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(cross)
-          break
-
-        case "chevron":
-          const chevron = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "polygon"
-          )
-
-          chevron.setAttribute(
-            "points",
-            `${element.width * 0.5},0 ${element.width},${
-              element.height * 0.5
-            } ` +
-              `${element.width * 0.5},${element.height} ` +
-              `0,${element.height} ${element.width * 0.5},${
-                element.height * 0.5
-              } 0,0`
-          )
-
-          // 设置填充色
-          setBackground(element, chevron)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            chevron.setAttribute("stroke", element.borderColor || "#000")
-            chevron.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                chevron.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                chevron.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                chevron.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(chevron)
-          break
-
-        case "frame":
-          // 创建外框和内框
-          const outerRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "rect"
-          )
-          outerRect.setAttribute("x", 0)
-          outerRect.setAttribute("y", 0)
-          outerRect.setAttribute("width", element.width)
-          outerRect.setAttribute("height", element.height)
-
-          const innerRect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "rect"
-          )
-          const frameWidth = element.width / 10
-          innerRect.setAttribute("x", frameWidth)
-          innerRect.setAttribute("y", frameWidth)
-          innerRect.setAttribute("width", element.width - frameWidth * 2)
-          innerRect.setAttribute("height", element.height - frameWidth * 2)
-
-          // 设置填充色
-          setBackground(element, outerRect)
-          innerRect.setAttribute("fill", "white") // 内框为白色
-          // 设置边框
-          if (element.borderWidth > 0) {
-            outerRect.setAttribute("stroke", element.borderColor || "#000")
-            outerRect.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                outerRect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                outerRect.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                outerRect.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(outerRect)
-          svg.appendChild(innerRect)
-          break
-
-        case "cloud":
-          // 使用路径绘制云形
-          const cloud = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-          const w = element.width
-          const h = element.height
-
-          cloud.setAttribute(
-            "d",
-            `M${w * 0.2},${h * 0.6} ` +
-              `C${w * 0.05},${h * 0.6} ${w * 0.05},${h * 0.3} ${w * 0.2},${
-                h * 0.3
-              } ` +
-              `C${w * 0.2},${h * 0.1} ${w * 0.45},${h * 0.1} ${w * 0.5},${
-                h * 0.3
-              } ` +
-              `C${w * 0.55},${h * 0.1} ${w * 0.8},${h * 0.1} ${w * 0.8},${
-                h * 0.3
-              } ` +
-              `C${w * 0.95},${h * 0.3} ${w * 0.95},${h * 0.6} ${w * 0.8},${
-                h * 0.6
-              } ` +
-              `L${w * 0.2},${h * 0.6} Z`
-          )
-
-          // 设置填充色
-          setBackground(element, cloud)
-          // 设置边框
-          if (element.borderWidth > 0) {
-            cloud.setAttribute("stroke", element.borderColor || "#000")
-            cloud.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                cloud.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                cloud.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                cloud.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(cloud)
-          break
-        case "blockArc":
-          const blockArc = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "path"
-          )
-
-          // 计算弧形参数
-          const rx = element.width / 2
-          const ry = element.height / 2
-          const innerRatio = 0.86 // 根据示例计算的内弧半径比例
-          const innerRx = rx * innerRatio
-          const innerRy = ry * innerRatio
-
-          // 构建路径
-          const path2 = `
-            M 0,${ry} 
-            A ${rx} ${ry} 0 1 1 ${element.width} ${ry}
-            L ${element.width - (rx - innerRx)},${ry}
-            A ${innerRx} ${innerRy} 0 1 0 ${rx - innerRx},${ry}
-            Z`
-
-          blockArc.setAttribute("d", path2.trim())
-
-          // 设置填充色
-          setBackground(element, blockArc)
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            blockArc.setAttribute("stroke", element.borderColor || "#000")
-            blockArc.setAttribute("stroke-width", element.borderWidth || 1)
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                blockArc.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                blockArc.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                blockArc.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(blockArc)
-          break
-
-        case "rect":
-        default:
-          const rect = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "rect"
-          )
-          rect.setAttribute("x", 0)
-          rect.setAttribute("y", 0)
-          rect.setAttribute("width", element.width)
-          rect.setAttribute("height", element.height)
-          if (element.fill && element.fill.type) {
-            // 设置填充色
-            if (element.fill.type === "color") {
-              rect.setAttribute("fill", element.fill.value || "transparent")
-            } else if (element.fill.type === "gradient") {
-              // 渐变填充
-              const { colors, path, rot } = element.fill.value
-
-              if (colors && colors.length >= 2) {
-                const gradientType = path === "rect" ? "linear" : "radial"
-                const gradientAngle =
-                  gradientType === "linear" ? (90 - (rot || 0)) % 360 : rot || 0
-
-                let gradientString = `${gradientType}-gradient(`
-                if (gradientType === "linear") {
-                  gradientString += `${gradientAngle}deg, `
-                }
-
-                colors.forEach((color, i) => {
-                  gradientString += `${color.color} ${color.pos}${
-                    i < colors.length - 1 ? ", " : ""
-                  }`
-                })
-                gradientString += ")"
-
-                // 创建渐变定义
-                const gradientDef = document.createElementNS(
-                  "http://www.w3.org/2000/svg",
-                  "defs"
-                )
-                const gradientEl = document.createElementNS(
-                  "http://www.w3.org/2000/svg",
-                  gradientType === "linear"
-                    ? "linearGradient"
-                    : "radialGradient"
-                )
-                const gradientId = `gradient-${Date.now()}-${Math.random()
-                  .toString(36)
-                  .substr(2, 9)}`
-                gradientEl.setAttribute("id", gradientId)
-
-                // 设置渐变属性
-                if (gradientType === "linear") {
-                  gradientEl.setAttribute(
-                    "gradientTransform",
-                    `rotate(${gradientAngle})`
-                  )
-                }
-
-                // 添加渐变色标
-                colors.forEach((color) => {
-                  const stop = document.createElementNS(
-                    "http://www.w3.org/2000/svg",
-                    "stop"
-                  )
-                  stop.setAttribute("offset", color.pos)
-                  stop.setAttribute("stop-color", color.color)
-                  gradientEl.appendChild(stop)
-                })
-
-                gradientDef.appendChild(gradientEl)
-                svg.appendChild(gradientDef)
-
-                // 应用渐变
-                rect.setAttribute("fill", `url(#${gradientId})`)
-              }
-            } else if (element.fill.type === "image") {
-              // 创建图案填充
-              const pattern = document.createElementNS(
-                "http://www.w3.org/2000/svg",
-                "pattern"
-              )
-              const patternId = `pattern-${Date.now()}-${Math.random()
-                .toString(36)
-                .substr(2, 9)}`
-              pattern.setAttribute("id", patternId)
-              pattern.setAttribute("patternUnits", "userSpaceOnUse")
-              pattern.setAttribute("width", "100%")
-              pattern.setAttribute("height", "100%")
-
-              // 创建图片元素
-              const image = document.createElementNS(
-                "http://www.w3.org/2000/svg",
-                "image"
-              )
-              image.setAttribute("width", "100%")
-              image.setAttribute("height", "100%")
-              image.setAttribute("preserveAspectRatio", "xMidYMid slice")
-              image.setAttributeNS(
-                "http://www.w3.org/1999/xlink",
-                "href",
-                element.fill.value.picBase64
-              )
-
-              pattern.appendChild(image)
-
-              // 添加pattern到defs
-              const defs = document.createElementNS(
-                "http://www.w3.org/2000/svg",
-                "defs"
-              )
-              defs.appendChild(pattern)
-              svg.appendChild(defs)
-
-              // 应用图案填充
-              rect.setAttribute("fill", `url(#${patternId})`)
-            } else {
-              rect.setAttribute("fill", "transparent")
-            }
-          } else {
-            rect.setAttribute("fill", "#ffffff00")
-          }
-
-          // 设置边框
-          if (element.borderWidth > 0) {
-            rect.setAttribute("stroke", element.borderColor || "#000")
-            rect.setAttribute("stroke-width", element.borderWidth || 1)
-
-            // 处理虚线边框
-            if (
-              element.borderType === "dotted" ||
-              element.borderType === "dashed"
-            ) {
-              if (element.borderStrokeDasharray) {
-                rect.setAttribute(
-                  "stroke-dasharray",
-                  element.borderStrokeDasharray
-                )
-              } else if (element.borderType === "dotted") {
-                rect.setAttribute("stroke-dasharray", "1, 3")
-              } else if (element.borderType === "dashed") {
-                rect.setAttribute("stroke-dasharray", "5, 5")
-              }
-            }
-          }
-
-          svg.appendChild(rect)
-          break
-      }
-
-      const transformList = []
-      let rotateDeg = element.rotate || 0
-
-      if (element.isFlipV) {
-        transformList.push(`scaleY(-1)`)
-        rotateDeg = -rotateDeg // 垂直翻转时反转旋转方向
-      }
-
-      if (element.isFlipH) {
-        transformList.push(`scaleX(-1)`)
-        rotateDeg = -rotateDeg // 水平翻转时反转旋转方向
-      }
-
-      if (element.rotate) {
-        transformList.push(`rotate(${rotateDeg}deg)`)
-      }
-
-      if (transformList.length > 0) {
-        el.style.transform = transformList.join(" ")
-        el.style.transformOrigin = "center center"
-      }
-
-      el.appendChild(svg)
-
-      // 设置形状内容
-      if (element.content) {
-        const contentContainer = document.createElement("div")
-        contentContainer.innerHTML = this.convertPtToPxInContent(
-          element.content
-        )
-        contentContainer.style.position = "absolute"
-        contentContainer.style.width = element.width + "px"
-        contentContainer.style.height = element.height + "px"
-        contentContainer.style.top = "0px"
-        contentContainer.style.left = "0px"
-        contentContainer.style.display = "flex"
-        contentContainer.style.alignItems = "center"
-        contentContainer.style.justifyContent = "center"
-        contentContainer.style.zIndex = element.order
-        contentContainer.style.pointerEvents = "none"
-        const transformList = []
-        let rotateDeg = element.rotate || 0
-
-        if (element.isFlipV) {
-          transformList.push(`scaleY(-1)`)
-          rotateDeg = -rotateDeg // 垂直翻转时反转旋转方向
-        }
-
-        if (element.isFlipH) {
-          transformList.push(`scaleX(-1)`)
-          rotateDeg = -rotateDeg // 水平翻转时反转旋转方向
-        }
-
-        if (element.rotate) {
-          transformList.push(`rotate(${rotateDeg}deg)`)
-        }
-
-        if (transformList.length > 0) {
-          contentContainer.style.transform = transformList.join(" ")
-          contentContainer.style.transformOrigin = "center center"
-        }
-        el.appendChild(contentContainer)
-      }
-      return el
-    },
-
-    // 创建表格元素
-    createTableElement(element) {
-      const el = document.createElement("div")
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.width = element.width + "px"
-      el.style.height = element.height + "px"
-      el.style.zIndex = element.order
-
-      // 创建表格元素
-      const table = document.createElement("table")
-      table.style.width = element.width + "px"
-      table.style.height = element.height + "px"
-      table.style.borderCollapse = "collapse"
-      table.style.tableLayout = "fixed"
-      // 设置表格边框
-      if (element.borders) {
-        if (element.borders.all) {
-          const border = element.borders.all
-          table.style.border = `${border.borderWidth || 1}px ${
-            border.borderType || "solid"
-          } ${border.borderColor || "#000"}`
-        } else {
-          // 分别设置四边边框
-          if (element.borders.top) {
-            table.style.borderTop = `${
-              element.borders.top.borderWidth || 1
-            }px ${element.borders.top.borderType || "solid"} ${
-              element.borders.top.borderColor || "#000"
-            }`
-          }
-          if (element.borders.bottom) {
-            table.style.borderBottom = `${
-              element.borders.bottom.borderWidth || 1
-            }px ${element.borders.bottom.borderType || "solid"} ${
-              element.borders.bottom.borderColor || "#000"
-            }`
-          }
-          if (element.borders.left) {
-            table.style.borderLeft = `${
-              element.borders.left.borderWidth || 1
-            }px ${element.borders.left.borderType || "solid"} ${
-              element.borders.left.borderColor || "#000"
-            }`
-          }
-          if (element.borders.right) {
-            table.style.borderRight = `${
-              element.borders.right.borderWidth || 1
-            }px ${element.borders.right.borderType || "solid"} ${
-              element.borders.right.borderColor || "#000"
-            }`
-          }
-        }
-      }
-
-      // 创建表格内容
-      const tbody = document.createElement("tbody")
-
-      // 处理表格数据
-      if (element.data && element.data.length > 0) {
-        element.data.forEach((rowData, rowIndex) => {
-          const tr = document.createElement("tr")
-
-          rowData.forEach((cell, colIndex) => {
-            // 跳过被合并的单元格
-            if (cell.hMerge) return
-
-            const td = document.createElement("td")
-
-            // 设置单元格内容
-            if (cell.text) {
-              td.innerHTML = this.convertPtToPxInContent(cell.text)
-            }
-
-            // 设置单元格样式
-            td.style.padding = "0px"
-            td.style.verticalAlign = "middle"
-
-            // 设置文本样式
-            if (cell.fontColor) td.style.color = cell.fontColor
-            if (cell.fontSize) td.style.fontSize = cell.fontSize
-            if (cell.fontFamily) td.style.fontFamily = cell.fontFamily
-            if (cell.bold) td.style.fontWeight = "bold"
-            if (cell.italic) td.style.fontStyle = "italic"
-            if (cell.underline) td.style.textDecoration = "underline"
-            if (cell.align) td.style.textAlign = cell.align
-
-            // 设置背景色
-            if (cell.fillColor) td.style.backgroundColor = cell.fillColor
-
-            // 设置单元格边框
-            if (cell.borders) {
-              if (cell.borders.all) {
-                const border = cell.borders.all
-                td.style.border = `${border.borderWidth || 1}px ${
-                  border.borderType || "solid"
-                } ${border.borderColor || "#000"}`
-              } else {
-                // 分别设置四边边框
-                if (cell.borders.top) {
-                  td.style.borderTop = `${
-                    cell.borders.top.borderWidth || 1
-                  }px ${cell.borders.top.borderType || "solid"} ${
-                    cell.borders.top.borderColor || "#000"
-                  }`
-                }
-                if (cell.borders.bottom) {
-                  td.style.borderBottom = `${
-                    cell.borders.bottom.borderWidth || 1
-                  }px ${cell.borders.bottom.borderType || "solid"} ${
-                    cell.borders.bottom.borderColor || "#000"
-                  }`
-                }
-                if (cell.borders.left) {
-                  td.style.borderLeft = `${
-                    cell.borders.left.borderWidth || 1
-                  }px ${cell.borders.left.borderType || "solid"} ${
-                    cell.borders.left.borderColor || "#000"
-                  }`
-                }
-                if (cell.borders.right) {
-                  td.style.borderRight = `${
-                    cell.borders.right.borderWidth || 1
-                  }px ${cell.borders.right.borderType || "solid"} ${
-                    cell.borders.right.borderColor || "#000"
-                  }`
-                }
-              }
-            }
-            td.style.width = element.colWidths[colIndex] + "px"
-            // 设置单元格合并
-            if (cell.colSpan && cell.colSpan > 1) {
-              td.colSpan = cell.colSpan
-              td.style.width = element.colWidths[colIndex] * cell.colSpan + "px"
-            }
-            if (cell.rowSpan && cell.rowSpan > 1) {
-              td.rowSpan = cell.rowSpan
-            }
-
-            tr.appendChild(td)
-          })
-          tr.style.height = element.rowHeights[rowIndex] + "px"
-          tbody.appendChild(tr)
-        })
-      }
-
-      table.appendChild(tbody)
-      el.appendChild(table)
-
-      return el
-    },
-    // 创建图表元素
-    createChartElement(element) {
-      // 1. 创建基础容器
-      const el = document.createElement("div")
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.width = element.width + "px"
-      el.style.height = element.height + "px"
-      el.style.zIndex = element.order
-      // 2. 创建SVG画布
-      const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg")
-      svg.setAttribute("width", element.width)
-      svg.setAttribute("height", element.height)
-      svg.setAttribute("viewBox", `0 0 ${element.width} ${element.height}`)
-
-      // 3. 设置图表内边距
-      const padding = {
-        top: 60, // 为图例留出空间
-        right: 40, // 右侧边距
-        bottom: 60, // X轴标签空间
-        left: 60, // Y轴标签空间
-      }
-
-      // 4. 计算实际绘图区域
-      const chartWidth = element.width - padding.left - padding.right
-      const chartHeight = element.height - padding.top - padding.bottom
-      // 处理不同图表类型
-      switch (element.chartType) {
-        case "barChart":
-          // 绘制柱状图
-          this.drawBarChart(svg, element, {
-            padding,
-            chartWidth,
-            chartHeight,
-            barDir: element.barDir || "col",
-            grouping: element.grouping || "clustered",
-          })
-          break
-        case "pieChart":
-        case "doughnutChart":
-          this.drawDonutChart(svg, element, chartWidth, chartHeight)
-          break
-        default:
-            // 占位符
-          svg.innerHTML = `<text x="${element.width / 2}" y="${
-            element.height / 2
-          }" text-anchor="middle" fill="#999" font-size="12px">
-            暂不支持该类型图表
-          </text>`
-          console.warn("Unsupported chart type:", element.chartType)
-      }
-
-      el.appendChild(svg)
-      return el
-    },
-    drawDonutChart(svg, element, chartWidth, chartHeight) {
-      // 计算饼图中心点和半径
-      const cx = element.width / 2
-      const cy = element.height / 2
-      const radius = Math.min(chartWidth, chartHeight) / 2
-
-      // 计算所有数据总和
-      const total = element.data[0].values.reduce(
-        (sum, item) => sum + item.y,
-        0
-      )
-
-      // 创建颜色数组
-      const colors = element.colors || [
-        "#5B9BD5",
-        "#ED7D31",
-        "#A5A5A5",
-        "#FFC000",
-      ]
-
-      let startAngle = 0
-      element.data[0].values.forEach((item, index) => {
-        // 计算扇形角度
-        const angle = (item.y / total) * Math.PI * 2
-
-        // 计算扇形路径
-        const endAngle = startAngle + angle
-        const x1 = cx + radius * Math.cos(startAngle)
-        const y1 = cy + radius * Math.sin(startAngle)
-        const x2 = cx + radius * Math.cos(endAngle)
-        const y2 = cy + radius * Math.sin(endAngle)
-
-        // 创建扇形路径
-        const path = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "path"
-        )
-        const largeArcFlag = angle > Math.PI ? 1 : 0
-
-        // 根据是否为环形图决定内圆半径
-        const innerRadius =
-          element.chartType === "doughnutChart" ? radius * 0.6 : 0
-        if (element.chartType === "doughnutChart") {
-          // 环形图路径
-          const ix1 = cx + innerRadius * Math.cos(startAngle)
-          const iy1 = cy + innerRadius * Math.sin(startAngle)
-          const ix2 = cx + innerRadius * Math.cos(endAngle)
-          const iy2 = cy + innerRadius * Math.sin(endAngle)
-
-          path.setAttribute(
-            "d",
-            `
-            M ${x1} ${y1}
-            A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}
-            L ${ix2} ${iy2}
-            A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${ix1} ${iy1}
-            Z
-          `
-          )
-        } else {
-          // 饼图路径
-          path.setAttribute(
-            "d",
-            `
-            M ${cx} ${cy}
-            L ${x1} ${y1}
-            A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}
-            Z
-          `
-          )
-        }
-
-        // 设置填充色
-        path.setAttribute("fill", colors[index % colors.length])
-        path.setAttribute("stroke", "#fff")
-        path.setAttribute("stroke-width", "1")
-        svg.appendChild(path)
-
-        // 添加数值标签
-        const labelAngle = startAngle + angle / 2
-        const labelRadius = radius * 1.1
-        const labelX = cx + labelRadius * Math.cos(labelAngle)
-        const labelY = cy + labelRadius * Math.sin(labelAngle)
-
-        const label = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        label.setAttribute("x", labelX)
-        label.setAttribute("y", labelY)
-        label.setAttribute("text-anchor", "middle")
-        label.setAttribute("alignment-baseline", "middle")
-        label.setAttribute("font-size", "12px")
-        label.textContent = `${((item.y / total) * 100).toFixed(1)}%`
-        svg.appendChild(label)
-
-        startAngle = endAngle
-      })
-    },
-    // 绘制柱状图
-    drawBarChart(svg, element, options) {
-      const { padding, chartWidth, chartHeight, barDir, grouping } = options
-      const series = element.data
-      const categories = series[0].xlabels
-      const categoryCount = Object.keys(categories).length
-
-      // 1. 计算最大值
-      let maxValue = 0
-      series.forEach((serie) => {
-        const seriesMax = Math.max(...serie.values.map((v) => v.y))
-        maxValue = Math.max(maxValue, seriesMax)
-      })
-      maxValue = maxValue * 1.2 // 增加20%空间
-
-      // 2. 计算柱子布局
-      const groupWidth = chartWidth / categoryCount
-      const barWidth =
-        grouping === "clustered"
-          ? (groupWidth * 0.6) / series.length // 分组模式
-          : groupWidth * 0.6 // 堆叠模式
-      const barSpacing =
-        (groupWidth * 0.4) / (grouping === "clustered" ? series.length + 1 : 2)
-
-      // 3. 绘制坐标轴
-      // X轴
-      const xAxisPath = document.createElementNS(
-        "http://www.w3.org/2000/svg",
-        "path"
-      )
-      xAxisPath.setAttribute(
-        "d",
-        `M${padding.left},${element.height - padding.bottom} L${
-          element.width - padding.right
-        },${element.height - padding.bottom}`
-      )
-      xAxisPath.setAttribute("stroke", "#000")
-      xAxisPath.setAttribute("stroke-width", "1")
-      svg.appendChild(xAxisPath)
-
-      // Y轴
-      const yAxisPath = document.createElementNS(
-        "http://www.w3.org/2000/svg",
-        "path"
-      )
-      yAxisPath.setAttribute(
-        "d",
-        `M${padding.left},${padding.top} L${padding.left},${
-          element.height - padding.bottom
-        }`
-      )
-      yAxisPath.setAttribute("stroke", "#000")
-      yAxisPath.setAttribute("stroke-width", "1")
-      svg.appendChild(yAxisPath)
-
-      // 4. 绘制Y轴刻度和网格线
-      const yTickCount = 5
-      for (let i = 0; i <= yTickCount; i++) {
-        const y = padding.top + (chartHeight * i) / yTickCount
-        const value = maxValue - (maxValue * i) / yTickCount
-
-        // 水平网格线
-        const gridLine = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "line"
-        )
-        gridLine.setAttribute("x1", padding.left)
-        gridLine.setAttribute("y1", y)
-        gridLine.setAttribute("x2", padding.left + chartWidth)
-        gridLine.setAttribute("y2", y)
-        gridLine.setAttribute("stroke", "#eee")
-        gridLine.setAttribute("stroke-width", "1")
-        svg.appendChild(gridLine)
-
-        // 刻度线
-        const tick = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "line"
-        )
-        tick.setAttribute("x1", padding.left - 6)
-        tick.setAttribute("y1", y)
-        tick.setAttribute("x2", padding.left)
-        tick.setAttribute("y2", y)
-        tick.setAttribute("stroke", "#000")
-        tick.setAttribute("stroke-width", "1")
-        svg.appendChild(tick)
-
-        // 刻度值
-        const label = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        label.setAttribute("x", padding.left - 10)
-        label.setAttribute("y", y + 4)
-        label.setAttribute("text-anchor", "end")
-        label.setAttribute("font-size", "12px")
-        label.textContent = value.toFixed(1)
-        svg.appendChild(label)
-      }
-
-      // 5. 绘制数据条
-      series.forEach((serie, serieIndex) => {
-        serie.values.forEach((value, index) => {
-          const barHeight = (value.y / maxValue) * chartHeight
-          const x =
-            padding.left +
-            groupWidth * index +
-            (grouping === "clustered"
-              ? barSpacing * (serieIndex + 1) + barWidth * serieIndex
-              : barSpacing)
-          const y = element.height - padding.bottom - barHeight
-
-          // 绘制柱子
-          const bar = document.createElementNS(
-            "http://www.w3.org/2000/svg",
-            "rect"
-          )
-          bar.setAttribute("x", x)
-          bar.setAttribute("y", y)
-          bar.setAttribute("width", barWidth)
-          bar.setAttribute("height", barHeight)
-          bar.setAttribute(
-            "fill",
-            element.colors[serieIndex] || `hsl(${serieIndex * 60}, 70%, 50%)`
-          )
-          svg.appendChild(bar)
-
-          // 数值标签
-          if (element.marker) {
-            const label = document.createElementNS(
-              "http://www.w3.org/2000/svg",
-              "text"
-            )
-            label.setAttribute("x", x + barWidth / 2)
-            label.setAttribute("y", y - 5)
-            label.setAttribute("text-anchor", "middle")
-            label.setAttribute("font-size", "12px")
-            label.textContent = value.y.toFixed(1)
-            svg.appendChild(label)
-          }
-        })
-      })
-
-      // 6. 绘制X轴类别标签
-      Object.values(categories).forEach((label, index) => {
-        const x = padding.left + groupWidth * (index + 0.5)
-        const text = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        text.setAttribute("x", x)
-        text.setAttribute("y", element.height - padding.bottom + 20)
-        text.setAttribute("text-anchor", "middle")
-        text.setAttribute("font-size", "12px")
-        text.textContent = label
-        svg.appendChild(text)
-      })
-
-      // 7. 绘制图例
-      series.forEach((serie, index) => {
-        const legendX = padding.left + index * 120
-        const legendY = 20
-
-        const rect = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "rect"
-        )
-        rect.setAttribute("x", legendX)
-        rect.setAttribute("y", legendY)
-        rect.setAttribute("width", 15)
-        rect.setAttribute("height", 15)
-        rect.setAttribute(
-          "fill",
-          element.colors[index] || `hsl(${index * 60}, 70%, 50%)`
-        )
-        svg.appendChild(rect)
-
-        const text = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        text.setAttribute("x", legendX + 25)
-        text.setAttribute("y", legendY + 12)
-        text.setAttribute("font-size", "12px")
-        text.textContent = serie.key
-        svg.appendChild(text)
-      })
-    },
-    // 绘制网格和刻度
-    drawGrid(svg, padding, width, height, maxValue) {
-      const yTickCount = 5
-      for (let i = 0; i <= yTickCount; i++) {
-        const y = padding.top + (height * i) / yTickCount
-        const value = maxValue - (maxValue * i) / yTickCount
-
-        // 刻度线
-        const tick = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "line"
-        )
-        tick.setAttribute("x1", padding.left - 5)
-        tick.setAttribute("x2", padding.left)
-        tick.setAttribute("y1", y)
-        tick.setAttribute("y2", y)
-        tick.setAttribute("stroke", "#000")
-        svg.appendChild(tick)
-
-        // 刻度值
-        const label = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        label.setAttribute("x", padding.left - 8)
-        label.setAttribute("y", y + 4)
-        label.setAttribute("text-anchor", "end")
-        label.setAttribute("font-size", "12px")
-        label.textContent = value.toFixed(1)
-        svg.appendChild(label)
-      }
-    },
-    // 绘制类别标签
-    drawCategoryLabels(svg, categories, padding, groupWidth, barDir) {
-      Object.values(categories).forEach((label, index) => {
-        const text = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        if (barDir === "col") {
-          text.setAttribute("x", padding.left + groupWidth * (index + 0.5))
-          text.setAttribute("y", svg.height.baseVal.value - padding.bottom + 20)
-          text.setAttribute("text-anchor", "middle")
-        } else {
-          text.setAttribute("x", padding.left - 10)
-          text.setAttribute("y", padding.top + groupWidth * (index + 0.5))
-          text.setAttribute("text-anchor", "end")
-          text.setAttribute("dominant-baseline", "middle")
-        }
-        text.setAttribute("font-size", "12px")
-        text.textContent = label
-        svg.appendChild(text)
-      })
-    },
-    // 绘制图例
-    drawLegend(svg, series, colors, padding) {
-      series.forEach((serie, index) => {
-        const legendX = padding.left + index * 100
-        const legendY = 20
-
-        const rect = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "rect"
-        )
-        rect.setAttribute("x", legendX)
-        rect.setAttribute("y", legendY)
-        rect.setAttribute("width", 15)
-        rect.setAttribute("height", 15)
-        rect.setAttribute(
-          "fill",
-          colors[index] || `hsl(${index * 60}, 70%, 50%)`
-        )
-        svg.appendChild(rect)
-
-        const text = document.createElementNS(
-          "http://www.w3.org/2000/svg",
-          "text"
-        )
-        text.setAttribute("x", legendX + 20)
-        text.setAttribute("y", legendY + 12)
-        text.setAttribute("font-size", "12px")
-        text.textContent = serie.key
-        svg.appendChild(text)
-      })
-    },
-    // 创建SmartArt图表元素
-    createDiagramElement(element) {
-      const el = document.createElement("div")
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.width = element.width + "px"
-      el.style.height = element.height + "px"
-      el.style.zIndex = element.order
-      // 递归渲染SmartArt节点
-      const renderDiagramNode = (node) => {
-        const nodeEl = document.createElement("div")
-        nodeEl.style.position = "absolute"
-        nodeEl.style.left = node.left + "px"
-        nodeEl.style.top = node.top + "px"
-        nodeEl.style.width = node.width + "px"
-        nodeEl.style.height = node.height + "px"
-
-        // 设置边框
-        if (node.borderWidth > 0) {
-          nodeEl.style.border = `${node.borderWidth}px ${node.borderType} ${node.borderColor}`
-          if (
-            node.borderStrokeDasharray &&
-            node.borderStrokeDasharray !== "0"
-          ) {
-            nodeEl.style.borderStyle = "dashed"
-          }
-        }
-
-        // 设置背景填充
-        if (node.fill && node.fill.type === "color") {
-          nodeEl.style.backgroundColor = node.fill.value
-        }
-
-        // 设置内容
-        if (node.content) {
-          nodeEl.innerHTML = this.convertPtToPxInContent(node.content)
-        }
-
-        // 设置垂直对齐
-        if (node.vAlign === "mid") {
-          nodeEl.style.display = "flex"
-          nodeEl.style.alignItems = "center"
-          nodeEl.style.justifyContent = "center"
-        }
-
-        // 设置翻转
-        const transforms = []
-        if (node.isFlipV) {
-          transforms.push("scaleY(-1)")
-        }
-        if (node.isFlipH) {
-          transforms.push("scaleX(-1)")
-        }
-        if (transforms.length > 0) {
-          nodeEl.style.transform = transforms.join(" ")
-        }
-
-        return nodeEl
-      }
-
-      // 按照 order 排序元素
-      const sortedElements = [...element.elements].sort(
-        (a, b) => a.order - b.order
-      )
-
-      // 渲染所有节点
-      sortedElements.forEach((node) => {
-        const nodeEl = renderDiagramNode(node)
-        el.appendChild(nodeEl)
-      })
-
-      return el
-    },
-    // 创建数学公式元素
-    createMathElement(element) {
-      const el = document.createElement("div")
-      el.style.position = "absolute"
-      el.style.top = element.top + "px"
-      el.style.left = element.left + "px"
-      el.style.width = element.width + "px"
-      el.style.height = element.height + "px"
-
-      // 如果有公式图片,优先使用图片显示
-      if (element.picBase64) {
-        const img = document.createElement("img")
-        img.src = element.picBase64
-        img.style.width = "100%"
-        img.style.height = "100%"
-        img.style.objectFit = "contain"
-        el.appendChild(img)
-        return el
-      }
-
-      // 如果有 LaTeX 表达式,使用 MathJax 渲染
-      if (element.latex) {
-        // 创建公式容器
-        const mathContainer = document.createElement("div")
-        mathContainer.style.width = "100%"
-        mathContainer.style.height = "100%"
-        mathContainer.style.display = "flex"
-        mathContainer.style.alignItems = "center"
-        mathContainer.style.justifyContent = "center"
-
-        // 添加 LaTeX 公式
-        mathContainer.innerHTML = `\\[${element.latex}\\]`
-
-        // 如果 MathJax 不可用,显示原始 LaTeX
-        mathContainer.style.fontFamily = "monospace"
-        mathContainer.style.whiteSpace = "pre-wrap"
-        mathContainer.style.padding = "10px"
-        mathContainer.textContent = element.latex
-
-        el.appendChild(mathContainer)
-      }
-
-      return el
-    },
-    // 创建文本元素
-    createTextElement(element) {
-      const el = document.createElement("div")
-      if (element.content) {
-        // 转换内容中的pt单位为px单位
-        const convertedContent = this.convertPtToPxInContent(element.content)
-        el.innerHTML = convertedContent
-
-        // 设置文本样式
-        el.style.width = element.width + "px"
-        el.style.height = element.height + "px"
-        el.style.color = element.fontColor || "#000"
-        el.style.fontSize = element.fontSize
-        el.style.fontFamily = element.fontFamily || "Arial"
-        el.style.textAlign = element.align || "left"
-        el.style.fontWeight = element.bold ? "bold" : "normal"
-        el.style.fontStyle = element.italic ? "italic" : "normal"
-        el.style.textDecoration = element.underline ? "underline" : "none"
-        el.style.position = "absolute"
-        el.style.top = element.top + "px" || "0"
-        el.style.left = element.left + "px" || "0"
-        el.style.zIndex = element.order
-        el.style.whiteSpace = "pre-wrap"
-
-        // 添加垂直对齐支持
-        el.style.display = "flex"
-        el.style.flexDirection = "column"
-        switch (element.vAlign) {
-          case "up":
-            el.style.justifyContent = "flex-start"
-            break
-          case "mid":
-            el.style.justifyContent = "center"
-            break
-          case "down":
-            el.style.justifyContent = "flex-end"
-            break
-          default:
-            el.style.justifyContent = "flex-start"
-        }
-
-        // 设置段落间距
-        el.style.lineHeight = element.lineHeight + "px" || "1.2"
-        el.style.letterSpacing = element.charSpacing
-          ? `${element.charSpacing}px`
-          : "normal"
-      }
-      return el
-    },
-    // 调整颜色明暗度
-    adjustBrightness(color, factor) {
-      if (color === "transparent") return color
-      const hex = color.replace("#", "")
-      const r = Math.min(
-        255,
-        Math.round(parseInt(hex.substr(0, 2), 16) * factor)
-      )
-      const g = Math.min(
-        255,
-        Math.round(parseInt(hex.substr(2, 2), 16) * factor)
-      )
-      const b = Math.min(
-        255,
-        Math.round(parseInt(hex.substr(4, 2), 16) * factor)
-      )
-      return `#${r.toString(16).padStart(2, "0")}${g
-        .toString(16)
-        .padStart(2, "0")}${b.toString(16).padStart(2, "0")}`
-    },
-    convertPtToPxInContent(content) {
-      if (!content) return content
-      // 使用正则表达式查找并替换
-      return content.replace(/(\d+\.?\d*)(pt|PT)/g, (match, size) => {
-        // 将 pt 转换为 px(1pt ≈ 1.33333px)
-        const pxSize = size
-        return `${pxSize}px`
-      })
-    },
-    processElements(elements, slideIndex) {
-      if (!elements || !Array.isArray(elements)) return
-
-      // 使用 Map 存储原始顺序,避免多次排序
-      const orderMap = new Map(
-        elements.map((el, index) => [el, el.order || index])
-      )
-
-      // 一次性排序
-      elements.sort((a, b) => orderMap.get(a) - orderMap.get(b))
-
-      const processElement = (element, baseOrder) => {
-        // 设置当前元素的 order
-        element.order = baseOrder
-
-        // 如果有子元素,递归处理
-        if (element.elements?.length > 0) {
-          element.elements
-            .sort((a, b) => (a.order || 0) - (b.order || 0))
-            .forEach((child, idx) => {
-              processElement(child, baseOrder * 10 + idx + 1)
-            })
-        }
-      }
-
-      // 处理每个顶层元素
-      elements.forEach((element, index) => {
-        processElement(element, (slideIndex + 1) * 10 + index + 1)
-      })
-    },
-  },
-}
-</script>
-<style scoped lang="less">
-.pptx-container {
-  width: 100%;
-  height: 100%;
-  z-index: 99;
-}
-</style>

+ 0 - 25
src/components/view_file/vendors/pptx/index.js

@@ -1,25 +0,0 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-09 10:49:05
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-24 11:49:34
- * @Description:
- */
-import Vue from "vue"
-import PPT from "./PPT.vue"
-import { parse } from "./libs/pptxToJson"
-/**
- * 渲染ppt
- */
-export default async function render(buffer, target) {
-  const pptxJson = await parse(buffer)
-  const el = new Vue({
-    render: (h) =>
-      h(PPT, {
-        props: {
-          pptxJson,
-        },
-      }),
-  }).$mount(target)
-  return el
-}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
src/components/view_file/vendors/pptx/libs/pptxToJson/index.js


+ 0 - 31
src/components/view_file/vendors/text/CodeViewer.vue

@@ -1,31 +0,0 @@
-<template>
-  <pre class="code-area">
-    {{ value }}
-  </pre>
-</template>
-
-<script>
-export default {
-  name: 'CodeEditor',
-  props: {
-    value: {
-      type: String,
-      description: '值'
-    }
-  }
-}
-</script>
-
-<style scoped>
-.code-area {
-  display: block;
-  margin: 0 auto;
-  font-size: 12px;
-  width: 1000px;
-  min-height: 500px;
-  background: #1f1f1f;
-  word-break: break-word;
-  white-space: break-spaces;
-  color: #5af117
-}
-</style>

+ 0 - 15
src/components/view_file/vendors/text/index.js

@@ -1,15 +0,0 @@
-import { readText } from '../../util'
-import Vue from 'vue'
-import CodeViewer from './CodeViewer'
-
-/**
- * 渲染文本
- * @param buffer 文本二进制内容
- * @param target 目标
- */
-export default async function renderText (buffer, target) {
-  const text = await readText(buffer)
-  return new Vue({
-    render: h => h(CodeViewer, { props: { value: text } })
-  }).$mount(target)
-}

+ 0 - 807
src/components/view_file/vendors/xlsx/Table.vue

@@ -1,807 +0,0 @@
-<template>
-  <div>
-    <div ref="spreadsheet" class="spreadsheet-container" id="spreadsheet"></div>
-  </div>
-</template>
-
-<script>
-import Spreadsheet from "x-data-spreadsheet"
-import { indexedColors } from "./color"
-import zhCN from "x-data-spreadsheet/dist/locale/zh-cn"
-import _ from "lodash-es"
-import tinycolor from "tinycolor2"
-Spreadsheet.locale("zh-cn", zhCN)
-
-export default {
-  name: "ExcelViewer",
-  props: {
-    workbook: Object,
-  },
-  data() {
-    return {
-      spreadsheet: null,
-      themeColors: [],
-    }
-  },
-  mounted() {
-    this.initSpreadsheet()
-  },
-  watch: {
-    workbook() {
-      this.parseTheme()
-      this.updateTable()
-    },
-  },
-  computed: {
-    sheets() {
-      if (this.workbook.worksheets) {
-        return this.workbook.worksheets.filter((sheet) => sheet._rows.length)
-      }
-      return []
-    },
-  },
-  methods: {
-    initSpreadsheet() {
-      // 优化性能配置
-      this.spreadsheet = new Spreadsheet(this.$refs.spreadsheet, {
-        view: {
-          height: () => document.documentElement.clientHeight - 120,
-          width: () => document.documentElement.clientWidth - 40,
-        },
-        mode: "read", // 只读模式
-        showToolbar: false,
-        showGrid: true,
-        showContextmenu: false, // 禁用右键菜单提高性能
-        multipleSheets: true,
-        rpx: 1, // 减少渲染计算
-        row: {
-          len: 100, // 限制初始行数
-          height: 25, // 固定行高
-          autoHeight: true,
-        },
-        col: {
-          len: 26, // 限制初始列数
-          width: 50, // 固定列宽
-          indexWidth: 60, // 行索引宽度
-          minWidth: 30, // 最小列宽
-          autoWidth: true, // 自动调整列宽
-        },
-        style: {
-          // 确保默认样式正确
-          bgcolor: "#ffffff",
-          color: "#333333",
-          align: "left",
-          valign: "middle",
-          textwrap: false,
-          strike: false,
-          underline: false,
-          italic: false,
-          bold: false,
-          fontSize: 12,
-        },
-      }).loadData({})
-
-      // 延迟加载数据,避免初始化时卡死
-      this.$nextTick(() => {
-        this.parseTheme()
-        this.updateSpreadsheet()
-      })
-    },
-    updateSpreadsheet() {
-      if (!this.spreadsheet) return
-      // 显示加载状态
-      this.$refs.spreadsheet.classList.add("loading")
-      try {
-        const data = this.convertWorksheetToData()
-        if (this.spreadsheet) {
-          this.$refs.spreadsheet.innerHTML = ""
-        }
-        // 重新创建实例
-        this.spreadsheet = new Spreadsheet(this.$refs.spreadsheet, {
-          view: {
-            height: () => document.documentElement.clientHeight - 120,
-            width: () => document.documentElement.clientWidth - 40,
-          },
-          mode: "read",
-          showToolbar: false,
-          showGrid: true,
-          showContextmenu: false,
-          multipleSheets: true,
-          rpx: 1,
-          row: {
-            len: 100,
-            height: 25,
-            autoHeight: true,
-          },
-          col: {
-            len: 26,
-            width: 50,
-            indexWidth: 60,
-            minWidth: 30,
-            autoWidth: true,
-          },
-        })
-          .loadData(data)
-      } finally {
-        this.$refs.spreadsheet.classList.remove("loading")
-      }
-    },
-
-    convertWorksheetToData() {
-      let data = []
-      this.sheets.forEach((sheet) => {
-        const sheetIndex = sheet.id
-        const sheetData = {
-          name: sheet._name,
-          freeze: "A1",
-          styles: [
-            {
-              bgcolor: "#ffffff",
-              color: "#000000",
-              align: "left",
-              valign: "middle",
-              fontSize: 12,
-            },
-          ],
-          merges: [],
-          rows: {},
-          cols: {},
-        }
-        try {
-          // 预处理合并单元格
-          this.processMerges(sheet, sheetData)
-          // 预处理样式缓存,避免重复创建相同样式
-          const styleCache = new Map()
-          // 处理单元格数据
-          this.processRows(sheet, sheetData, styleCache)
-          // 处理列宽
-          this.processColumns(sheet, sheetData)
-          data.push(sheetData)
-        } catch (error) {
-          data[sheetIndex] = {
-            name: sheet._name || "Sheet1",
-            rows: {},
-            cols: {},
-          }
-        }
-      })
-      return data
-    },
-
-    // 处理合并单元格
-    processMerges(sheet, sheetData) {
-      if (!sheet._merges) return
-
-      Object.values(sheet._merges).forEach((merge) => {
-        const { top, left, bottom, right } = merge
-          sheetData.merges.push(
-            `${this.columnIndexToLetter(
-              left - 1
-            )}${top}:${this.columnIndexToLetter(right - 1)}${bottom}`
-          )
-      })
-    },
-
-    // 处理行和单元格数据
-    processRows(sheet, sheetData, styleCache) {
-      // 增加最大行数限制,确保所有行都能显示
-      const maxRows = Math.min(sheet.rowCount || 50, 100)
-
-      // 预处理所有行,确保即使空行也能被处理
-      for (let rowIndex = 0; rowIndex < maxRows; rowIndex++) {
-        const row = sheet.getRow(rowIndex + 1)
-
-        // 初始化行数据和行高
-        let maxHeight = 25 // 最小行高
-        sheetData.rows[rowIndex] = {
-          cells: {},
-          height: maxHeight,
-        }
-
-        // 如果行不存在,创建一个空行
-        if (!row || !row.cellCount) {
-          continue
-        }
-
-        // 处理行中的单元格
-        // 使用列数而不是cellCount,确保处理所有可能的单元格
-        const maxCols = Math.min(sheet.columnCount || 26, 100)
-        for (let colIndex = 0; colIndex < maxCols; colIndex++) {
-          try {
-            const cell = row.getCell(colIndex + 1)
-            if (!cell || (cell.type === "null" && !cell.style)) {
-              // 对于空单元格,添加一个默认样式的空单元格
-              sheetData.rows[rowIndex].cells[colIndex] = {
-                text: "",
-                style: 0,
-              }
-              continue
-            }
-
-            // 获取单元格文本和样式
-            const { text: cellText, height: cellHeight } =
-              this.getCellTextAndHeight(cell)
-            const styleIndex = this.getCellStyle(
-              cell,
-              styleCache,
-              sheetData.styles
-            )
-
-            // 更新行高
-            maxHeight = Math.max(maxHeight, cellHeight)
-
-            // 检查是否是合并单元格的起始单元格
-            const mergeInfo = Object.values(sheet._merges || {}).find(
-              (m) => m.top === row.number && m.left === colIndex + 1
-            )
-
-            // 设置单元格数据
-            if (mergeInfo) {
-              sheetData.rows[rowIndex].cells[colIndex] = {
-                text: cellText,
-                style: styleIndex,
-                merge: [
-                  mergeInfo.bottom - mergeInfo.top,
-                  mergeInfo.right - mergeInfo.left,
-                ],
-              }
-            } else {
-              sheetData.rows[rowIndex].cells[colIndex] = {
-                text: cellText,
-                style: styleIndex,
-              }
-            }
-          } catch (error) {
-
-            sheetData.rows[rowIndex].cells[colIndex] = {
-              text: "",
-              style: 0,
-            }
-          }
-        }
-
-        // 更新行高
-        sheetData.rows[rowIndex].height = maxHeight
-      }
-    },
-
-    // 获取单元格文本和计算高度
-    getCellTextAndHeight(cell) {
-      let cellText = ""
-      try {
-        // 处理不同类型的单元格内容
-        if (!cell || cell.value === null || cell.value === undefined) {
-          cellText = ""
-        } else if (
-          cell.type === "date" ||
-          (cell.numFmt &&
-            (cell.numFmt.includes("yy") ||
-              cell.numFmt.includes("mm") ||
-              cell.numFmt.includes("dd") ||
-              cell.numFmt.includes("h") ||
-              cell.numFmt.includes("m:s")))
-        ) {
-          // 处理日期类型或带有日期格式的数字
-          try {
-            // 检查是否为日期值
-            let date
-            if (cell.value instanceof Date) {
-              date = cell.value
-            } else if (typeof cell.value === "number") {
-              // Excel日期是从1900年1月1日开始的天数
-              // 需要转换为JavaScript日期
-              const excelEpoch = new Date(1899, 11, 30) // Excel的起始日期
-              date = new Date(
-                excelEpoch.getTime() + cell.value * 24 * 60 * 60 * 1000
-              )
-            } else {
-              date = new Date(cell.value)
-            }
-
-            if (!isNaN(date.getTime())) {
-              // 格式化日期
-              const year = date.getFullYear()
-              const month = (date.getMonth() + 1).toString().padStart(2, "0")
-              const day = date.getDate().toString().padStart(2, "0")
-
-              // 检查是否需要显示时间
-              if (
-                cell.numFmt &&
-                (cell.numFmt.includes("h") || cell.numFmt.includes("s"))
-              ) {
-                const hour = date.getHours().toString().padStart(2, "0")
-                const minute = date.getMinutes().toString().padStart(2, "0")
-                const second = date.getSeconds().toString().padStart(2, "0")
-                cellText = `${year}/${month}/${day} ${hour}:${minute}:${second}`
-              } else {
-                cellText = `${year}/${month}/${day}`
-              }
-            } else {
-              // 如果不是有效日期,使用原始文本
-              cellText = String(cell.text || cell.value || "")
-            }
-          } catch (e) {
-        
-            cellText = String(cell.text || cell.value || "")
-          }
-        } else if (typeof cell.value === "object" && cell.value !== null) {
-          if (cell.value.hyperlink) {
-            cellText = "[链接]"
-          } else if (cell.value.image) {
-            cellText = "[图片]"
-          } else if (cell.value.richText) {
-            cellText = cell.value.richText
-              .map((t) => String(t?.text || ""))
-              .join("")
-          } else {
-            cellText = String(cell.text || "")
-          }
-        } else if (cell.formula) {
-          // 检查公式结果是否可能是日期
-          if (
-            cell.numFmt &&
-            (cell.numFmt.includes("yy") ||
-              cell.numFmt.includes("mm") ||
-              cell.numFmt.includes("dd"))
-          ) {
-            try {
-              // 尝试将结果转换为日期
-              const excelEpoch = new Date(1899, 11, 30)
-              const date = new Date(
-                excelEpoch.getTime() + cell.result * 24 * 60 * 60 * 1000
-              )
-
-              if (!isNaN(date.getTime())) {
-                const year = date.getFullYear()
-                const month = (date.getMonth() + 1).toString().padStart(2, "0")
-                const day = date.getDate().toString().padStart(2, "0")
-                cellText = `${year}-${month}-${day}`
-              } else {
-                cellText = String(cell.result || cell.value || "")
-              }
-            } catch (e) {
-              cellText = String(cell.result || cell.value || "")
-            }
-          } else {
-            cellText =
-              cell.result !== undefined && cell.result !== null
-                ? String(cell.result)
-                : String(cell.value || "")
-          }
-        } else {
-          cellText =
-            cell.text !== undefined && cell.text !== null
-              ? String(cell.text)
-              : cell.value !== undefined && cell.value !== null
-              ? String(cell.value)
-              : ""
-        }
-      } catch (e) {
-  
-        cellText = "[格式错误]"
-      }
-
-      // 计算行高
-      const lineBreaks = ((cellText || "").match(/\n/g) || []).length + 1
-      const chars = [...(cellText || "")]
-      const lines = Math.ceil(chars.length / 40)
-      const neededHeight = Math.max(lineBreaks, lines) * 20
-
-      return { text: cellText, height: neededHeight }
-    },
-
-    // 获取单元格样式
-    getCellStyle(cell, styleCache, styles) {
-      // 创建样式对象
-      const cellStyle = {
-        bgcolor: "#ffffff",
-        color: "#000000",
-        align: cell.alignment?.horizontal || "left",
-        valign: cell.alignment?.vertical || "middle",
-        fontSize: cell.font?.size || 12,
-        textwrap: true,
-        bold: cell.font?.bold,
-        italic: cell.font?.italic,
-        underline: false,
-        strike: false,
-      }
-
-      // 处理背景色
-      if (cell.fill && cell.fill.type === "pattern") {
-        const fgColor = cell.fill.fgColor || {}
-
-        // 处理索引颜色
-        if (typeof fgColor.indexed === "number") {
-          const indexedColor = indexedColors[fgColor.indexed]
-          if (indexedColor) {
-            cellStyle.bgcolor = `#${indexedColor}`
-          }
-        }
-        // 处理主题颜色
-        else if (typeof fgColor.theme === "number") {
-          // Excel主题颜色索引映射
-          const themeColorMap = {
-            0: 1, // 浅色1
-            1: 0, // 深色1
-            2: 3, // 浅色2
-            3: 2, // 深色2
-            4: 4, // 强调色1
-            5: 5, // 强调色2
-            6: 6, // 强调色3
-            7: 7, // 强调色4
-            8: 8, // 强调色5
-            9: 9, // 强调色6
-          }
-
-          const mappedIndex =
-            themeColorMap[fgColor.theme] !== undefined
-              ? themeColorMap[fgColor.theme]
-              : fgColor.theme
-
-          if (this.themeColors[mappedIndex]) {
-            let color = `#${this.themeColors[mappedIndex]}`
-
-            // 应用色调调整
-            if (typeof fgColor.tint === "number" && fgColor.tint !== 0) {
-              color = this.applyTint(color, fgColor.tint)
-            }
-
-            cellStyle.bgcolor = color
-          }
-        }
-        // 处理RGB颜色
-        else if (fgColor.rgb) {
-          cellStyle.bgcolor = `#${fgColor.rgb.substring(
-            fgColor.rgb.length - 6
-          )}`
-        }
-        // 处理ARGB颜色
-        else if (fgColor.argb) {
-          const color = this.convertArgbToHex(fgColor.argb)
-          if (color) cellStyle.bgcolor = color
-        }
-      }
-
-      // 处理字体颜色
-      if (cell.font && cell.font.color) {
-        const fontColor = cell.font.color
-
-        // 处理索引颜色
-        if (typeof fontColor.indexed === "number") {
-          const indexedColor = indexedColors[fontColor.indexed]
-          if (indexedColor) {
-            cellStyle.color = `#${indexedColor}`
-          }
-        }
-        // 处理主题颜色
-        else if (typeof fontColor.theme === "number") {
-          // Excel主题颜色索引映射
-          const themeColorMap = {
-            0: 1, // 浅色1
-            1: 0, // 深色1
-            2: 3, // 浅色2
-            3: 2, // 深色2
-            4: 4, // 强调色1
-            5: 5, // 强调色2
-            6: 6, // 强调色3
-            7: 7, // 强调色4
-            8: 8, // 强调色5
-            9: 9, // 强调色6
-          }
-
-          const mappedIndex =
-            themeColorMap[fontColor.theme] !== undefined
-              ? themeColorMap[fontColor.theme]
-              : fontColor.theme
-
-          if (this.themeColors[mappedIndex]) {
-            let color = `#${this.themeColors[mappedIndex]}`
-
-            // 应用色调调整
-            if (typeof fontColor.tint === "number" && fontColor.tint !== 0) {
-              color = this.applyTint(color, fontColor.tint)
-            }
-
-            cellStyle.color = color
-          }
-        }
-        // 处理RGB颜色
-        else if (fontColor.rgb) {
-          cellStyle.color = `#${fontColor.rgb.substring(
-            fontColor.rgb.length - 6
-          )}`
-        }
-        // 处理ARGB颜色
-        else if (fontColor.argb) {
-          const color = this.convertArgbToHex(fontColor.argb)
-          if (color) cellStyle.color = color
-        }
-      }
-
-      // 使用样式缓存避免重复
-      const styleKey = JSON.stringify(cellStyle)
-      if (styleCache.has(styleKey)) {
-        return styleCache.get(styleKey)
-      }
-
-      // 添加新样式
-      styles.push(cellStyle)
-      const styleIndex = styles.length - 1
-      styleCache.set(styleKey, styleIndex)
-
-      return styleIndex
-    },
-    applyTint(hexColor, tint) {
-      try {
-        // 将十六进制颜色转换为RGB
-        const color = tinycolor(hexColor)
-        const rgb = color.toRgb()
-
-        // 根据Excel的色调算法调整颜色
-        const adjustColor = (value, tint) => {
-          let result
-          if (tint < 0) {
-            // 负色调值,使颜色变暗
-            result = value * (1 + tint)
-          } else {
-            // 正色调值,使颜色变亮
-            result = value + (255 - value) * tint
-          }
-          return Math.max(0, Math.min(255, Math.round(result)))
-        }
-
-        // 应用色调到每个RGB通道
-        const r = adjustColor(rgb.r, tint)
-        const g = adjustColor(rgb.g, tint)
-        const b = adjustColor(rgb.b, tint)
-
-        // 返回调整后的颜色
-        return tinycolor({ r, g, b }).toHexString()
-      } catch (e) {
-      
-        return hexColor
-      }
-    },
-
-    // 处理列宽
-    processColumns(sheet, sheetData) {
-      const maxCols = Math.min(sheet.columnCount || 26, 50)
-      const colWidthCache = new Map()
-      const mergedCols = new Set()
-      // 收集合并单元格信息
-      if (sheet._merges) {
-        Object.values(sheet._merges).forEach((merge) => {
-          // 记录被合并的列
-          for (let col = merge.left; col <= merge.right; col++) {
-            mergedCols.add(col - 1)
-          }
-        })
-      }
-      // 先收集所有单元格的文本宽度
-      sheet.eachRow((row) => {
-        for (let colIndex = 0; colIndex < maxCols; colIndex++) {
-          try {
-            const cell = row.getCell(colIndex + 1)
-            if (!cell) continue
-            // 安全获取单元格文本
-            let cellText = ""
-            try {
-              if (cell.text !== undefined && cell.text !== null) {
-                cellText = String(cell.text)
-              } else if (cell.value !== undefined && cell.value !== null) {
-                if (typeof cell.value === "object") {
-                  cellText = cell.value?.richText
-                    ? cell.value.richText
-                        .map((t) => String(t?.text || ""))
-                        .join("")
-                    : cell.value?.hyperlink
-                    ? "[链接]"
-                    : cell.value?.image
-                    ? "[图片]"
-                    : ""
-                } else {
-                  cellText = String(cell.value)
-                }
-              }
-            } catch (e) {
-              cellText = ""
-            }
-            // 计算文本宽度
-            if (cellText) {
-              // 检查是否是合并单元格的一部分
-              const isMerged = Object.values(sheet._merges || {}).some(
-                (merge) =>
-                  row.number >= merge.top &&
-                  row.number <= merge.bottom &&
-                  colIndex + 1 >= merge.left &&
-                  colIndex + 1 <= merge.right
-              )
-              // 如果是合并单元格,根据合并的列数调整宽度计算
-              if (isMerged) {
-                const merge = Object.values(sheet._merges || {}).find(
-                  (m) =>
-                    row.number >= m.top &&
-                    row.number <= m.bottom &&
-                    colIndex + 1 >= m.left &&
-                    colIndex + 1 <= m.right
-                )
-                if (merge && colIndex + 1 === merge.left) {
-                  // 只为合并单元格的第一列计算宽度
-                  const mergeWidth = merge.right - merge.left + 1
-                  const textWidth = [...cellText].reduce((width, char) => {
-                    return width + (/[\u4e00-\u9fa5]/.test(char) ? 2 : 1)
-                  }, 0)
-                  // 平均分配到每一列
-                  const avgWidth = Math.ceil(textWidth / mergeWidth)
-                  colWidthCache.set(
-                    colIndex,
-                    Math.max(colWidthCache.get(colIndex) || 0, avgWidth)
-                  )
-                }
-              } else {
-                // 普通单元格
-                const textWidth = [...cellText].reduce((width, char) => {
-                  return width + (/[\u4e00-\u9fa5]/.test(char) ? 2 : 1)
-                }, 0)
-
-                colWidthCache.set(
-                  colIndex,
-                  Math.max(colWidthCache.get(colIndex) || 0, textWidth)
-                )
-              }
-            }
-          } catch (e) {
-            // 忽略错误
-          }
-        }
-      })
-
-      // 设置列宽
-      for (let colIndex = 0; colIndex < maxCols; colIndex++) {
-        let maxWidth = colWidthCache.get(colIndex) || 0
-        // 对于合并单元格的列,限制最大宽度
-        if (mergedCols.has(colIndex)) {
-          maxWidth = Math.min(maxWidth, 30) // 限制合并列的宽度
-        }
-        // 设置合理的列宽范围
-        const width = Math.max(40, Math.min(300, maxWidth * 9))
-        sheetData.cols[colIndex] = {
-          width: width,
-        }
-      }
-    },
-    // ARGB 转 Hex 颜色方法
-    convertArgbToHex(argb) {
-      if (!argb) return null
-      try {
-        const matches =
-          /^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(argb)
-        if (!matches) return null
-        return `#${matches[2]}${matches[3]}${matches[4]}`
-      } catch (e) {
-     
-        return null
-      }
-    },
-    columnIndexToLetter(index) {
-      let temp
-      let letter = ""
-      // 修复列索引转字母的算法
-      if (index < 0) return ""
-      do {
-        temp = index % 26
-        letter = String.fromCharCode(temp + 65) + letter
-        index = Math.floor(index / 26) - 1
-      } while (index >= 0)
-      return letter
-    },
-    parseTheme() {
-      const theme = this.workbook._themes?.theme1
-      if (!theme) {
-        // Office默认主题颜色
-        this.themeColors = [
-          "FFFFFF", // 白色 - 浅色1
-          "000000", // 黑色 - 深色1
-          "EEECE1", // 浅灰 - 浅色2
-          "1F497D", // 深灰 - 深色2
-          "4F81BD", // 蓝色 - 强调色1
-          "C0504D", // 红色 - 强调色2
-          "9BBB59", // 绿色 - 强调色3
-          "8064A2", // 紫色 - 强调色4
-          "4BACC6", // 青色 - 强调色5
-          "F79646", // 橙色 - 强调色6
-        ]
-        return
-      }
-      try {
-        const parser = new DOMParser()
-        const doc = parser.parseFromString(theme, "text/xml")
-        // 获取颜色方案元素
-        const clrScheme = doc.getElementsByTagName("a:clrScheme")[0]
-        if (!clrScheme) {
-          throw new Error("找不到颜色方案元素")
-        }
-        // 初始化主题颜色数组
-        this.themeColors = []
-        const colorElements = Array.from(clrScheme.children)
-        // 处理每个颜色元素
-        for (const element of colorElements) {
-          let colorValue = null
-          // 查找颜色定义元素
-          const srgbClr = element.getElementsByTagName("a:srgbClr")[0]
-          const sysClr = element.getElementsByTagName("a:sysClr")[0]
-          if (srgbClr) {
-            colorValue = srgbClr.getAttribute("val")
-          } else if (sysClr) {
-            colorValue =
-              sysClr.getAttribute("lastClr") || sysClr.getAttribute("val")
-          }
-          this.themeColors.push(colorValue || "FFFFFF")
-        }
-      } catch (error) {
-      
-        this.themeColors = [
-          "FFFFFF", // 白色 - 浅色1
-          "000000", // 黑色 - 深色1
-          "EEECE1", // 浅灰 - 浅色2
-          "1F497D", // 深灰 - 深色2
-          "4F81BD", // 蓝色 - 强调色1
-          "C0504D", // 红色 - 强调色2
-          "9BBB59", // 绿色 - 强调色3
-          "8064A2", // 紫色 - 强调色4
-          "4BACC6", // 青色 - 强调色5
-          "F79646", // 橙色 - 强调色6
-        ]
-      }
-    },
-  },
-}
-</script>
-
-<style scoped>
-.spreadsheet-container {
-  width: 100%;
-  height: calc(100vh - 120px);
-  position: relative;
-}
-
-.spreadsheet-container.loading::after {
-  content: "加载中...";
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(255, 255, 255, 0.7);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 18px;
-  z-index: 1000;
-}
-
-.sheet-btn {
-  border: 1px solid #ccc;
-  background-color: #f0f0f0;
-  cursor: pointer;
-  margin-right: 5px;
-  border-radius: 4px;
-  padding: 5px 15px;
-}
-
-.sheet-btn.active {
-  background-color: #4caf50;
-  color: white;
-  border-color: #388e3c;
-}
-
-.btn-group {
-  margin-bottom: 10px;
-  display: flex;
-  flex-wrap: wrap;
-  gap: 5px;
-  padding: 8px;
-  background-color: #f8f8f8;
-  border-radius: 4px;
-}
-</style>

+ 0 - 69
src/components/view_file/vendors/xlsx/color.js

@@ -1,69 +0,0 @@
-
-export const indexedColors = [
-  '000000',
-  'FFFFFF',
-  'FF0000',
-  '00FF00',
-  '0000FF',
-  'FFFF00',
-  'FF00FF',
-  '00FFFF',
-  '000000',
-  'FFFFFF',
-  'FF0000',
-  '00FF00',
-  '0000FF',
-  'FFFF00',
-  'FF00FF',
-  '00FFFF',
-  '800000',
-  '008000',
-  '000080',
-  '808000',
-  '800080',
-  '008080',
-  'C0C0C0',
-  '808080',
-  '9999FF',
-  '993366',
-  'FFFFCC',
-  'CCFFFF',
-  '660066',
-  'FF8080',
-  '0066CC',
-  'CCCCFF',
-  '000080',
-  'FF00FF',
-  'FFFF00',
-  '00FFFF',
-  '800080',
-  '800000',
-  '008080',
-  '0000FF',
-  '00CCFF',
-  'CCFFFF',
-  'CCFFCC',
-  'FFFF99',
-  '99CCFF',
-  'FF99CC',
-  'CC99FF',
-  'FFCC99',
-  '3366FF',
-  '33CCCC',
-  '99CC00',
-  'FFCC00',
-  'FF9900',
-  'FF6600',
-  '666699',
-  '969696',
-  '003366',
-  '339966',
-  '003300',
-  '333300',
-  '993300',
-  '993366',
-  '333399',
-  '333333',
-  'b7e0ff',
-  '00CCFF'
-]

+ 0 - 27
src/components/view_file/vendors/xlsx/index.js

@@ -1,27 +0,0 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-09 10:49:05
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 17:45:30
- * @Description:
- */
-import ExcelJS from 'exceljs'
-import Vue from 'vue'
-import Table from './Table.vue'
-import 'x-data-spreadsheet/dist/xspreadsheet.css'
-
-/**
- * 渲染excel
- */
-export default async function render (buffer, target) {
-  const workbook = await new ExcelJS.Workbook().xlsx.load(buffer)
-  const el = new Vue({
-    render: (h) =>
-      h(Table, {
-        props: {
-          workbook
-        }
-      })
-  }).$mount(target)
-  return el
-}

+ 0 - 49
src/components/view_file/vendors/xlsx/util.js

@@ -1,49 +0,0 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-09 10:49:05
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-14 17:30:04
- * @Description:
- */
-// 深度扁平化routes
-export function flatten (routes) {
-  return routes.flatMap((route) =>
-    route.children ? [route, ...flatten(route.children)] : [route]
-  )
-}
-
-// 转化style对象为style字符串
-export function toStyleString (style) {
-  return [...style].map((key) => `${key}: ${style[key]}`).join(';')
-}
-
-// 修复矩阵的宽度
-export function fixMatrix (data, colLen) {
-  for (const row of data) {
-    for (let j = 0; j < colLen; j++) {
-      if (!row[j]) {
-        row[j] = ''
-      }
-    }
-  }
-  return data
-}
-
-// 首字母大写
-export function captain (str) {
-  return `${str.charAt(0).toUpperCase()}${str.slice(1)}`
-}
-
-// 连字符转驼峰
-export function camelCase (str) {
-  return str
-    .split('-')
-    .map((part, index) => {
-      if (index !== 0) {
-        return captain(part)
-      } else {
-        return part
-      }
-    })
-    .join('')
-}

+ 0 - 61
src/config/index.ts

@@ -1,61 +0,0 @@
-/*
- * @Author: WangQiBiao
- * @LastEditors: ChenYaJin
- * @Description: 全局参数设置
- * @Date: 2019-03-12 09:40:46
- * @LastEditTime: 2023-07-03 17:11:00
- */
-import { Config } from '#/config'
-
-const REQUEST_MATCHING_HASH = `/9ad134a361f8d778` // 【9ad134a361f8d778 = 前端服务,用于后端接口匹配】
-
-const config: Config = {
-/**
-     * @description token在Cookie中存储的天数,默认1天
-     */
-  cookieExpires: 1,
-  /**
-     * @description 是否使用国际化,默认为false
-     *              如果不使用,则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'}
-     *              用来在菜单中显示文字
-     */
-  useI18n: false,
-  /**
-     * @description api请求基础路径
-     */
-  baseUrl: {
-    pro: `${REQUEST_MATCHING_HASH}`, // 生产环境
-    test: `${REQUEST_MATCHING_HASH}` // 测试环境
-  },
-  // 图片路径
-  fileUrl: process.env.NODE_ENV === 'production' ? `${REQUEST_MATCHING_HASH}` : 'https://wy-test.huiguanjia.cn/9ad134a361f8d778',
-  // 上传图片路径
-  uploadFileUrl: process.env.NODE_ENV === 'production' ? `https://wy.huiguanjia.cn${REQUEST_MATCHING_HASH}` : 'https://wy-test.huiguanjia.cn/9ad134a361f8d778',
-  // 导出文件路径
-  exportUrl: process.env.NODE_ENV === 'production' ? `${REQUEST_MATCHING_HASH}` : '/api',
-  // 分享绘服务路径
-  shareUrl: process.env.NODE_ENV === 'production' ? 'https://m.huifuwu.cn' : 'http://pm-test.huiguanjia.cn', // https://m.huifuwu.cn
-  huiFuWuQrCodeUrl: 'https://m.huifuwu.cn',
-  /**
-     * 输入框最长值
-     */
-  maxTextNum: 20,
-  /**
-   * 版本tag
-   */
-  version: 'v2.5.9',
-  /**
-   * 钉钉消息通知
-   */
-  dingDingNotice: process.env.NODE_ENV === 'production' ? `${REQUEST_MATCHING_HASH}/risk/ding/front/chat/send` : '/api/risk/ding/front/chat/send',
-  /**
-   * 百度地图 ak
-   */
-  mapKey: process.env.NODE_ENV === 'production' ? '11hnWXWWGgQnCHVzL2RrILKjNbd4iSR9' : 'Grz9EBWKpYvTU4YesHQH5vcQ6f6gxpC2',
-  /**
-   * PDFjs 字体文件 cdn
-   */
-  PDFCmapURL: '/bcmaps/'
-}
-
-export default config

+ 9 - 16
src/main.ts

@@ -1,21 +1,14 @@
 /*
  * @Author: LiZhiWei
- * @Date: 2025-04-09 09:06:37
+ * @Date: 2025-04-24 15:20:36
  * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 16:35:19
- * @Description:
+ * @LastEditTime: 2025-04-24 15:24:44
+ * @Description: 
  */
-import Vue from "vue"
-import router from "./router"
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
 
-import ElementUI from "element-ui"
-import "element-ui/lib/theme-chalk/index.css"
-import App from "./App.vue"
-
-Vue.use(ElementUI, { size: "small" })
-
-new Vue({
-  el: "#app",
-  router,
-  render: (h) => h(App),
-})
+const app = createApp(App)
+app.use(router)
+app.mount('#app')

+ 11 - 13
src/router/index.ts

@@ -1,25 +1,23 @@
 /*
  * @Author: LiZhiWei
- * @Date: 2025-04-23 09:33:35
+ * @Date: 2025-04-24 15:24:52
  * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-23 17:29:01
- * @Description:
+ * @LastEditTime: 2025-04-24 15:26:11
+ * @Description: 
  */
-import Vue from "vue"
-import VueRouter from "vue-router"
-
-Vue.use(VueRouter)
+import { createRouter, createWebHistory } from 'vue-router'
 
 const routes = [
   {
-    path: "/",
-    name: "home",
-    component: () => import("@/views/index.vue"),
+    path: '/',
+    name: 'Home',
+    component: () => import('../views/index.vue')
   },
 ]
 
-const router = new VueRouter({
-  routes,
+const router = createRouter({
+  history: createWebHistory(),
+  routes
 })
 
-export default router
+export default router

+ 0 - 63
src/utils/pptxToJson/align.js

@@ -1,63 +0,0 @@
-import { getTextByPathList } from './utils'
-
-export function getHorizontalAlign (node, pNode, type, warpObj) {
-  let algn = getTextByPathList(node, ['a:pPr', 'attrs', 'algn'])
-  if (!algn) algn = getTextByPathList(pNode, ['a:pPr', 'attrs', 'algn'])
-
-  if (!algn) {
-    if (type === 'title' || type === 'ctrTitle' || type === 'subTitle') {
-      let lvlIdx = 1
-      const lvlNode = getTextByPathList(pNode, ['a:pPr', 'attrs', 'lvl'])
-      if (lvlNode) {
-        lvlIdx = parseInt(lvlNode) + 1
-      }
-      const lvlStr = 'a:lvl' + lvlIdx + 'pPr'
-      algn = getTextByPathList(warpObj, ['slideLayoutTables', 'typeTable', type, 'p:txBody', 'a:lstStyle', lvlStr, 'attrs', 'algn'])
-      if (!algn) algn = getTextByPathList(warpObj, ['slideMasterTables', 'typeTable', type, 'p:txBody', 'a:lstStyle', lvlStr, 'attrs', 'algn'])
-      if (!algn) algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:titleStyle', lvlStr, 'attrs', 'algn'])
-      if (!algn && type === 'subTitle') {
-        algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:bodyStyle', lvlStr, 'attrs', 'algn'])
-      }
-    } else if (type === 'body') {
-      algn = getTextByPathList(warpObj, ['slideMasterTextStyles', 'p:bodyStyle', 'a:lvl1pPr', 'attrs', 'algn'])
-    } else {
-      algn = getTextByPathList(warpObj, ['slideMasterTables', 'typeTable', type, 'p:txBody', 'a:lstStyle', 'a:lvl1pPr', 'attrs', 'algn'])
-    }
-  }
-
-  let align = 'left'
-  if (algn) {
-    switch (algn) {
-      case 'l':
-        align = 'left'
-        break
-      case 'r':
-        align = 'right'
-        break
-      case 'ctr':
-        align = 'center'
-        break
-      case 'just':
-        align = 'justify'
-        break
-      case 'dist':
-        align = 'justify'
-        break
-      default:
-        align = 'inherit'
-    }
-  }
-  return align
-}
-
-export function getVerticalAlign (node, slideLayoutSpNode, slideMasterSpNode) {
-  let anchor = getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
-  if (!anchor) {
-    anchor = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
-    if (!anchor) {
-      anchor = getTextByPathList(slideMasterSpNode, ['p:txBody', 'a:bodyPr', 'attrs', 'anchor'])
-      if (!anchor) anchor = 't'
-    }
-  }
-  return (anchor === 'ctr') ? 'mid' : ((anchor === 'b') ? 'down' : 'up')
-}

+ 0 - 105
src/utils/pptxToJson/border.js

@@ -1,105 +0,0 @@
-import tinycolor from 'tinycolor2'
-import { getSchemeColorFromTheme } from './schemeColor'
-import { getTextByPathList } from './utils'
-
-export function getBorder (node, elType, warpObj) {
-  let lineNode = getTextByPathList(node, ['p:spPr', 'a:ln'])
-  if (!lineNode) {
-    const lnRefNode = getTextByPathList(node, ['p:style', 'a:lnRef'])
-    if (lnRefNode) {
-      const lnIdx = getTextByPathList(lnRefNode, ['attrs', 'idx'])
-      lineNode = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:lnStyleLst']['a:ln'][Number(lnIdx) - 1]
-    }
-  }
-  if (!lineNode) lineNode = node
-
-  const isNoFill = getTextByPathList(lineNode, ['a:noFill'])
-
-  let borderWidth = isNoFill ? 0 : (parseInt(getTextByPathList(lineNode, ['attrs', 'w'])) / 12700)
-  if (isNaN(borderWidth)) {
-    if (lineNode) borderWidth = 0
-    else if (elType !== 'obj') borderWidth = 0
-    else borderWidth = 1
-  }
-
-  let borderColor = getTextByPathList(lineNode, ['a:solidFill', 'a:srgbClr', 'attrs', 'val'])
-  if (!borderColor) {
-    const schemeClrNode = getTextByPathList(lineNode, ['a:solidFill', 'a:schemeClr'])
-    const schemeClr = 'a:' + getTextByPathList(schemeClrNode, ['attrs', 'val'])
-    borderColor = getSchemeColorFromTheme(schemeClr, warpObj)
-  }
-
-  if (!borderColor) {
-    const schemeClrNode = getTextByPathList(node, ['p:style', 'a:lnRef', 'a:schemeClr'])
-    const schemeClr = 'a:' + getTextByPathList(schemeClrNode, ['attrs', 'val'])
-    borderColor = getSchemeColorFromTheme(schemeClr, warpObj)
-
-    if (borderColor) {
-      let shade = getTextByPathList(schemeClrNode, ['a:shade', 'attrs', 'val'])
-
-      if (shade) {
-        shade = parseInt(shade) / 100000
-
-        const color = tinycolor('#' + borderColor).toHsl()
-        borderColor = tinycolor({ h: color.h, s: color.s, l: color.l * shade, a: color.a }).toHex()
-      }
-    }
-  }
-
-  if (!borderColor) borderColor = '#000000'
-  else borderColor = `#${borderColor}`
-
-  const type = getTextByPathList(lineNode, ['a:prstDash', 'attrs', 'val'])
-  let borderType = 'solid'
-  let strokeDasharray = '0'
-  switch (type) {
-    case 'solid':
-      borderType = 'solid'
-      strokeDasharray = '0'
-      break
-    case 'dash':
-      borderType = 'dashed'
-      strokeDasharray = '5'
-      break
-    case 'dashDot':
-      borderType = 'dashed'
-      strokeDasharray = '5, 5, 1, 5'
-      break
-    case 'dot':
-      borderType = 'dotted'
-      strokeDasharray = '1, 5'
-      break
-    case 'lgDash':
-      borderType = 'dashed'
-      strokeDasharray = '10, 5'
-      break
-    case 'lgDashDotDot':
-      borderType = 'dotted'
-      strokeDasharray = '10, 5, 1, 5, 1, 5'
-      break
-    case 'sysDash':
-      borderType = 'dashed'
-      strokeDasharray = '5, 2'
-      break
-    case 'sysDashDot':
-      borderType = 'dotted'
-      strokeDasharray = '5, 2, 1, 5'
-      break
-    case 'sysDashDotDot':
-      borderType = 'dotted'
-      strokeDasharray = '5, 2, 1, 5, 1, 5'
-      break
-    case 'sysDot':
-      borderType = 'dotted'
-      strokeDasharray = '2, 5'
-      break
-    default:
-  }
-
-  return {
-    borderColor,
-    borderWidth,
-    borderType,
-    strokeDasharray
-  }
-}

+ 0 - 210
src/utils/pptxToJson/chart.js

@@ -1,210 +0,0 @@
-import { eachElement, getTextByPathList } from './utils'
-import { applyTint } from './color'
-
-function extractChartColors (serNode, warpObj) {
-  if (serNode.constructor !== Array) serNode = [serNode]
-  const schemeClrs = []
-  for (const node of serNode) {
-    let schemeClr = getTextByPathList(node, ['c:spPr', 'a:solidFill', 'a:schemeClr'])
-    if (!schemeClr) schemeClr = getTextByPathList(node, ['c:spPr', 'a:ln', 'a:solidFill', 'a:schemeClr'])
-    if (!schemeClr) schemeClr = getTextByPathList(node, ['c:marker', 'c:spPr', 'a:ln', 'a:solidFill', 'a:schemeClr'])
-
-    let clr = getTextByPathList(schemeClr, ['attrs', 'val'])
-    if (clr) {
-      clr = getTextByPathList(warpObj['themeContent'], ['a:theme', 'a:themeElements', 'a:clrScheme', `a:${clr}`, 'a:srgbClr', 'attrs', 'val'])
-      const tint = getTextByPathList(schemeClr, ['a:tint', 'attrs', 'val']) / 100000
-      if (clr && !isNaN(tint)) {
-        clr = applyTint(clr, tint)
-      }
-    } else clr = getTextByPathList(node, ['c:spPr', 'a:solidFill', 'a:srgbClr', 'attrs', 'val'])
-
-    if (clr) clr = '#' + clr
-    schemeClrs.push(clr)
-  }
-  return schemeClrs
-}
-
-function extractChartData (serNode) {
-  const dataMat = []
-  if (!serNode) return dataMat
-
-  if (serNode['c:xVal']) {
-    let dataRow = []
-    eachElement(serNode['c:xVal']['c:numRef']['c:numCache']['c:pt'], innerNode => {
-      dataRow.push(parseFloat(innerNode['c:v']))
-      return ''
-    })
-    dataMat.push(dataRow)
-    dataRow = []
-    eachElement(serNode['c:yVal']['c:numRef']['c:numCache']['c:pt'], innerNode => {
-      dataRow.push(parseFloat(innerNode['c:v']))
-      return ''
-    })
-    dataMat.push(dataRow)
-  } else {
-    eachElement(serNode, (innerNode, index) => {
-      const dataRow = []
-      const colName = getTextByPathList(innerNode, ['c:tx', 'c:strRef', 'c:strCache', 'c:pt', 'c:v']) || index
-
-      const rowNames = {}
-      if (getTextByPathList(innerNode, ['c:cat', 'c:strRef', 'c:strCache', 'c:pt'])) {
-        eachElement(innerNode['c:cat']['c:strRef']['c:strCache']['c:pt'], innerNode => {
-          rowNames[innerNode['attrs']['idx']] = innerNode['c:v']
-          return ''
-        })
-      } else if (getTextByPathList(innerNode, ['c:cat', 'c:numRef', 'c:numCache', 'c:pt'])) {
-        eachElement(innerNode['c:cat']['c:numRef']['c:numCache']['c:pt'], innerNode => {
-          rowNames[innerNode['attrs']['idx']] = innerNode['c:v']
-          return ''
-        })
-      }
-
-      if (getTextByPathList(innerNode, ['c:val', 'c:numRef', 'c:numCache', 'c:pt'])) {
-        eachElement(innerNode['c:val']['c:numRef']['c:numCache']['c:pt'], innerNode => {
-          dataRow.push({
-            x: innerNode['attrs']['idx'],
-            y: parseFloat(innerNode['c:v'])
-          })
-          return ''
-        })
-      }
-
-      dataMat.push({
-        key: colName,
-        values: dataRow,
-        xlabels: rowNames
-      })
-      return ''
-    })
-  }
-
-  return dataMat
-}
-
-export function getChartInfo (plotArea, warpObj) {
-  let chart = null
-  for (const key in plotArea) {
-    switch (key) {
-      case 'c:lineChart':
-        chart = {
-          type: 'lineChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          grouping: getTextByPathList(plotArea[key], ['c:grouping', 'attrs', 'val']),
-          marker: !!plotArea[key]['c:marker']
-        }
-        break
-      case 'c:line3DChart':
-        chart = {
-          type: 'line3DChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          grouping: getTextByPathList(plotArea[key], ['c:grouping', 'attrs', 'val'])
-        }
-        break
-      case 'c:barChart':
-        chart = {
-          type: 'barChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          grouping: getTextByPathList(plotArea[key], ['c:grouping', 'attrs', 'val']),
-          barDir: getTextByPathList(plotArea[key], ['c:barDir', 'attrs', 'val'])
-        }
-        break
-      case 'c:bar3DChart':
-        chart = {
-          type: 'bar3DChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          grouping: getTextByPathList(plotArea[key], ['c:grouping', 'attrs', 'val']),
-          barDir: getTextByPathList(plotArea[key], ['c:barDir', 'attrs', 'val'])
-        }
-        break
-      case 'c:pieChart':
-        chart = {
-          type: 'pieChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser']['c:dPt'], warpObj)
-        }
-        break
-      case 'c:pie3DChart':
-        chart = {
-          type: 'pie3DChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser']['c:dPt'], warpObj)
-        }
-        break
-      case 'c:doughnutChart':
-        chart = {
-          type: 'doughnutChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser']['c:dPt'], warpObj),
-          holeSize: getTextByPathList(plotArea[key], ['c:holeSize', 'attrs', 'val'])
-        }
-        break
-      case 'c:areaChart':
-        chart = {
-          type: 'areaChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          grouping: getTextByPathList(plotArea[key], ['c:grouping', 'attrs', 'val'])
-        }
-        break
-      case 'c:area3DChart':
-        chart = {
-          type: 'area3DChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          grouping: getTextByPathList(plotArea[key], ['c:grouping', 'attrs', 'val'])
-        }
-        break
-      case 'c:scatterChart':
-        chart = {
-          type: 'scatterChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          style: getTextByPathList(plotArea[key], ['c:scatterStyle', 'attrs', 'val'])
-        }
-        break
-      case 'c:bubbleChart':
-        chart = {
-          type: 'bubbleChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj)
-        }
-        break
-      case 'c:radarChart':
-        chart = {
-          type: 'radarChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj),
-          style: getTextByPathList(plotArea[key], ['c:radarStyle', 'attrs', 'val'])
-        }
-        break
-      case 'c:surfaceChart':
-        chart = {
-          type: 'surfaceChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj)
-        }
-        break
-      case 'c:surface3DChart':
-        chart = {
-          type: 'surface3DChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: extractChartColors(plotArea[key]['c:ser'], warpObj)
-        }
-        break
-      case 'c:stockChart':
-        chart = {
-          type: 'stockChart',
-          data: extractChartData(plotArea[key]['c:ser']),
-          colors: []
-        }
-        break
-      default:
-    }
-  }
-
-  return chart
-}

+ 0 - 176
src/utils/pptxToJson/color.js

@@ -1,176 +0,0 @@
-import tinycolor from 'tinycolor2'
-
-export function hueToRgb (t1, t2, hue) {
-  if (hue < 0) hue += 6
-  if (hue >= 6) hue -= 6
-  if (hue < 1) return (t2 - t1) * hue + t1
-  else if (hue < 3) return t2
-  else if (hue < 4) return (t2 - t1) * (4 - hue) + t1
-  return t1
-}
-
-export function hslToRgb (hue, sat, light) {
-  let t2
-  hue = hue / 60
-  if (light <= 0.5) {
-    t2 = light * (sat + 1)
-  } else {
-    t2 = light + sat - (light * sat)
-  }
-  const t1 = light * 2 - t2
-  const r = hueToRgb(t1, t2, hue + 2) * 255
-  const g = hueToRgb(t1, t2, hue) * 255
-  const b = hueToRgb(t1, t2, hue - 2) * 255
-  return { r, g, b }
-}
-
-export function applyShade (rgbStr, shadeValue, isAlpha) {
-  const color = tinycolor(rgbStr).toHsl()
-  if (shadeValue >= 1) shadeValue = 1
-  const cacl_l = Math.min(color.l * shadeValue, 1)
-  if (isAlpha) {
-    return tinycolor({
-      h: color.h,
-      s: color.s,
-      l: cacl_l,
-      a: color.a
-    }).toHex8()
-  }
-
-  return tinycolor({
-    h: color.h,
-    s: color.s,
-    l: cacl_l,
-    a: color.a
-  }).toHex()
-}
-
-export function applyTint (rgbStr, tintValue, isAlpha) {
-  const color = tinycolor(rgbStr).toHsl()
-  if (tintValue >= 1) tintValue = 1
-  const cacl_l = color.l * tintValue + (1 - tintValue)
-  if (isAlpha) {
-    return tinycolor({
-      h: color.h,
-      s: color.s,
-      l: cacl_l,
-      a: color.a
-    }).toHex8()
-  }
-
-  return tinycolor({
-    h: color.h,
-    s: color.s,
-    l: cacl_l,
-    a: color.a
-  }).toHex()
-}
-
-export function applyLumOff (rgbStr, offset, isAlpha) {
-  const color = tinycolor(rgbStr).toHsl()
-  const lum = offset + color.l
-  if (lum >= 1) {
-    if (isAlpha) {
-      return tinycolor({
-        h: color.h,
-        s: color.s,
-        l: 1,
-        a: color.a
-      }).toHex8()
-    }
-
-    return tinycolor({
-      h: color.h,
-      s: color.s,
-      l: 1,
-      a: color.a
-    }).toHex()
-  }
-  if (isAlpha) {
-    return tinycolor({
-      h: color.h,
-      s: color.s,
-      l: lum,
-      a: color.a
-    }).toHex8()
-  }
-
-  return tinycolor({
-    h: color.h,
-    s: color.s,
-    l: lum,
-    a: color.a
-  }).toHex()
-}
-
-export function applyLumMod (rgbStr, multiplier, isAlpha) {
-  const color = tinycolor(rgbStr).toHsl()
-  let cacl_l = color.l * multiplier
-  if (cacl_l >= 1) cacl_l = 1
-  if (isAlpha) {
-    return tinycolor({
-      h: color.h,
-      s: color.s,
-      l: cacl_l,
-      a: color.a
-    }).toHex8()
-  }
-
-  return tinycolor({
-    h: color.h,
-    s: color.s,
-    l: cacl_l,
-    a: color.a
-  }).toHex()
-}
-
-export function applyHueMod (rgbStr, multiplier, isAlpha) {
-  const color = tinycolor(rgbStr).toHsl()
-  let cacl_h = color.h * multiplier
-  if (cacl_h >= 360) cacl_h = cacl_h - 360
-  if (isAlpha) {
-    return tinycolor({
-      h: cacl_h,
-      s: color.s,
-      l: color.l,
-      a: color.a
-    }).toHex8()
-  }
-
-  return tinycolor({
-    h: cacl_h,
-    s: color.s,
-    l: color.l,
-    a: color.a
-  }).toHex()
-}
-
-export function applySatMod (rgbStr, multiplier, isAlpha) {
-  const color = tinycolor(rgbStr).toHsl()
-  let cacl_s = color.s * multiplier
-  if (cacl_s >= 1) cacl_s = 1
-  if (isAlpha) {
-    return tinycolor({
-      h: color.h,
-      s: cacl_s,
-      l: color.l,
-      a: color.a
-    }).toHex8()
-  }
-
-  return tinycolor({
-    h: color.h,
-    s: cacl_s,
-    l: color.l,
-    a: color.a
-  }).toHex()
-}
-
-export function getColorName2Hex (name) {
-  let hex
-  const colorName = ['white', 'AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque', 'black', 'BlanchedAlmond', 'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue', 'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson', 'Cyan', 'DarkBlue', 'DarkCyan', 'DarkGoldenRod', 'DarkGray', 'DarkGrey', 'DarkGreen', 'DarkKhaki', 'DarkMagenta', 'DarkOliveGreen', 'DarkOrange', 'DarkOrchid', 'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue', 'DarkSlateGray', 'DarkSlateGrey', 'DarkTurquoise', 'DarkViolet', 'DeepPink', 'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick', 'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod', 'Gray', 'Grey', 'Green', 'GreenYellow', 'HoneyDew', 'HotPink', 'IndianRed', 'Indigo', 'Ivory', 'Khaki', 'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral', 'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGrey', 'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue', 'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon', 'MediumAquaMarine', 'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen', 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue', 'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive', 'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple', 'RebeccaPurple', 'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon', 'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue', 'SlateGray', 'SlateGrey', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke', 'Yellow', 'YellowGreen']
-  const colorHex = ['ffffff', 'f0f8ff', 'faebd7', '00ffff', '7fffd4', 'f0ffff', 'f5f5dc', 'ffe4c4', '000000', 'ffebcd', '0000ff', '8a2be2', 'a52a2a', 'deb887', '5f9ea0', '7fff00', 'd2691e', 'ff7f50', '6495ed', 'fff8dc', 'dc143c', '00ffff', '00008b', '008b8b', 'b8860b', 'a9a9a9', 'a9a9a9', '006400', 'bdb76b', '8b008b', '556b2f', 'ff8c00', '9932cc', '8b0000', 'e9967a', '8fbc8f', '483d8b', '2f4f4f', '2f4f4f', '00ced1', '9400d3', 'ff1493', '00bfff', '696969', '696969', '1e90ff', 'b22222', 'fffaf0', '228b22', 'ff00ff', 'dcdcdc', 'f8f8ff', 'ffd700', 'daa520', '808080', '808080', '008000', 'adff2f', 'f0fff0', 'ff69b4', 'cd5c5c', '4b0082', 'fffff0', 'f0e68c', 'e6e6fa', 'fff0f5', '7cfc00', 'fffacd', 'add8e6', 'f08080', 'e0ffff', 'fafad2', 'd3d3d3', 'd3d3d3', '90ee90', 'ffb6c1', 'ffa07a', '20b2aa', '87cefa', '778899', '778899', 'b0c4de', 'ffffe0', '00ff00', '32cd32', 'faf0e6', 'ff00ff', '800000', '66cdaa', '0000cd', 'ba55d3', '9370db', '3cb371', '7b68ee', '00fa9a', '48d1cc', 'c71585', '191970', 'f5fffa', 'ffe4e1', 'ffe4b5', 'ffdead', '000080', 'fdf5e6', '808000', '6b8e23', 'ffa500', 'ff4500', 'da70d6', 'eee8aa', '98fb98', 'afeeee', 'db7093', 'ffefd5', 'ffdab9', 'cd853f', 'ffc0cb', 'dda0dd', 'b0e0e6', '800080', '663399', 'ff0000', 'bc8f8f', '4169e1', '8b4513', 'fa8072', 'f4a460', '2e8b57', 'fff5ee', 'a0522d', 'c0c0c0', '87ceeb', '6a5acd', '708090', '708090', 'fffafa', '00ff7f', '4682b4', 'd2b48c', '008080', 'd8bfd8', 'ff6347', '40e0d0', 'ee82ee', 'f5deb3', 'ffffff', 'f5f5f5', 'ffff00', '9acd32']
-  const findIndx = colorName.indexOf(name)
-  if (findIndx !== -1) hex = colorHex[findIndx]
-  return hex
-}

+ 0 - 3
src/utils/pptxToJson/constants.js

@@ -1,3 +0,0 @@
-export const RATIO_Inches_EMUs = 914400 // 1英寸 = 914400EMUs
-export const RATIO_Inches_Points = 72 // 1英寸 = 72pt
-export const RATIO_EMUs_Points = RATIO_Inches_Points / RATIO_Inches_EMUs // 1EMUs = (72 / 914400)pt

+ 0 - 555
src/utils/pptxToJson/fill.js

@@ -1,555 +0,0 @@
-import tinycolor from 'tinycolor2'
-import { getSchemeColorFromTheme } from './schemeColor'
-import {
-  applyShade,
-  applyTint,
-  applyLumOff,
-  applyLumMod,
-  applyHueMod,
-  applySatMod,
-  hslToRgb,
-  getColorName2Hex
-} from './color'
-
-import {
-  base64ArrayBuffer,
-  getTextByPathList,
-  angleToDegrees,
-  escapeHtml,
-  getMimeType,
-  toHex
-} from './utils'
-
-export function getFillType (node) {
-  let fillType = ''
-  if (node['a:noFill']) fillType = 'NO_FILL'
-  if (node['a:solidFill']) fillType = 'SOLID_FILL'
-  if (node['a:gradFill']) fillType = 'GRADIENT_FILL'
-  if (node['a:pattFill']) fillType = 'PATTERN_FILL'
-  if (node['a:blipFill']) fillType = 'PIC_FILL'
-  if (node['a:grpFill']) fillType = 'GROUP_FILL'
-
-  return fillType
-}
-
-export async function getPicFill (type, node, warpObj) {
-  let img
-  const rId = node['a:blip']['attrs']['r:embed']
-  let imgPath
-  if (type === 'slideBg' || type === 'slide') {
-    imgPath = getTextByPathList(warpObj, ['slideResObj', rId, 'target'])
-  } else if (type === 'slideLayoutBg') {
-    imgPath = getTextByPathList(warpObj, ['layoutResObj', rId, 'target'])
-  } else if (type === 'slideMasterBg') {
-    imgPath = getTextByPathList(warpObj, ['masterResObj', rId, 'target'])
-  } else if (type === 'themeBg') {
-    imgPath = getTextByPathList(warpObj, ['themeResObj', rId, 'target'])
-  } else if (type === 'diagramBg') {
-    imgPath = getTextByPathList(warpObj, ['diagramResObj', rId, 'target'])
-  }
-  if (!imgPath) return imgPath
-
-  img = getTextByPathList(warpObj, ['loaded-images', imgPath])
-  if (!img) {
-    imgPath = escapeHtml(imgPath)
-
-    const imgExt = imgPath.split('.').pop()
-    if (imgExt === 'xml') return undefined
-
-    const imgArrayBuffer = await warpObj['zip'].file(imgPath).async('arraybuffer')
-    const imgMimeType = getMimeType(imgExt)
-    img = `data:${imgMimeType};base64,${base64ArrayBuffer(imgArrayBuffer)}`
-
-    const loadedImages = warpObj['loaded-images'] || {}
-    loadedImages[imgPath] = img
-    warpObj['loaded-images'] = loadedImages
-  }
-  return img
-}
-
-export function getPicFillOpacity (node) {
-  const aBlipNode = node['a:blip']
-
-  const aphaModFixNode = getTextByPathList(aBlipNode, ['a:alphaModFix', 'attrs'])
-  let opacity = 1
-  if (aphaModFixNode && aphaModFixNode['amt'] && aphaModFixNode['amt'] !== '') {
-    opacity = parseInt(aphaModFixNode['amt']) / 100000
-  }
-
-  return opacity
-}
-
-export async function getBgPicFill (bgPr, sorce, warpObj) {
-  const picBase64 = await getPicFill(sorce, bgPr['a:blipFill'], warpObj)
-  const aBlipNode = bgPr['a:blipFill']['a:blip']
-
-  const aphaModFixNode = getTextByPathList(aBlipNode, ['a:alphaModFix', 'attrs'])
-  let opacity = 1
-  if (aphaModFixNode && aphaModFixNode['amt'] && aphaModFixNode['amt'] !== '') {
-    opacity = parseInt(aphaModFixNode['amt']) / 100000
-  }
-
-  return {
-    picBase64,
-    opacity
-  }
-}
-
-export function getGradientFill (node, warpObj) {
-  const gsLst = node['a:gsLst']['a:gs']
-  const colors = []
-  for (let i = 0; i < gsLst.length; i++) {
-    const lo_color = getSolidFill(gsLst[i], undefined, undefined, warpObj)
-    const pos = getTextByPathList(gsLst[i], ['attrs', 'pos'])
-
-    colors[i] = {
-      pos: pos ? (pos / 1000 + '%') : '',
-      color: lo_color
-    }
-  }
-  const lin = node['a:lin']
-  let rot = 0
-  let pathType = 'line'
-  if (lin) rot = angleToDegrees(lin['attrs']['ang'])
-  else {
-    const path = node['a:path']
-    if (path && path['attrs'] && path['attrs']['path']) pathType = path['attrs']['path']
-  }
-  return {
-    rot,
-    path: pathType,
-    colors: colors.sort((a, b) => parseInt(a.pos) - parseInt(b.pos))
-  }
-}
-
-export function getBgGradientFill (bgPr, phClr, slideMasterContent, warpObj) {
-  if (bgPr) {
-    const grdFill = bgPr['a:gradFill']
-    const gsLst = grdFill['a:gsLst']['a:gs']
-    const colors = []
-
-    for (let i = 0; i < gsLst.length; i++) {
-      const lo_color = getSolidFill(gsLst[i], slideMasterContent['p:sldMaster']['p:clrMap']['attrs'], phClr, warpObj)
-      const pos = getTextByPathList(gsLst[i], ['attrs', 'pos'])
-
-      colors[i] = {
-        pos: pos ? (pos / 1000 + '%') : '',
-        color: lo_color
-      }
-    }
-    const lin = grdFill['a:lin']
-    let rot = 0
-    let pathType = 'line'
-    if (lin) rot = angleToDegrees(lin['attrs']['ang']) + 0
-    else {
-      const path = grdFill['a:path']
-      if (path && path['attrs'] && path['attrs']['path']) pathType = path['attrs']['path']
-    }
-    return {
-      rot,
-      path: pathType,
-      colors: colors.sort((a, b) => parseInt(a.pos) - parseInt(b.pos))
-    }
-  } else if (phClr) {
-    return phClr.indexOf('#') === -1 ? `#${phClr}` : phClr
-  }
-  return null
-}
-
-export async function getSlideBackgroundFill (warpObj) {
-  const slideContent = warpObj['slideContent']
-  const slideLayoutContent = warpObj['slideLayoutContent']
-  const slideMasterContent = warpObj['slideMasterContent']
-
-  let bgPr = getTextByPathList(slideContent, ['p:sld', 'p:cSld', 'p:bg', 'p:bgPr'])
-  let bgRef = getTextByPathList(slideContent, ['p:sld', 'p:cSld', 'p:bg', 'p:bgRef'])
-
-  let background = '#fff'
-  let backgroundType = 'color'
-
-  if (bgPr) {
-    const bgFillTyp = getFillType(bgPr)
-
-    if (bgFillTyp === 'SOLID_FILL') {
-      const sldFill = bgPr['a:solidFill']
-      let clrMapOvr
-      const sldClrMapOvr = getTextByPathList(slideContent, ['p:sld', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-      if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
-      else {
-        const sldClrMapOvr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-        if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
-        else clrMapOvr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
-      }
-      const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
-      background = sldBgClr
-    } else if (bgFillTyp === 'GRADIENT_FILL') {
-      const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
-      if (typeof gradientFill === 'string') {
-        background = gradientFill
-      } else if (gradientFill) {
-        background = gradientFill
-        backgroundType = 'gradient'
-      }
-    } else if (bgFillTyp === 'PIC_FILL') {
-      background = await getBgPicFill(bgPr, 'slideBg', warpObj)
-      backgroundType = 'image'
-    }
-  } else if (bgRef) {
-    let clrMapOvr
-    const sldClrMapOvr = getTextByPathList(slideContent, ['p:sld', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-    if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
-    else {
-      const sldClrMapOvr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-      if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
-      else clrMapOvr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
-    }
-    const phClr = getSolidFill(bgRef, clrMapOvr, undefined, warpObj)
-    const idx = Number(bgRef['attrs']['idx'])
-
-    if (idx > 1000) {
-      const trueIdx = idx - 1000
-      const bgFillLst = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:bgFillStyleLst']
-      const sortblAry = []
-      Object.keys(bgFillLst).forEach(key => {
-        const bgFillLstTyp = bgFillLst[key]
-        if (key !== 'attrs') {
-          if (bgFillLstTyp.constructor === Array) {
-            for (let i = 0; i < bgFillLstTyp.length; i++) {
-              const obj = {}
-              obj[key] = bgFillLstTyp[i]
-              if (bgFillLstTyp[i]['attrs']) {
-                obj['idex'] = bgFillLstTyp[i]['attrs']['order']
-                obj['attrs'] = {
-                  'order': bgFillLstTyp[i]['attrs']['order']
-                }
-              }
-              sortblAry.push(obj)
-            }
-          } else {
-            const obj = {}
-            obj[key] = bgFillLstTyp
-            if (bgFillLstTyp['attrs']) {
-              obj['idex'] = bgFillLstTyp['attrs']['order']
-              obj['attrs'] = {
-                'order': bgFillLstTyp['attrs']['order']
-              }
-            }
-            sortblAry.push(obj)
-          }
-        }
-      })
-      const sortByOrder = sortblAry.slice(0)
-      sortByOrder.sort((a, b) => a.idex - b.idex)
-      const bgFillLstIdx = sortByOrder[trueIdx - 1]
-      const bgFillTyp = getFillType(bgFillLstIdx)
-      if (bgFillTyp === 'SOLID_FILL') {
-        const sldFill = bgFillLstIdx['a:solidFill']
-        const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
-        background = sldBgClr
-      } else if (bgFillTyp === 'GRADIENT_FILL') {
-        const gradientFill = getBgGradientFill(bgFillLstIdx, phClr, slideMasterContent, warpObj)
-        if (typeof gradientFill === 'string') {
-          background = gradientFill
-        } else if (gradientFill) {
-          background = gradientFill
-          backgroundType = 'gradient'
-        }
-      }
-    }
-  } else {
-    bgPr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:bg', 'p:bgPr'])
-    bgRef = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:bg', 'p:bgRef'])
-
-    let clrMapOvr
-    const sldClrMapOvr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-    if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
-    else clrMapOvr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
-
-    if (bgPr) {
-      const bgFillTyp = getFillType(bgPr)
-      if (bgFillTyp === 'SOLID_FILL') {
-        const sldFill = bgPr['a:solidFill']
-        const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
-        background = sldBgClr
-      } else if (bgFillTyp === 'GRADIENT_FILL') {
-        const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
-        if (typeof gradientFill === 'string') {
-          background = gradientFill
-        } else if (gradientFill) {
-          background = gradientFill
-          backgroundType = 'gradient'
-        }
-      } else if (bgFillTyp === 'PIC_FILL') {
-        background = await getBgPicFill(bgPr, 'slideLayoutBg', warpObj)
-        backgroundType = 'image'
-      }
-    } else if (bgRef) {
-      const phClr = getSolidFill(bgRef, clrMapOvr, undefined, warpObj)
-      const idx = Number(bgRef['attrs']['idx'])
-
-      if (idx > 1000) {
-        const trueIdx = idx - 1000
-        const bgFillLst = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:bgFillStyleLst']
-        const sortblAry = []
-        Object.keys(bgFillLst).forEach(key => {
-          const bgFillLstTyp = bgFillLst[key]
-          if (key !== 'attrs') {
-            if (bgFillLstTyp.constructor === Array) {
-              for (let i = 0; i < bgFillLstTyp.length; i++) {
-                const obj = {}
-                obj[key] = bgFillLstTyp[i]
-                if (bgFillLstTyp[i]['attrs']) {
-                  obj['idex'] = bgFillLstTyp[i]['attrs']['order']
-                  obj['attrs'] = {
-                    'order': bgFillLstTyp[i]['attrs']['order']
-                  }
-                }
-                sortblAry.push(obj)
-              }
-            } else {
-              const obj = {}
-              obj[key] = bgFillLstTyp
-              if (bgFillLstTyp['attrs']) {
-                obj['idex'] = bgFillLstTyp['attrs']['order']
-                obj['attrs'] = {
-                  'order': bgFillLstTyp['attrs']['order']
-                }
-              }
-              sortblAry.push(obj)
-            }
-          }
-        })
-        const sortByOrder = sortblAry.slice(0)
-        sortByOrder.sort((a, b) => a.idex - b.idex)
-        const bgFillLstIdx = sortByOrder[trueIdx - 1]
-        const bgFillTyp = getFillType(bgFillLstIdx)
-        if (bgFillTyp === 'SOLID_FILL') {
-          const sldFill = bgFillLstIdx['a:solidFill']
-          const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
-          background = sldBgClr
-        } else if (bgFillTyp === 'GRADIENT_FILL') {
-          const gradientFill = getBgGradientFill(bgFillLstIdx, phClr, slideMasterContent, warpObj)
-          if (typeof gradientFill === 'string') {
-            background = gradientFill
-          } else if (gradientFill) {
-            background = gradientFill
-            backgroundType = 'gradient'
-          }
-        } else if (bgFillTyp === 'PIC_FILL') {
-          background = await getBgPicFill(bgFillLstIdx, 'themeBg', warpObj)
-          backgroundType = 'image'
-        }
-      }
-    } else {
-      bgPr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:bg', 'p:bgPr'])
-      bgRef = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:bg', 'p:bgRef'])
-
-      const clrMap = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
-      if (bgPr) {
-        const bgFillTyp = getFillType(bgPr)
-        if (bgFillTyp === 'SOLID_FILL') {
-          const sldFill = bgPr['a:solidFill']
-          const sldBgClr = getSolidFill(sldFill, clrMap, undefined, warpObj)
-          background = sldBgClr
-        } else if (bgFillTyp === 'GRADIENT_FILL') {
-          const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
-          if (typeof gradientFill === 'string') {
-            background = gradientFill
-          } else if (gradientFill) {
-            background = gradientFill
-            backgroundType = 'gradient'
-          }
-        } else if (bgFillTyp === 'PIC_FILL') {
-          background = await getBgPicFill(bgPr, 'slideMasterBg', warpObj)
-          backgroundType = 'image'
-        }
-      } else if (bgRef) {
-        const phClr = getSolidFill(bgRef, clrMap, undefined, warpObj)
-        const idx = Number(bgRef['attrs']['idx'])
-
-        if (idx > 1000) {
-          const trueIdx = idx - 1000
-          const bgFillLst = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:bgFillStyleLst']
-          const sortblAry = []
-          Object.keys(bgFillLst).forEach(key => {
-            const bgFillLstTyp = bgFillLst[key]
-            if (key !== 'attrs') {
-              if (bgFillLstTyp.constructor === Array) {
-                for (let i = 0; i < bgFillLstTyp.length; i++) {
-                  const obj = {}
-                  obj[key] = bgFillLstTyp[i]
-                  if (bgFillLstTyp[i]['attrs']) {
-                    obj['idex'] = bgFillLstTyp[i]['attrs']['order']
-                    obj['attrs'] = {
-                      'order': bgFillLstTyp[i]['attrs']['order']
-                    }
-                  }
-                  sortblAry.push(obj)
-                }
-              } else {
-                const obj = {}
-                obj[key] = bgFillLstTyp
-                if (bgFillLstTyp['attrs']) {
-                  obj['idex'] = bgFillLstTyp['attrs']['order']
-                  obj['attrs'] = {
-                    'order': bgFillLstTyp['attrs']['order']
-                  }
-                }
-                sortblAry.push(obj)
-              }
-            }
-          })
-          const sortByOrder = sortblAry.slice(0)
-          sortByOrder.sort((a, b) => a.idex - b.idex)
-          const bgFillLstIdx = sortByOrder[trueIdx - 1]
-          const bgFillTyp = getFillType(bgFillLstIdx)
-          if (bgFillTyp === 'SOLID_FILL') {
-            const sldFill = bgFillLstIdx['a:solidFill']
-            const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
-            background = sldBgClr
-          } else if (bgFillTyp === 'GRADIENT_FILL') {
-            const gradientFill = getBgGradientFill(bgFillLstIdx, phClr, slideMasterContent, warpObj)
-            if (typeof gradientFill === 'string') {
-              background = gradientFill
-            } else if (gradientFill) {
-              background = gradientFill
-              backgroundType = 'gradient'
-            }
-          } else if (bgFillTyp === 'PIC_FILL') {
-            background = await getBgPicFill(bgFillLstIdx, 'themeBg', warpObj)
-            backgroundType = 'image'
-          }
-        }
-      }
-    }
-  }
-  return {
-    type: backgroundType,
-    value: background
-  }
-}
-
-export async function getShapeFill (node, pNode, isSvgMode, warpObj, source) {
-  const fillType = getFillType(getTextByPathList(node, ['p:spPr']))
-  let type = 'color'
-  let fillValue = ''
-  if (fillType === 'NO_FILL') {
-    return isSvgMode ? 'none' : ''
-  } else if (fillType === 'SOLID_FILL') {
-    const shpFill = node['p:spPr']['a:solidFill']
-    fillValue = getSolidFill(shpFill, undefined, undefined, warpObj)
-    type = 'color'
-  } else if (fillType === 'GRADIENT_FILL') {
-    const shpFill = node['p:spPr']['a:gradFill']
-    fillValue = getGradientFill(shpFill, warpObj)
-    type = 'gradient'
-  } else if (fillType === 'PIC_FILL') {
-    const shpFill = node['p:spPr']['a:blipFill']
-    const picBase64 = await getPicFill(source, shpFill, warpObj)
-    const opacity = getPicFillOpacity(shpFill)
-    fillValue = {
-      picBase64,
-      opacity
-    }
-    type = 'image'
-  }
-  if (!fillValue) {
-    const clrName = getTextByPathList(node, ['p:style', 'a:fillRef'])
-    fillValue = getSolidFill(clrName, undefined, undefined, warpObj)
-    type = 'color'
-  }
-  if (!fillValue && pNode) {
-    const grpFill = getTextByPathList(node, ['p:spPr', 'a:grpFill'])
-    if (grpFill) {
-      const grpShpFill = pNode['p:grpSpPr']
-      if (grpShpFill) {
-        const spShpNode = { 'p:spPr': grpShpFill }
-        return getShapeFill(spShpNode, node, isSvgMode, warpObj, source)
-      }
-    } else if (fillType === 'NO_FILL') {
-      return isSvgMode ? 'none' : ''
-    }
-  }
-
-  return {
-    type,
-    value: fillValue
-  }
-}
-
-export function getSolidFill (solidFill, clrMap, phClr, warpObj) {
-  if (!solidFill) return ''
-
-  let color = ''
-  let clrNode
-
-  if (solidFill['a:srgbClr']) {
-    clrNode = solidFill['a:srgbClr']
-    color = getTextByPathList(clrNode, ['attrs', 'val'])
-  } else if (solidFill['a:schemeClr']) {
-    clrNode = solidFill['a:schemeClr']
-    const schemeClr = 'a:' + getTextByPathList(clrNode, ['attrs', 'val'])
-    color = getSchemeColorFromTheme(schemeClr, warpObj, clrMap, phClr) || ''
-  } else if (solidFill['a:scrgbClr']) {
-    clrNode = solidFill['a:scrgbClr']
-    const defBultColorVals = clrNode['attrs']
-    const red = (defBultColorVals['r'].indexOf('%') !== -1) ? defBultColorVals['r'].split('%').shift() : defBultColorVals['r']
-    const green = (defBultColorVals['g'].indexOf('%') !== -1) ? defBultColorVals['g'].split('%').shift() : defBultColorVals['g']
-    const blue = (defBultColorVals['b'].indexOf('%') !== -1) ? defBultColorVals['b'].split('%').shift() : defBultColorVals['b']
-    color = toHex(255 * (Number(red) / 100)) + toHex(255 * (Number(green) / 100)) + toHex(255 * (Number(blue) / 100))
-  } else if (solidFill['a:prstClr']) {
-    clrNode = solidFill['a:prstClr']
-    const prstClr = getTextByPathList(clrNode, ['attrs', 'val'])
-    color = getColorName2Hex(prstClr)
-  } else if (solidFill['a:hslClr']) {
-    clrNode = solidFill['a:hslClr']
-    const defBultColorVals = clrNode['attrs']
-    const hue = Number(defBultColorVals['hue']) / 100000
-    const sat = Number((defBultColorVals['sat'].indexOf('%') !== -1) ? defBultColorVals['sat'].split('%').shift() : defBultColorVals['sat']) / 100
-    const lum = Number((defBultColorVals['lum'].indexOf('%') !== -1) ? defBultColorVals['lum'].split('%').shift() : defBultColorVals['lum']) / 100
-    const hsl2rgb = hslToRgb(hue, sat, lum)
-    color = toHex(hsl2rgb.r) + toHex(hsl2rgb.g) + toHex(hsl2rgb.b)
-  } else if (solidFill['a:sysClr']) {
-    clrNode = solidFill['a:sysClr']
-    const sysClr = getTextByPathList(clrNode, ['attrs', 'lastClr'])
-    if (sysClr) color = sysClr
-  }
-
-  let isAlpha = false
-  const alpha = parseInt(getTextByPathList(clrNode, ['a:alpha', 'attrs', 'val'])) / 100000
-  if (!isNaN(alpha)) {
-    const al_color = tinycolor(color)
-    al_color.setAlpha(alpha)
-    color = al_color.toHex8()
-    isAlpha = true
-  }
-
-  const hueMod = parseInt(getTextByPathList(clrNode, ['a:hueMod', 'attrs', 'val'])) / 100000
-  if (!isNaN(hueMod)) {
-    color = applyHueMod(color, hueMod, isAlpha)
-  }
-  const lumMod = parseInt(getTextByPathList(clrNode, ['a:lumMod', 'attrs', 'val'])) / 100000
-  if (!isNaN(lumMod)) {
-    color = applyLumMod(color, lumMod, isAlpha)
-  }
-  const lumOff = parseInt(getTextByPathList(clrNode, ['a:lumOff', 'attrs', 'val'])) / 100000
-  if (!isNaN(lumOff)) {
-    color = applyLumOff(color, lumOff, isAlpha)
-  }
-  const satMod = parseInt(getTextByPathList(clrNode, ['a:satMod', 'attrs', 'val'])) / 100000
-  if (!isNaN(satMod)) {
-    color = applySatMod(color, satMod, isAlpha)
-  }
-  const shade = parseInt(getTextByPathList(clrNode, ['a:shade', 'attrs', 'val'])) / 100000
-  if (!isNaN(shade)) {
-    color = applyShade(color, shade, isAlpha)
-  }
-  const tint = parseInt(getTextByPathList(clrNode, ['a:tint', 'attrs', 'val'])) / 100000
-  if (!isNaN(tint)) {
-    color = applyTint(color, tint, isAlpha)
-  }
-
-  if (color && color.indexOf('#') === -1) color = '#' + color
-
-  return color
-}

+ 0 - 154
src/utils/pptxToJson/fontStyle.js

@@ -1,154 +0,0 @@
-import { getTextByPathList } from './utils'
-import { getShadow } from './shadow'
-import { getFillType, getSolidFill } from './fill'
-
-export function getFontType (node, type, warpObj) {
-  let typeface = getTextByPathList(node, ['a:rPr', 'a:latin', 'attrs', 'typeface'])
-
-  if (!typeface) {
-    const fontSchemeNode = getTextByPathList(warpObj['themeContent'], ['a:theme', 'a:themeElements', 'a:fontScheme'])
-
-    if (type === 'title' || type === 'subTitle' || type === 'ctrTitle') {
-      typeface = getTextByPathList(fontSchemeNode, ['a:majorFont', 'a:latin', 'attrs', 'typeface'])
-    } else if (type === 'body') {
-      typeface = getTextByPathList(fontSchemeNode, ['a:minorFont', 'a:latin', 'attrs', 'typeface'])
-    } else {
-      typeface = getTextByPathList(fontSchemeNode, ['a:minorFont', 'a:latin', 'attrs', 'typeface'])
-    }
-  }
-
-  return typeface || ''
-}
-
-export function getFontColor (node, pNode, lstStyle, pFontStyle, lvl, warpObj) {
-  const rPrNode = getTextByPathList(node, ['a:rPr'])
-  let filTyp, color
-  if (rPrNode) {
-    filTyp = getFillType(rPrNode)
-    if (filTyp === 'SOLID_FILL') {
-      const solidFillNode = rPrNode['a:solidFill']
-      color = getSolidFill(solidFillNode, undefined, undefined, warpObj)
-    }
-  }
-  if (!color && getTextByPathList(lstStyle, ['a:lvl' + lvl + 'pPr', 'a:defRPr'])) {
-    const lstStyledefRPr = getTextByPathList(lstStyle, ['a:lvl' + lvl + 'pPr', 'a:defRPr'])
-    filTyp = getFillType(lstStyledefRPr)
-    if (filTyp === 'SOLID_FILL') {
-      const solidFillNode = lstStyledefRPr['a:solidFill']
-      color = getSolidFill(solidFillNode, undefined, undefined, warpObj)
-    }
-  }
-  if (!color) {
-    const sPstyle = getTextByPathList(pNode, ['p:style', 'a:fontRef'])
-    if (sPstyle) color = getSolidFill(sPstyle, undefined, undefined, warpObj)
-    if (!color && pFontStyle) color = getSolidFill(pFontStyle, undefined, undefined, warpObj)
-  }
-  return color || ''
-}
-
-export function getFontSize (node, slideLayoutSpNode, type, slideMasterTextStyles) {
-  let fontSize
-
-  // 检查列表样式中的字体大小
-  const lstStyleSz = getTextByPathList(node, ['a:lstStyle', 'a:lvl1pPr', 'a:defRPr', 'attrs', 'sz'])
-  if (lstStyleSz) {
-    fontSize = parseInt(lstStyleSz) / 100
-  }
-
-  // 检查直接在文本上设置的字体大小
-  if (!fontSize || isNaN(fontSize)) {
-    const directSz = getTextByPathList(node, ['a:rPr', 'attrs', 'sz'])
-    if (directSz) {
-      fontSize = parseInt(directSz) / 100
-    }
-  }
-
-  // 检查段落级别的字体大小
-  if (!fontSize || isNaN(fontSize)) {
-    const pPrNode = getTextByPathList(node, ['a:pPr'])
-    if (pPrNode) {
-      const lvl = parseInt(pPrNode.attrs?.lvl || '0')
-
-      // 检查布局中的字体大小设置
-      const layoutSz = getTextByPathList(slideLayoutSpNode, ['p:txBody', 'a:lstStyle', `a:lvl${lvl + 1}pPr`, 'a:defRPr', 'attrs', 'sz'])
-      if (layoutSz) {
-        fontSize = parseInt(layoutSz) / 100
-      }
-
-      // 如果没有找到布局大小,检查母版样式
-      if ((!fontSize || isNaN(fontSize)) && slideMasterTextStyles) {
-        let styleNode
-        if (type === 'title' || type === 'ctrTitle') {
-          styleNode = getTextByPathList(slideMasterTextStyles, ['p:titleStyle'])
-        } else if (type === 'body') {
-          styleNode = getTextByPathList(slideMasterTextStyles, ['p:bodyStyle'])
-        } else if (type === 'subTitle') {
-          styleNode = getTextByPathList(slideMasterTextStyles, ['p:otherStyle'])
-        }
-
-        if (styleNode) {
-          const masterSz = getTextByPathList(styleNode, [`a:lvl${lvl + 1}pPr`, 'a:defRPr', 'attrs', 'sz'])
-          if (masterSz) {
-            fontSize = parseInt(masterSz) / 100
-          }
-        }
-      }
-    }
-  }
-
-  // 4. 如果还是没有找到,使用默认大小
-  if (!fontSize || isNaN(fontSize)) {
-    if (type === 'title' || type === 'ctrTitle') {
-      fontSize = 60 // 标题默认60磅
-    } else if (type === 'subTitle') {
-      fontSize = 32 // 副标题默认32磅
-    } else if (type === 'body') {
-      fontSize = 18 // 正文默认18磅
-    } else {
-      fontSize = 18 // 其他默认18磅
-    }
-  }
-
-  return fontSize + 'pt'
-}
-
-export function getFontBold (node) {
-  return getTextByPathList(node, ['a:rPr', 'attrs', 'b']) === '1' ? 'bold' : ''
-}
-
-export function getFontItalic (node) {
-  return getTextByPathList(node, ['a:rPr', 'attrs', 'i']) === '1' ? 'italic' : ''
-}
-
-export function getFontDecoration (node) {
-  return getTextByPathList(node, ['a:rPr', 'attrs', 'u']) === 'sng' ? 'underline' : ''
-}
-
-export function getFontDecorationLine (node) {
-  return getTextByPathList(node, ['a:rPr', 'attrs', 'strike']) === 'sngStrike' ? 'line-through' : ''
-}
-
-export function getFontSpace (node) {
-  const spc = getTextByPathList(node, ['a:rPr', 'attrs', 'spc'])
-  return spc ? (parseInt(spc) / 100 + 'pt') : ''
-}
-
-export function getFontSubscript (node) {
-  const baseline = getTextByPathList(node, ['a:rPr', 'attrs', 'baseline'])
-  if (!baseline) return ''
-  return parseInt(baseline) > 0 ? 'super' : 'sub'
-}
-
-export function getFontShadow (node, warpObj) {
-  const txtShadow = getTextByPathList(node, ['a:rPr', 'a:effectLst', 'a:outerShdw'])
-  if (txtShadow) {
-    const shadow = getShadow(txtShadow, warpObj)
-    if (shadow) {
-      const { h, v, blur, color } = shadow
-      if (!isNaN(v) && !isNaN(h)) {
-        return h + 'pt ' + v + 'pt ' + (blur ? blur + 'pt' : '') + ' ' + color
-      }
-    }
-  }
-  return ''
-}

+ 0 - 182
src/utils/pptxToJson/math.js

@@ -1,182 +0,0 @@
-import { getTextByPathList } from './utils'
-
-export function findOMath (obj) {
-  let results = []
-  if (typeof obj !== 'object') return results
-  if (obj['m:oMath']) results = results.concat(obj['m:oMath'])
-
-  Object.values(obj).forEach(value => {
-    if (Array.isArray(value) || typeof value === 'object') {
-      results = results.concat(findOMath(value))
-    }
-  })
-  return results
-}
-
-export function parseFraction (fraction) {
-  const numerator = parseOMath(fraction['m:num'])
-  const denominator = parseOMath(fraction['m:den'])
-  return `\\frac{${numerator}}{${denominator}}`
-}
-export function parseSuperscript (superscript) {
-  const base = parseOMath(superscript['m:e'])
-  const sup = parseOMath(superscript['m:sup'])
-  return `${base}^{${sup}}`
-}
-export function parseSubscript (subscript) {
-  const base = parseOMath(subscript['m:e'])
-  const sub = parseOMath(subscript['m:sub'])
-  return `${base}_{${sub}}`
-}
-export function parseRadical (radical) {
-  const degree = parseOMath(radical['m:deg'])
-  const expression = parseOMath(radical['m:e'])
-  return degree ? `\\sqrt[${degree}]{${expression}}` : `\\sqrt{${expression}}`
-}
-export function parseMatrix (matrix) {
-  const rows = matrix['m:mr']
-  const matrixRows = rows.map((row) => {
-    return row['m:e'].map((element) => parseOMath(element)).join(' & ')
-  })
-  return `\\begin{matrix} ${matrixRows.join(' \\\\ ')} \\end{matrix}`
-}
-export function parseNary (nary) {
-  const op = getTextByPathList(nary, ['m:naryPr', 'm:chr', 'attrs', 'm:val']) || '∫'
-  const sub = parseOMath(nary['m:sub'])
-  const sup = parseOMath(nary['m:sup'])
-  const e = parseOMath(nary['m:e'])
-  return `${op}_{${sub}}^{${sup}}{${e}}`
-}
-export function parseLimit (limit, type) {
-  const base = parseOMath(limit['m:e'])
-  const lim = parseOMath(limit['m:lim'])
-  return type === 'low' ? `${base}_{${lim}}` : `${base}^{${lim}}`
-}
-export function parseDelimiter (delimiter) {
-  let left = getTextByPathList(delimiter, ['m:dPr', 'm:begChr', 'attrs', 'm:val'])
-  let right = getTextByPathList(delimiter, ['m:dPr', 'm:endChr', 'attrs', 'm:val'])
-  if (!left && !right) {
-    left = '('
-    right = ')'
-  }
-  if (left && right) {
-    left = `\\left${left}`
-    right = `\\right${right}`
-  }
-  const e = parseOMath(delimiter['m:e'])
-  return `${left}${e}${right}`
-}
-export function parseFunction (func) {
-  const name = parseOMath(func['m:fName'])
-  const arg = parseOMath(func['m:e'])
-  return `\\${name}{${arg}}`
-}
-export function parseGroupChr (groupChr) {
-  const chr = getTextByPathList(groupChr, ['m:groupChrPr', 'm:chr', 'attrs', 'm:val'])
-  const e = parseOMath(groupChr['m:e'])
-  return `${chr}${e}${chr}`
-}
-export function parseEqArr (eqArr) {
-  const equations = eqArr['m:e'].map((eq) => parseOMath(eq)).join(' \\\\ ')
-  return `\\begin{cases} ${equations} \\end{cases}`
-}
-export function parseBar (bar) {
-  const e = parseOMath(bar['m:e'])
-  const pos = getTextByPathList(bar, ['m:barPr', 'm:pos', 'attrs', 'm:val'])
-  return pos === 'top' ? `\\overline{${e}}` : `\\underline{${e}}`
-}
-export function parseAccent (accent) {
-  const chr = getTextByPathList(accent, ['m:accPr', 'm:chr', 'attrs', 'm:val']) || '^'
-  const e = parseOMath(accent['m:e'])
-  switch (chr) {
-    case '\u0301':
-      return `\\acute{${e}}`
-    case '\u0300':
-      return `\\grave{${e}}`
-    case '\u0302':
-      return `\\hat{${e}}`
-    case '\u0303':
-      return `\\tilde{${e}}`
-    case '\u0304':
-      return `\\bar{${e}}`
-    case '\u0306':
-      return `\\breve{${e}}`
-    case '\u0307':
-      return `\\dot{${e}}`
-    case '\u0308':
-      return `\\ddot{${e}}`
-    case '\u030A':
-      return `\\mathring{${e}}`
-    case '\u030B':
-      return `\\H{${e}}`
-    case '\u030C':
-      return `\\check{${e}}`
-    case '\u0327':
-      return `\\c{${e}}`
-    default:
-      return `\\${chr}{${e}}`
-  }
-}
-export function parseBox (box) {
-  const e = parseOMath(box['m:e'])
-  return `\\boxed{${e}}`
-}
-
-export function parseOMath (oMath) {
-  if (!oMath) return ''
-
-  if (Array.isArray(oMath)) {
-    return oMath.map(item => parseOMath(item)).join('')
-  }
-
-  const oMathList = []
-  const keys = Object.keys(oMath)
-  for (const key of keys) {
-    if (Array.isArray(oMath[key])) {
-      oMathList.push(...oMath[key].map(item => ({ key, value: item })))
-    } else oMathList.push({ key, value: oMath[key] })
-  }
-
-  oMathList.sort((a, b) => {
-    let oA = 0
-    if (a.key === 'm:r' && a.value && a.value['a:rPr']) oA = a.value['a:rPr']['attrs']['order']
-    else if (a.value[`${a.key}Pr`] && a.value[`${a.key}Pr`]['m:ctrlPr'] && a.value[`${a.key}Pr`]['m:ctrlPr']['a:rPr']) {
-      oA = a.value[`${a.key}Pr`] && a.value[`${a.key}Pr`]['m:ctrlPr'] && a.value[`${a.key}Pr`]['m:ctrlPr']['a:rPr'] && a.value[`${a.key}Pr`]['m:ctrlPr']['a:rPr']['attrs']['order']
-    }
-    let oB = 0
-    if (b.key === 'm:r' && b.value && b.value['a:rPr']) oB = b.value['a:rPr']['attrs']['order']
-    else if (b.value[`${b.key}Pr`] && b.value[`${b.key}Pr`]['m:ctrlPr'] && b.value[`${b.key}Pr`]['m:ctrlPr']['a:rPr']) {
-      oB = b.value[`${b.key}Pr`] && b.value[`${b.key}Pr`]['m:ctrlPr'] && b.value[`${b.key}Pr`]['m:ctrlPr']['a:rPr'] && b.value[`${b.key}Pr`]['m:ctrlPr']['a:rPr']['attrs']['order']
-    }
-    return oA - oB
-  })
-
-  return oMathList.map(({ key, value }) => {
-    if (key === 'm:f') return parseFraction(value)
-    if (key === 'm:sSup') return parseSuperscript(value)
-    if (key === 'm:sSub') return parseSubscript(value)
-    if (key === 'm:rad') return parseRadical(value)
-    if (key === 'm:nary') return parseNary(value)
-    if (key === 'm:limLow') return parseLimit(value, 'low')
-    if (key === 'm:limUpp') return parseLimit(value, 'upp')
-    if (key === 'm:d') return parseDelimiter(value)
-    if (key === 'm:func') return parseFunction(value)
-    if (key === 'm:groupChr') return parseGroupChr(value)
-    if (key === 'm:eqArr') return parseEqArr(value)
-    if (key === 'm:bar') return parseBar(value)
-    if (key === 'm:acc') return parseAccent(value)
-    if (key === 'm:borderBox') return parseBox(value)
-    if (key === 'm:m') return parseMatrix(value)
-    if (key === 'm:r') return parseOMath(value)
-    if (key === 'm:t') return value
-    return ''
-  }).join('')
-}
-
-export function latexFormart (latex) {
-  return latex.replaceAll(/&lt;/g, '<')
-    .replaceAll(/&gt;/g, '>')
-    .replaceAll(/&amp;/g, '&')
-    .replaceAll(/&apos;/g, "'")
-    .replaceAll(/&quot;/g, '"')
-}

+ 0 - 38
src/utils/pptxToJson/position.js

@@ -1,38 +0,0 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-21 16:39:43
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-21 16:41:33
- * @Description:
- */
-import { RATIO_EMUs_Points } from './constants'
-
-export function getPosition (slideSpNode, slideLayoutSpNode, slideMasterSpNode) {
-  let off
-
-  if (slideSpNode) off = slideSpNode['a:off']['attrs']
-  else if (slideLayoutSpNode) off = slideLayoutSpNode['a:off']['attrs']
-  else if (slideMasterSpNode) off = slideMasterSpNode['a:off']['attrs']
-
-  if (!off) return { top: 0, left: 0 }
-
-  return {
-    top: parseInt(off['y']) * RATIO_EMUs_Points,
-    left: parseInt(off['x']) * RATIO_EMUs_Points
-  }
-}
-
-export function getSize (slideSpNode, slideLayoutSpNode, slideMasterSpNode) {
-  let ext
-
-  if (slideSpNode) ext = slideSpNode['a:ext']['attrs']
-  else if (slideLayoutSpNode) ext = slideLayoutSpNode['a:ext']['attrs']
-  else if (slideMasterSpNode) ext = slideMasterSpNode['a:ext']['attrs']
-
-  if (!ext) return { width: 0, height: 0 }
-
-  return {
-    width: parseInt(ext['cx']) * RATIO_EMUs_Points,
-    height: parseInt(ext['cy']) * RATIO_EMUs_Points
-  }
-}

+ 0 - 1699
src/utils/pptxToJson/pptxtojson.js

@@ -1,1699 +0,0 @@
-import JSZip from 'jszip'
-import { readXmlFile } from './readXmlFile'
-import { getBorder } from './border'
-import {
-  getSlideBackgroundFill,
-  getShapeFill,
-  getSolidFill,
-  getPicFill
-} from './fill'
-import { getChartInfo } from './chart'
-import { getVerticalAlign } from './align'
-import { getPosition, getSize } from './position'
-import { genTextBody } from './text'
-import { getCustomShapePath } from './shape'
-import {
-  extractFileExtension,
-  base64ArrayBuffer,
-  getTextByPathList,
-  angleToDegrees,
-  getMimeType,
-  isVideoLink,
-  escapeHtml,
-  hasValidText
-} from './utils'
-import { getShadow } from './shadow'
-import {
-  getTableBorders,
-  getTableCellParams,
-  getTableRowParams
-} from './table'
-import { RATIO_EMUs_Points } from './constants'
-import { findOMath, latexFormart, parseOMath } from './math'
-
-export async function parse (file) {
-  const slides = []
-  const zip = await JSZip.loadAsync(file)
-  const filesInfo = await getContentTypes(zip)
-  const { width, height, defaultTextStyle } = await getSlideInfo(zip)
-
-  // 获取所有主题文件
-  const themeMap = await getAllThemes(zip)
-
-  for (const filename of filesInfo.slides) {
-    // 为每个幻灯片获取对应的主题
-    const { themeContent, themeColors } = await getSlideTheme(
-      zip,
-      filename,
-      themeMap
-    )
-    const singleSlide = await processSingleSlide(
-      zip,
-      filename,
-      themeContent,
-      defaultTextStyle
-    )
-    slides.push({
-      ...singleSlide,
-      themeColors // 为每个幻灯片添加其对应的主题颜色
-    })
-  }
-
-  return {
-    slides,
-    size: {
-      width,
-      height
-    }
-  }
-}
-
-async function getSlideInfo (zip) {
-  const content = await readXmlFile(zip, 'ppt/presentation.xml')
-  const sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']
-  const defaultTextStyle = content['p:presentation']['p:defaultTextStyle']
-  return {
-    width: parseInt(sldSzAttrs['cx']) * RATIO_EMUs_Points,
-    height: parseInt(sldSzAttrs['cy']) * RATIO_EMUs_Points,
-    defaultTextStyle
-  }
-}
-
-async function getContentTypes (zip) {
-  const ContentTypesJson = await readXmlFile(zip, '[Content_Types].xml')
-  const subObj = ContentTypesJson['Types']['Override']
-  let slidesLocArray = []
-  let slideLayoutsLocArray = []
-  let themeLocArray = []
-
-  for (const item of subObj) {
-    switch (item['attrs']['ContentType']) {
-      case 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml':
-        slidesLocArray.push(item['attrs']['PartName'].substr(1))
-        break
-      case 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml':
-        slideLayoutsLocArray.push(item['attrs']['PartName'].substr(1))
-        break
-      case 'application/vnd.openxmlformats-officedocument.theme+xml':
-        themeLocArray.push(item['attrs']['PartName'].substr(1))
-        break
-      default:
-    }
-  }
-
-  const sortSlideXml = (p1, p2) => {
-    const n1 = +/(\d+)\.xml/.exec(p1)[1]
-    const n2 = +/(\d+)\.xml/.exec(p2)[1]
-    return n1 - n2
-  }
-  slidesLocArray = slidesLocArray.sort(sortSlideXml)
-  slideLayoutsLocArray = slideLayoutsLocArray.sort(sortSlideXml)
-  themeLocArray = themeLocArray.sort(sortSlideXml)
-
-  return {
-    slides: slidesLocArray,
-    slideLayouts: slideLayoutsLocArray,
-    themes: themeLocArray
-  }
-}
-
-// 获取所有主题文件并建立映射关系
-async function getAllThemes (zip) {
-  const themeMap = new Map()
-
-  const filesInfo = await getContentTypes(zip)
-
-    // 从 Content_Types.xml 中获取主题文件路径
-    for (const themePath of filesInfo.themes) {
-        const themeContent = await readXmlFile(zip, themePath)
-        themeMap.set(themePath, { themeContent, masterId: null })
-    }
-
-    // 获取母版与主题的对应关系
-    const preResContent = await readXmlFile(
-      zip,
-      'ppt/_rels/presentation.xml.rels'
-    )
-    const presentationContent = await readXmlFile(zip, 'ppt/presentation.xml')
-    const masterIdList = getTextByPathList(presentationContent, [
-      'p:presentation',
-      'p:sldMasterIdLst',
-      'p:sldMasterId'
-    ])
-
-    if (masterIdList) {
-      const relationshipArray = preResContent['Relationships']['Relationship']
-      const masters = Array.isArray(masterIdList)
-        ? masterIdList
-        : [masterIdList]
-
-      for (const master of masters) {
-        const masterId = master['attrs']['r:id']
-        const masterRel = Array.isArray(relationshipArray)
-          ? relationshipArray.find((rel) => rel['attrs']['Id'] === masterId)
-          : relationshipArray['attrs']['Id'] === masterId
-            ? relationshipArray
-            : null
-
-        if (masterRel) {
-          const masterTarget = masterRel['attrs']['Target'].replace(
-            '../',
-            'ppt/'
-          )
-          const masterRelsPath =
-            masterTarget.replace(
-              'slideMasters/slideMaster',
-              'slideMasters/_rels/slideMaster'
-            ) + '.rels'
-
-            const masterRels = await readXmlFile(zip, masterRelsPath)
-            if (masterRels && masterRels['Relationships']) {
-              const relationships = masterRels['Relationships']['Relationship']
-              const themeRel = Array.isArray(relationships)
-                ? relationships.find((rel) =>
-                  rel['attrs']['Type'].endsWith('/theme')
-                )
-                : relationships['attrs']['Type'].endsWith('/theme')
-                  ? relationships
-                  : null
-
-              if (themeRel) {
-                const themeURI = themeRel['attrs']['Target'].replace('../', '')
-                const themePath = 'ppt/' + themeURI
-
-                // 更新主题映射中的 masterId
-                if (themeMap.has(themePath)) {
-                  const themeData = themeMap.get(themePath)
-                  themeData.masterId = masterId
-                  themeMap.set(masterTarget, themeData)
-                }
-              }
-            }
-        }
-      }
-    }
-
-  return themeMap
-}
-
-// 获取单个幻灯片对应的主题
-async function getSlideTheme (zip, slideFilename, themeMap) {
-  try {
-    // 获取幻灯片的布局信息
-    const slideRelsPath =
-      slideFilename.replace('slides/slide', 'slides/_rels/slide') + '.rels'
-    const slideRels = await readXmlFile(zip, slideRelsPath)
-
-    if (!slideRels?.Relationships?.Relationship) {
-      return { themeContent: {}, themeColors: [] }
-    }
-
-    // 获取布局文件路径
-    const relationships = slideRels['Relationships']['Relationship']
-    const layoutRel = Array.isArray(relationships)
-      ? relationships.find((rel) =>
-        rel['attrs']['Type'].endsWith('/slideLayout')
-      )
-      : relationships['attrs']['Type'].endsWith('/slideLayout')
-        ? relationships
-        : null
-
-    if (!layoutRel) return { themeContent: {}, themeColors: [] }
-
-    const layoutPath = 'ppt/' + layoutRel['attrs']['Target'].replace('../', '')
-    const layoutRelsPath =
-      layoutPath.replace(
-        'slideLayouts/slideLayout',
-        'slideLayouts/_rels/slideLayout'
-      ) + '.rels'
-
-    // 获取母版文件路径
-    const layoutRels = await readXmlFile(zip, layoutRelsPath)
-    if (!layoutRels?.Relationships?.Relationship) {
-      return { themeContent: {}, themeColors: [] }
-    }
-
-    const masterRelationships = layoutRels['Relationships']['Relationship']
-    const masterRel = Array.isArray(masterRelationships)
-      ? masterRelationships.find((rel) =>
-        rel['attrs']['Type'].endsWith('/slideMaster')
-      )
-      : masterRelationships['attrs']['Type'].endsWith('/slideMaster')
-        ? masterRelationships
-        : null
-
-    if (!masterRel) return { themeContent: {}, themeColors: [] }
-
-    const masterPath = 'ppt/' + masterRel['attrs']['Target'].replace('../', '')
-    const masterRelsPath =
-      masterPath.replace(
-        'slideMasters/slideMaster',
-        'slideMasters/_rels/slideMaster'
-      ) + '.rels'
-
-    // 获取主题关系
-    const masterRels = await readXmlFile(zip, masterRelsPath)
-    if (!masterRels?.Relationships?.Relationship) {
-      return { themeContent: {}, themeColors: [] }
-    }
-
-    const themeRelationships = masterRels['Relationships']['Relationship']
-    const themeRel = Array.isArray(themeRelationships)
-      ? themeRelationships.find((rel) =>
-        rel['attrs']['Type'].endsWith('/theme')
-      )
-      : themeRelationships['attrs']['Type'].endsWith('/theme')
-        ? themeRelationships
-        : null
-
-    if (!themeRel) return { themeContent: {}, themeColors: [] }
-
-    const themePath = 'ppt/' + themeRel['attrs']['Target'].replace('../', '')
-    const themeData = themeMap.get(themePath)
-
-    if (!themeData?.themeContent) return { themeContent: {}, themeColors: [] }
-
-    // 提取主题颜色
-    const themeColors = []
-    const clrScheme = getTextByPathList(themeData.themeContent, [
-      'a:theme',
-      'a:themeElements',
-      'a:clrScheme'
-    ])
-
-    if (clrScheme) {
-      for (let i = 1; i <= 6; i++) {
-        if (clrScheme[`a:accent${i}`] === undefined) break
-        const color = getTextByPathList(clrScheme, [
-          `a:accent${i}`,
-          'a:srgbClr',
-          'attrs',
-          'val'
-        ])
-        if (color) themeColors.push('#' + color)
-      }
-    }
-
-    return { themeContent: themeData.themeContent, themeColors }
-  } catch (error) {
-    return { themeContent: {}, themeColors: [] }
-  }
-}
-
-async function processSingleSlide (
-  zip,
-  sldFileName,
-  themeContent,
-  defaultTextStyle
-) {
-  const resName =
-    sldFileName.replace('slides/slide', 'slides/_rels/slide') + '.rels'
-  const resContent = await readXmlFile(zip, resName)
-  let relationshipArray = resContent['Relationships']['Relationship']
-  if (relationshipArray.constructor !== Array) { relationshipArray = [relationshipArray] }
-
-  let noteFilename = ''
-  let layoutFilename = ''
-  let masterFilename = ''
-  let themeFilename = ''
-  let diagramFilename = ''
-  const slideResObj = {}
-  const layoutResObj = {}
-  const masterResObj = {}
-  const themeResObj = {}
-  const diagramResObj = {}
-
-  for (const relationshipArrayItem of relationshipArray) {
-    switch (relationshipArrayItem['attrs']['Type']) {
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout':
-        layoutFilename = relationshipArrayItem['attrs']['Target'].replace(
-          '../',
-          'ppt/'
-        )
-        break
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide':
-        noteFilename = relationshipArrayItem['attrs']['Target'].replace(
-          '../',
-          'ppt/'
-        )
-        break
-      case 'http://schemas.microsoft.com/office/2007/relationships/diagramDrawing':
-        diagramFilename = relationshipArrayItem['attrs']['Target'].replace(
-          '../',
-          'ppt/'
-        )
-        slideResObj[relationshipArrayItem['attrs']['Id']] = {
-          type: relationshipArrayItem['attrs']['Type'].replace(
-            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/',
-            ''
-          ),
-          target: relationshipArrayItem['attrs']['Target'].replace(
-            '../',
-            'ppt/'
-          )
-        }
-        break
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image':
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart':
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink':
-      default:
-        slideResObj[relationshipArrayItem['attrs']['Id']] = {
-          type: relationshipArrayItem['attrs']['Type'].replace(
-            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/',
-            ''
-          ),
-          target: relationshipArrayItem['attrs']['Target'].replace(
-            '../',
-            'ppt/'
-          )
-        }
-    }
-  }
-
-  const slideNotesContent = await readXmlFile(zip, noteFilename)
-  const note = getNote(slideNotesContent)
-
-  const slideLayoutContent = await readXmlFile(zip, layoutFilename)
-  const slideLayoutTables = await indexNodes(slideLayoutContent)
-  const slideLayoutResFilename =
-    layoutFilename.replace(
-      'slideLayouts/slideLayout',
-      'slideLayouts/_rels/slideLayout'
-    ) + '.rels'
-  const slideLayoutResContent = await readXmlFile(zip, slideLayoutResFilename)
-  relationshipArray = slideLayoutResContent['Relationships']['Relationship']
-  if (relationshipArray.constructor !== Array) { relationshipArray = [relationshipArray] }
-
-  for (const relationshipArrayItem of relationshipArray) {
-    switch (relationshipArrayItem['attrs']['Type']) {
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster':
-        masterFilename = relationshipArrayItem['attrs']['Target'].replace(
-          '../',
-          'ppt/'
-        )
-        break
-      default:
-        layoutResObj[relationshipArrayItem['attrs']['Id']] = {
-          type: relationshipArrayItem['attrs']['Type'].replace(
-            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/',
-            ''
-          ),
-          target: relationshipArrayItem['attrs']['Target'].replace(
-            '../',
-            'ppt/'
-          )
-        }
-    }
-  }
-
-  const slideMasterContent = await readXmlFile(zip, masterFilename)
-  const slideMasterTextStyles = getTextByPathList(slideMasterContent, [
-    'p:sldMaster',
-    'p:txStyles'
-  ])
-  const slideMasterTables = indexNodes(slideMasterContent)
-  const slideMasterResFilename =
-    masterFilename.replace(
-      'slideMasters/slideMaster',
-      'slideMasters/_rels/slideMaster'
-    ) + '.rels'
-  const slideMasterResContent = await readXmlFile(zip, slideMasterResFilename)
-  relationshipArray = slideMasterResContent['Relationships']['Relationship']
-  if (relationshipArray.constructor !== Array) { relationshipArray = [relationshipArray] }
-
-  for (const relationshipArrayItem of relationshipArray) {
-    switch (relationshipArrayItem['attrs']['Type']) {
-      case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme':
-        themeFilename = relationshipArrayItem['attrs']['Target'].replace(
-          '../',
-          'ppt/'
-        )
-        break
-      default:
-        masterResObj[relationshipArrayItem['attrs']['Id']] = {
-          type: relationshipArrayItem['attrs']['Type'].replace(
-            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/',
-            ''
-          ),
-          target: relationshipArrayItem['attrs']['Target'].replace(
-            '../',
-            'ppt/'
-          )
-        }
-    }
-  }
-
-  if (themeFilename) {
-    const themeName = themeFilename.split('/').pop()
-    const themeResFileName =
-      themeFilename.replace(themeName, '_rels/' + themeName) + '.rels'
-    const themeResContent = await readXmlFile(zip, themeResFileName)
-    if (themeResContent) {
-      relationshipArray = themeResContent['Relationships']['Relationship']
-      if (relationshipArray) {
-        if (relationshipArray.constructor !== Array) { relationshipArray = [relationshipArray] }
-        for (const relationshipArrayItem of relationshipArray) {
-          themeResObj[relationshipArrayItem['attrs']['Id']] = {
-            type: relationshipArrayItem['attrs']['Type'].replace(
-              'http://schemas.openxmlformats.org/officeDocument/2006/relationships/',
-              ''
-            ),
-            target: relationshipArrayItem['attrs']['Target'].replace(
-              '../',
-              'ppt/'
-            )
-          }
-        }
-      }
-    }
-  }
-
-  let digramFileContent = {}
-  if (diagramFilename) {
-    const diagName = diagramFilename.split('/').pop()
-    const diagramResFileName =
-      diagramFilename.replace(diagName, '_rels/' + diagName) + '.rels'
-    digramFileContent = await readXmlFile(zip, diagramFilename)
-    if (digramFileContent) {
-      const digramFileContentObjToStr = JSON.stringify(
-        digramFileContent
-      ).replace(/dsp:/g, 'p:')
-      digramFileContent = JSON.parse(digramFileContentObjToStr)
-    }
-    const digramResContent = await readXmlFile(zip, diagramResFileName)
-    if (digramResContent) {
-      relationshipArray = digramResContent['Relationships']['Relationship']
-      if (relationshipArray.constructor !== Array) { relationshipArray = [relationshipArray] }
-      for (const relationshipArrayItem of relationshipArray) {
-        diagramResObj[relationshipArrayItem['attrs']['Id']] = {
-          type: relationshipArrayItem['attrs']['Type'].replace(
-            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/',
-            ''
-          ),
-          target: relationshipArrayItem['attrs']['Target'].replace(
-            '../',
-            'ppt/'
-          )
-        }
-      }
-    }
-  }
-
-  const tableStyles = await readXmlFile(zip, 'ppt/tableStyles.xml')
-
-  const slideContent = await readXmlFile(zip, sldFileName)
-  const nodes = slideContent['p:sld']['p:cSld']['p:spTree']
-  const warpObj = {
-    zip,
-    slideLayoutContent,
-    slideLayoutTables,
-    slideMasterContent,
-    slideMasterTables,
-    slideContent,
-    tableStyles,
-    slideResObj,
-    slideMasterTextStyles,
-    layoutResObj,
-    masterResObj,
-    themeContent,
-    themeResObj,
-    digramFileContent,
-    diagramResObj,
-    defaultTextStyle
-  }
-  const layoutElements = await getLayoutElements(warpObj)
-  const fill = await getSlideBackgroundFill(warpObj)
-
-  const elements = []
-  for (const nodeKey in nodes) {
-    if (nodes[nodeKey].constructor !== Array) nodes[nodeKey] = [nodes[nodeKey]]
-    for (const node of nodes[nodeKey]) {
-      const ret = await processNodesInSlide(
-        nodeKey,
-        node,
-        nodes,
-        warpObj,
-        'slide'
-      )
-      if (ret) elements.push(ret)
-    }
-  }
-
-  return {
-    fill,
-    elements,
-    layoutElements,
-    note
-  }
-}
-
-function getNote (noteContent) {
-  let text = ''
-  let spNodes = getTextByPathList(noteContent, [
-    'p:notes',
-    'p:cSld',
-    'p:spTree',
-    'p:sp'
-  ])
-  if (!spNodes) return ''
-
-  if (spNodes.constructor !== Array) spNodes = [spNodes]
-  for (const spNode of spNodes) {
-    let rNodes = getTextByPathList(spNode, ['p:txBody', 'a:p', 'a:r'])
-    if (!rNodes) continue
-
-    if (rNodes.constructor !== Array) rNodes = [rNodes]
-    for (const rNode of rNodes) {
-      const t = getTextByPathList(rNode, ['a:t'])
-      if (t && typeof t === 'string') text += t
-    }
-  }
-  return text
-}
-
-async function getLayoutElements (warpObj) {
-  const elements = []
-  const slideLayoutContent = warpObj['slideLayoutContent']
-  const slideMasterContent = warpObj['slideMasterContent']
-  const nodesSldLayout = getTextByPathList(slideLayoutContent, [
-    'p:sldLayout',
-    'p:cSld',
-    'p:spTree'
-  ])
-  const nodesSldMaster = getTextByPathList(slideMasterContent, [
-    'p:sldMaster',
-    'p:cSld',
-    'p:spTree'
-  ])
-
-  const showMasterSp = getTextByPathList(slideLayoutContent, [
-    'p:sldLayout',
-    'attrs',
-    'showMasterSp'
-  ])
-  if (nodesSldLayout) {
-    for (const nodeKey in nodesSldLayout) {
-      if (nodesSldLayout[nodeKey].constructor === Array) {
-        for (let i = 0; i < nodesSldLayout[nodeKey].length; i++) {
-          const ph = getTextByPathList(nodesSldLayout[nodeKey][i], [
-            'p:nvSpPr',
-            'p:nvPr',
-            'p:ph'
-          ])
-          if (!ph) {
-            const ret = await processNodesInSlide(
-              nodeKey,
-              nodesSldLayout[nodeKey][i],
-              nodesSldLayout,
-              warpObj,
-              'slideLayoutBg'
-            )
-            if (ret) elements.push(ret)
-          }
-        }
-      } else {
-        const ph = getTextByPathList(nodesSldLayout[nodeKey], [
-          'p:nvSpPr',
-          'p:nvPr',
-          'p:ph'
-        ])
-        if (!ph) {
-          const ret = await processNodesInSlide(
-            nodeKey,
-            nodesSldLayout[nodeKey],
-            nodesSldLayout,
-            warpObj,
-            'slideLayoutBg'
-          )
-          if (ret) elements.push(ret)
-        }
-      }
-    }
-  }
-  if (nodesSldMaster && showMasterSp !== '0') {
-    for (const nodeKey in nodesSldMaster) {
-      if (nodesSldMaster[nodeKey].constructor === Array) {
-        for (let i = 0; i < nodesSldMaster[nodeKey].length; i++) {
-          const ph = getTextByPathList(nodesSldMaster[nodeKey][i], [
-            'p:nvSpPr',
-            'p:nvPr',
-            'p:ph'
-          ])
-          if (!ph) {
-            const ret = await processNodesInSlide(
-              nodeKey,
-              nodesSldMaster[nodeKey][i],
-              nodesSldMaster,
-              warpObj,
-              'slideMasterBg'
-            )
-            if (ret) elements.push(ret)
-          }
-        }
-      } else {
-        const ph = getTextByPathList(nodesSldMaster[nodeKey], [
-          'p:nvSpPr',
-          'p:nvPr',
-          'p:ph'
-        ])
-        if (!ph) {
-          const ret = await processNodesInSlide(
-            nodeKey,
-            nodesSldMaster[nodeKey],
-            nodesSldMaster,
-            warpObj,
-            'slideMasterBg'
-          )
-          if (ret) elements.push(ret)
-        }
-      }
-    }
-  }
-  return elements
-}
-
-function indexNodes (content) {
-  const keys = Object.keys(content)
-  const spTreeNode = content[keys[0]]['p:cSld']['p:spTree']
-  const idTable = {}
-  const idxTable = {}
-  const typeTable = {}
-
-  for (const key in spTreeNode) {
-    if (key === 'p:nvGrpSpPr' || key === 'p:grpSpPr') continue
-
-    const targetNode = spTreeNode[key]
-
-    if (targetNode.constructor === Array) {
-      for (const targetNodeItem of targetNode) {
-        const nvSpPrNode = targetNodeItem['p:nvSpPr']
-        const id = getTextByPathList(nvSpPrNode, ['p:cNvPr', 'attrs', 'id'])
-        const idx = getTextByPathList(nvSpPrNode, [
-          'p:nvPr',
-          'p:ph',
-          'attrs',
-          'idx'
-        ])
-        const type = getTextByPathList(nvSpPrNode, [
-          'p:nvPr',
-          'p:ph',
-          'attrs',
-          'type'
-        ])
-
-        if (id) idTable[id] = targetNodeItem
-        if (idx) idxTable[idx] = targetNodeItem
-        if (type) typeTable[type] = targetNodeItem
-      }
-    } else {
-      const nvSpPrNode = targetNode['p:nvSpPr']
-      const id = getTextByPathList(nvSpPrNode, ['p:cNvPr', 'attrs', 'id'])
-      const idx = getTextByPathList(nvSpPrNode, [
-        'p:nvPr',
-        'p:ph',
-        'attrs',
-        'idx'
-      ])
-      const type = getTextByPathList(nvSpPrNode, [
-        'p:nvPr',
-        'p:ph',
-        'attrs',
-        'type'
-      ])
-
-      if (id) idTable[id] = targetNode
-      if (idx) idxTable[idx] = targetNode
-      if (type) typeTable[type] = targetNode
-    }
-  }
-
-  return { idTable, idxTable, typeTable }
-}
-
-async function processNodesInSlide (nodeKey, nodeValue, nodes, warpObj, source) {
-  let json
-
-  switch (nodeKey) {
-    case 'p:sp': // Shape, Text
-      json = await processSpNode(nodeValue, nodes, warpObj, source)
-      break
-    case 'p:cxnSp': // Shape, Text
-      json = await processCxnSpNode(nodeValue, nodes, warpObj, source)
-      break
-    case 'p:pic': // Image, Video, Audio
-      json = await processPicNode(nodeValue, warpObj, source)
-      break
-    case 'p:graphicFrame': // Chart, Diagram, Table
-      json = await processGraphicFrameNode(nodeValue, warpObj, source)
-      break
-    case 'p:grpSp':
-      json = await processGroupSpNode(nodeValue, warpObj, source)
-      break
-    case 'mc:AlternateContent':
-      if (
-        getTextByPathList(nodeValue, ['mc:Fallback', 'p:grpSpPr', 'a:xfrm'])
-      ) {
-        json = await processGroupSpNode(
-          getTextByPathList(nodeValue, ['mc:Fallback']),
-          warpObj,
-          source
-        )
-      } else if (getTextByPathList(nodeValue, ['mc:Choice'])) {
-        json = await processMathNode(nodeValue, warpObj, source)
-      }
-      break
-    default:
-  }
-
-  return json
-}
-
-async function processMathNode (node, warpObj, source) {
-  const choice = getTextByPathList(node, ['mc:Choice'])
-  const fallback = getTextByPathList(node, ['mc:Fallback'])
-
-  const order = node['attrs']['order']
-  const xfrmNode = getTextByPathList(choice, ['p:sp', 'p:spPr', 'a:xfrm'])
-  const { top, left } = getPosition(xfrmNode, undefined, undefined)
-  const { width, height } = getSize(xfrmNode, undefined, undefined)
-
-  const oMath = findOMath(choice)[0]
-  const latex = latexFormart(parseOMath(oMath))
-
-  const blipFill = getTextByPathList(fallback, [
-    'p:sp',
-    'p:spPr',
-    'a:blipFill'
-  ])
-  const picBase64 = await getPicFill(source, blipFill, warpObj)
-
-  return {
-    type: 'math',
-    top,
-    left,
-    width,
-    height,
-    latex,
-    picBase64,
-    order
-  }
-}
-
-async function processGroupSpNode (node, warpObj, source) {
-  const order = node['attrs']['order']
-  const xfrmNode = getTextByPathList(node, ['p:grpSpPr', 'a:xfrm'])
-  if (!xfrmNode) return null
-
-  const x = parseInt(xfrmNode['a:off']['attrs']['x']) * RATIO_EMUs_Points
-  const y = parseInt(xfrmNode['a:off']['attrs']['y']) * RATIO_EMUs_Points
-  const chx = parseInt(xfrmNode['a:chOff']['attrs']['x']) * RATIO_EMUs_Points
-  const chy = parseInt(xfrmNode['a:chOff']['attrs']['y']) * RATIO_EMUs_Points
-  const cx = parseInt(xfrmNode['a:ext']['attrs']['cx']) * RATIO_EMUs_Points
-  const cy = parseInt(xfrmNode['a:ext']['attrs']['cy']) * RATIO_EMUs_Points
-  const chcx = parseInt(xfrmNode['a:chExt']['attrs']['cx']) * RATIO_EMUs_Points
-  const chcy = parseInt(xfrmNode['a:chExt']['attrs']['cy']) * RATIO_EMUs_Points
-
-  const isFlipV = getTextByPathList(xfrmNode, ['attrs', 'flipV']) === '1'
-  const isFlipH = getTextByPathList(xfrmNode, ['attrs', 'flipH']) === '1'
-
-  let rotate = getTextByPathList(xfrmNode, ['attrs', 'rot']) || 0
-  if (rotate) rotate = angleToDegrees(rotate)
-
-  const ws = cx / chcx
-  const hs = cy / chcy
-
-  const elements = []
-  for (const nodeKey in node) {
-    if (node[nodeKey].constructor === Array) {
-      for (const item of node[nodeKey]) {
-        const ret = await processNodesInSlide(
-          nodeKey,
-          item,
-          node,
-          warpObj,
-          source
-        )
-        if (ret) {
-          // 如果是嵌套的组合,需要调整其子元素的位置和大小
-          if (ret.type === 'group') {
-            ret.elements = ret.elements.map((element) => ({
-              ...element,
-              left: element.left * ws,
-              top: element.top * hs,
-              width: element.width * ws,
-              height: element.height * hs
-            }))
-          }
-          elements.push(ret)
-        }
-      }
-    } else {
-      const ret = await processNodesInSlide(
-        nodeKey,
-        node[nodeKey],
-        node,
-        warpObj,
-        source
-      )
-      if (ret) {
-        // 如果是嵌套的组合,需要调整其子元素的位置和大小
-        if (ret.type === 'group') {
-          ret.elements = ret.elements.map((element) => ({
-            ...element,
-            left: element.left * ws,
-            top: element.top * hs,
-            width: element.width * ws,
-            height: element.height * hs
-          }))
-        }
-        elements.push(ret)
-      }
-    }
-  }
-
-  return {
-    type: 'group',
-    top: y,
-    left: x,
-    width: cx,
-    height: cy,
-    rotate,
-    order,
-    isFlipV,
-    isFlipH,
-    elements: elements.map((element) => ({
-      ...element,
-      left: (element.left - chx) * ws,
-      top: (element.top - chy) * hs,
-      width: element.width * ws,
-      height: element.height * hs
-    }))
-  }
-}
-
-async function processSpNode (node, pNode, warpObj, source) {
-  const name = getTextByPathList(node, [
-    'p:nvSpPr',
-    'p:cNvPr',
-    'attrs',
-    'name'
-  ])
-  const idx = getTextByPathList(node, [
-    'p:nvSpPr',
-    'p:nvPr',
-    'p:ph',
-    'attrs',
-    'idx'
-  ])
-  let type = getTextByPathList(node, [
-    'p:nvSpPr',
-    'p:nvPr',
-    'p:ph',
-    'attrs',
-    'type'
-  ])
-  const order = getTextByPathList(node, ['attrs', 'order'])
-
-  let slideLayoutSpNode, slideMasterSpNode
-
-  if (type) {
-    if (idx) {
-      slideLayoutSpNode = warpObj['slideLayoutTables']['typeTable'][type]
-      slideMasterSpNode = warpObj['slideMasterTables']['typeTable'][type]
-    } else {
-      slideLayoutSpNode = warpObj['slideLayoutTables']['typeTable'][type]
-      slideMasterSpNode = warpObj['slideMasterTables']['typeTable'][type]
-    }
-  } else if (idx) {
-    slideLayoutSpNode = warpObj['slideLayoutTables']['idxTable'][idx]
-    slideMasterSpNode = warpObj['slideMasterTables']['idxTable'][idx]
-  }
-
-  if (!type) {
-    const txBoxVal = getTextByPathList(node, [
-      'p:nvSpPr',
-      'p:cNvSpPr',
-      'attrs',
-      'txBox'
-    ])
-    if (txBoxVal === '1') type = 'text'
-  }
-  if (!type) {
-    type = getTextByPathList(slideLayoutSpNode, [
-      'p:nvSpPr',
-      'p:nvPr',
-      'p:ph',
-      'attrs',
-      'type'
-    ])
-  }
-  if (!type) {
-    type = getTextByPathList(slideMasterSpNode, [
-      'p:nvSpPr',
-      'p:nvPr',
-      'p:ph',
-      'attrs',
-      'type'
-    ])
-  }
-
-  if (!type) {
-    if (source === 'diagramBg') type = 'diagram'
-    else type = 'obj'
-  }
-
-  return await genShape(
-    node,
-    pNode,
-    slideLayoutSpNode,
-    slideMasterSpNode,
-    name,
-    type,
-    order,
-    warpObj,
-    source
-  )
-}
-
-async function processCxnSpNode (node, pNode, warpObj, source) {
-  const name = node['p:nvCxnSpPr']['p:cNvPr']['attrs']['name']
-  const type =
-    node['p:nvCxnSpPr']['p:nvPr']['p:ph'] === undefined
-      ? undefined
-      : node['p:nvSpPr']['p:nvPr']['p:ph']['attrs']['type']
-  const order = node['attrs']['order']
-
-  return await genShape(
-    node,
-    pNode,
-    undefined,
-    undefined,
-    name,
-    type,
-    order,
-    warpObj,
-    source
-  )
-}
-
-async function genShape (
-  node,
-  pNode,
-  slideLayoutSpNode,
-  slideMasterSpNode,
-  name,
-  type,
-  order,
-  warpObj,
-  source
-) {
-  const xfrmList = ['p:spPr', 'a:xfrm']
-  const slideXfrmNode = getTextByPathList(node, xfrmList)
-  const slideLayoutXfrmNode = getTextByPathList(slideLayoutSpNode, xfrmList)
-  const slideMasterXfrmNode = getTextByPathList(slideMasterSpNode, xfrmList)
-
-  const shapType = getTextByPathList(node, [
-    'p:spPr',
-    'a:prstGeom',
-    'attrs',
-    'prst'
-  ])
-  const custShapType = getTextByPathList(node, ['p:spPr', 'a:custGeom'])
-
-  const { top, left } = getPosition(
-    slideXfrmNode,
-    slideLayoutXfrmNode,
-    slideMasterXfrmNode
-  )
-  const { width, height } = getSize(
-    slideXfrmNode,
-    slideLayoutXfrmNode,
-    slideMasterXfrmNode
-  )
-
-  const isFlipV = getTextByPathList(slideXfrmNode, ['attrs', 'flipV']) === '1'
-  const isFlipH = getTextByPathList(slideXfrmNode, ['attrs', 'flipH']) === '1'
-
-  const rotate = angleToDegrees(
-    getTextByPathList(slideXfrmNode, ['attrs', 'rot'])
-  )
-
-  const txtXframeNode = getTextByPathList(node, ['p:txXfrm'])
-  let txtRotate
-  if (txtXframeNode) {
-    const txtXframeRot = getTextByPathList(txtXframeNode, ['attrs', 'rot'])
-    if (txtXframeRot) txtRotate = angleToDegrees(txtXframeRot) + 90
-  } else txtRotate = rotate
-
-  let content = ''
-  if (node['p:txBody']) {
-    content = genTextBody(
-      node['p:txBody'],
-      node,
-      slideLayoutSpNode,
-      type,
-      warpObj
-    )
-  }
-
-  const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(
-    node,
-    type,
-    warpObj
-  )
-  const fill =
-    (await getShapeFill(node, pNode, undefined, warpObj, source)) || ''
-
-  let shadow
-  const outerShdwNode = getTextByPathList(node, [
-    'p:spPr',
-    'a:effectLst',
-    'a:outerShdw'
-  ])
-  if (outerShdwNode) shadow = getShadow(outerShdwNode, warpObj)
-
-  const vAlign = getVerticalAlign(
-    node,
-    slideLayoutSpNode,
-    slideMasterSpNode,
-    type
-  )
-  const isVertical =
-    getTextByPathList(node, ['p:txBody', 'a:bodyPr', 'attrs', 'vert']) ===
-    'eaVert'
-
-  const data = {
-    left,
-    top,
-    width,
-    height,
-    borderColor,
-    borderWidth,
-    borderType,
-    borderStrokeDasharray: strokeDasharray,
-    fill,
-    content,
-    isFlipV,
-    isFlipH,
-    rotate,
-    vAlign,
-    name,
-    order
-  }
-
-  if (shadow) data.shadow = shadow
-
-  if (custShapType && type !== 'diagram') {
-    const ext = getTextByPathList(slideXfrmNode, ['a:ext', 'attrs'])
-    const w = parseInt(ext['cx']) * RATIO_EMUs_Points
-    const h = parseInt(ext['cy']) * RATIO_EMUs_Points
-    const d = getCustomShapePath(custShapType, w, h)
-    if (data.content && !hasValidText(data.content)) data.content = ''
-
-    return {
-      ...data,
-      type: 'shape',
-      shapType: 'custom',
-      path: d
-    }
-  }
-  if (shapType && (type === 'obj' || !type)) {
-    if (data.content && !hasValidText(data.content)) data.content = ''
-    return {
-      ...data,
-      type: 'shape',
-      shapType
-    }
-  }
-  return {
-    ...data,
-    type: 'text',
-    isVertical,
-    rotate: txtRotate
-  }
-}
-
-async function processPicNode (node, warpObj, source) {
-  let resObj
-  if (source === 'slideMasterBg') resObj = warpObj['masterResObj']
-  else if (source === 'slideLayoutBg') resObj = warpObj['layoutResObj']
-  else resObj = warpObj['slideResObj']
-
-  const order = node['attrs']['order']
-
-  const rid = node['p:blipFill']['a:blip']['attrs']['r:embed']
-  const imgName = resObj[rid]['target']
-  const imgFileExt = extractFileExtension(imgName).toLowerCase()
-  const zip = warpObj['zip']
-  const imgArrayBuffer = await zip.file(imgName).async('arraybuffer')
-  const xfrmNode = node['p:spPr']['a:xfrm']
-
-  const mimeType = getMimeType(imgFileExt)
-  const { top, left } = getPosition(xfrmNode, undefined, undefined)
-  const { width, height } = getSize(xfrmNode, undefined, undefined)
-  const src = `data:${mimeType};base64,${base64ArrayBuffer(imgArrayBuffer)}`
-
-  const isFlipV = getTextByPathList(xfrmNode, ['attrs', 'flipV']) === '1'
-  const isFlipH = getTextByPathList(xfrmNode, ['attrs', 'flipH']) === '1'
-
-  let rotate = 0
-  const rotateNode = getTextByPathList(node, [
-    'p:spPr',
-    'a:xfrm',
-    'attrs',
-    'rot'
-  ])
-  if (rotateNode) rotate = angleToDegrees(rotateNode)
-
-  const videoNode = getTextByPathList(node, [
-    'p:nvPicPr',
-    'p:nvPr',
-    'a:videoFile'
-  ])
-  let videoRid,
-    videoFile,
-    videoFileExt,
-    videoMimeType,
-    uInt8ArrayVideo,
-    videoBlob
-  let isVdeoLink = false
-
-  if (videoNode) {
-    videoRid = videoNode['attrs']['r:link']
-    videoFile = resObj[videoRid]['target']
-    if (isVideoLink(videoFile)) {
-      videoFile = escapeHtml(videoFile)
-      isVdeoLink = true
-    } else {
-      videoFileExt = extractFileExtension(videoFile).toLowerCase()
-      if (
-        videoFileExt === 'mp4' ||
-        videoFileExt === 'webm' ||
-        videoFileExt === 'ogg'
-      ) {
-        uInt8ArrayVideo = await zip.file(videoFile).async('arraybuffer')
-        videoMimeType = getMimeType(videoFileExt)
-        videoBlob = URL.createObjectURL(
-          new Blob([uInt8ArrayVideo], {
-            type: videoMimeType
-          })
-        )
-      }
-    }
-  }
-
-  const audioNode = getTextByPathList(node, [
-    'p:nvPicPr',
-    'p:nvPr',
-    'a:audioFile'
-  ])
-  let audioRid, audioFile, audioFileExt, uInt8ArrayAudio, audioBlob
-  if (audioNode) {
-    audioRid = audioNode['attrs']['r:link']
-    audioFile = resObj[audioRid]['target']
-    audioFileExt = extractFileExtension(audioFile).toLowerCase()
-    if (
-      audioFileExt === 'mp3' ||
-      audioFileExt === 'wav' ||
-      audioFileExt === 'ogg'
-    ) {
-      uInt8ArrayAudio = await zip.file(audioFile).async('arraybuffer')
-      audioBlob = URL.createObjectURL(new Blob([uInt8ArrayAudio]))
-    }
-  }
-
-  if (videoNode && !isVdeoLink) {
-    return {
-      type: 'video',
-      top,
-      left,
-      width,
-      height,
-      rotate,
-      blob: videoBlob,
-      order
-    }
-  }
-  if (videoNode && isVdeoLink) {
-    return {
-      type: 'video',
-      top,
-      left,
-      width,
-      height,
-      rotate,
-      src: videoFile,
-      order
-    }
-  }
-  if (audioNode) {
-    return {
-      type: 'audio',
-      top,
-      left,
-      width,
-      height,
-      rotate,
-      blob: audioBlob,
-      order
-    }
-  }
-
-  let rect
-  const srcRectAttrs = getTextByPathList(node, [
-    'p:blipFill',
-    'a:srcRect',
-    'attrs'
-  ])
-  if (
-    srcRectAttrs &&
-    (srcRectAttrs.t || srcRectAttrs.b || srcRectAttrs.l || srcRectAttrs.r)
-  ) {
-    rect = {}
-    if (srcRectAttrs.t) rect.t = srcRectAttrs.t / 1000
-    if (srcRectAttrs.b) rect.b = srcRectAttrs.b / 1000
-    if (srcRectAttrs.l) rect.l = srcRectAttrs.l / 1000
-    if (srcRectAttrs.r) rect.r = srcRectAttrs.r / 1000
-  }
-  const geom =
-    getTextByPathList(node, ['p:spPr', 'a:prstGeom', 'attrs', 'prst']) ||
-    'rect'
-
-  const { borderColor, borderWidth, borderType, strokeDasharray } = getBorder(
-    node,
-    undefined,
-    warpObj
-  )
-
-  return {
-    type: 'image',
-    top,
-    left,
-    width,
-    height,
-    rotate,
-    src,
-    isFlipV,
-    isFlipH,
-    order,
-    rect,
-    geom,
-    borderColor,
-    borderWidth,
-    borderType,
-    borderStrokeDasharray: strokeDasharray
-  }
-}
-
-async function processGraphicFrameNode (node, warpObj, source) {
-  const graphicTypeUri = getTextByPathList(node, [
-    'a:graphic',
-    'a:graphicData',
-    'attrs',
-    'uri'
-  ])
-
-  let result
-  switch (graphicTypeUri) {
-    case 'http://schemas.openxmlformats.org/drawingml/2006/table':
-      result = await genTable(node, warpObj)
-      break
-    case 'http://schemas.openxmlformats.org/drawingml/2006/chart':
-      result = await genChart(node, warpObj)
-      break
-    case 'http://schemas.openxmlformats.org/drawingml/2006/diagram':
-      result = await genDiagram(node, warpObj)
-      break
-    case 'http://schemas.openxmlformats.org/presentationml/2006/ole':
-      let oleObjNode = getTextByPathList(node, [
-        'a:graphic',
-        'a:graphicData',
-        'mc:AlternateContent',
-        'mc:Fallback',
-        'p:oleObj'
-      ])
-      if (!oleObjNode) {
-        oleObjNode = getTextByPathList(node, [
-          'a:graphic',
-          'a:graphicData',
-          'p:oleObj'
-        ])
-      }
-      if (oleObjNode) { result = await processGroupSpNode(oleObjNode, warpObj, source) }
-      break
-    default:
-  }
-  return result
-}
-
-async function genTable (node, warpObj) {
-  const order = node['attrs']['order']
-  const tableNode = getTextByPathList(node, [
-    'a:graphic',
-    'a:graphicData',
-    'a:tbl'
-  ])
-  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
-  const { top, left } = getPosition(xfrmNode, undefined, undefined)
-  const { width, height } = getSize(xfrmNode, undefined, undefined)
-
-  const getTblPr = getTextByPathList(node, [
-    'a:graphic',
-    'a:graphicData',
-    'a:tbl',
-    'a:tblPr'
-  ])
-  let getColsGrid = getTextByPathList(node, [
-    'a:graphic',
-    'a:graphicData',
-    'a:tbl',
-    'a:tblGrid',
-    'a:gridCol'
-  ])
-  if (getColsGrid.constructor !== Array) getColsGrid = [getColsGrid]
-
-  const colWidths = []
-  if (getColsGrid) {
-    for (const item of getColsGrid) {
-      const colWidthParam = getTextByPathList(item, ['attrs', 'w']) || 0
-      const colWidth = parseInt(colWidthParam) * RATIO_EMUs_Points
-      colWidths.push(colWidth)
-    }
-  }
-
-  const firstRowAttr = getTblPr['attrs']
-    ? getTblPr['attrs']['firstRow']
-    : undefined
-  const firstColAttr = getTblPr['attrs']
-    ? getTblPr['attrs']['firstCol']
-    : undefined
-  const lastRowAttr = getTblPr['attrs']
-    ? getTblPr['attrs']['lastRow']
-    : undefined
-  const lastColAttr = getTblPr['attrs']
-    ? getTblPr['attrs']['lastCol']
-    : undefined
-  const bandRowAttr = getTblPr['attrs']
-    ? getTblPr['attrs']['bandRow']
-    : undefined
-  const bandColAttr = getTblPr['attrs']
-    ? getTblPr['attrs']['bandCol']
-    : undefined
-  const tblStylAttrObj = {
-    isFrstRowAttr: firstRowAttr && firstRowAttr === '1' ? 1 : 0,
-    isFrstColAttr: firstColAttr && firstColAttr === '1' ? 1 : 0,
-    isLstRowAttr: lastRowAttr && lastRowAttr === '1' ? 1 : 0,
-    isLstColAttr: lastColAttr && lastColAttr === '1' ? 1 : 0,
-    isBandRowAttr: bandRowAttr && bandRowAttr === '1' ? 1 : 0,
-    isBandColAttr: bandColAttr && bandColAttr === '1' ? 1 : 0
-  }
-
-  let thisTblStyle
-  const tbleStyleId = getTblPr['a:tableStyleId']
-  if (tbleStyleId) {
-    const tbleStylList = warpObj['tableStyles']['a:tblStyleLst']['a:tblStyle']
-    if (tbleStylList) {
-      if (tbleStylList.constructor === Array) {
-        for (let k = 0; k < tbleStylList.length; k++) {
-          if (tbleStylList[k]['attrs']['styleId'] === tbleStyleId) {
-            thisTblStyle = tbleStylList[k]
-          }
-        }
-      } else {
-        if (tbleStylList['attrs']['styleId'] === tbleStyleId) {
-          thisTblStyle = tbleStylList
-        }
-      }
-    }
-  }
-  if (thisTblStyle) thisTblStyle['tblStylAttrObj'] = tblStylAttrObj
-
-  let borders = {}
-  const tblStyl = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle'])
-  const tblBorderStyl = getTextByPathList(tblStyl, ['a:tcBdr'])
-  if (tblBorderStyl) borders = getTableBorders(tblBorderStyl, warpObj)
-
-  let tbl_bgcolor = ''
-  let tbl_bgFillschemeClr = getTextByPathList(thisTblStyle, [
-    'a:tblBg',
-    'a:fillRef'
-  ])
-  if (tbl_bgFillschemeClr) {
-    tbl_bgcolor = getSolidFill(
-      tbl_bgFillschemeClr,
-      undefined,
-      undefined,
-      warpObj
-    )
-  }
-  if (tbl_bgFillschemeClr === undefined) {
-    tbl_bgFillschemeClr = getTextByPathList(thisTblStyle, [
-      'a:wholeTbl',
-      'a:tcStyle',
-      'a:fill',
-      'a:solidFill'
-    ])
-    tbl_bgcolor = getSolidFill(
-      tbl_bgFillschemeClr,
-      undefined,
-      undefined,
-      warpObj
-    )
-  }
-
-  let trNodes = tableNode['a:tr']
-  if (trNodes.constructor !== Array) trNodes = [trNodes]
-
-  const data = []
-  const rowHeights = []
-  for (let i = 0; i < trNodes.length; i++) {
-    const trNode = trNodes[i]
-
-    const rowHeightParam = getTextByPathList(trNodes[i], ['attrs', 'h']) || 0
-    const rowHeight = parseInt(rowHeightParam) * RATIO_EMUs_Points
-    rowHeights.push(rowHeight)
-
-    const { fillColor, fontColor, fontBold } = getTableRowParams(
-      trNodes,
-      i,
-      tblStylAttrObj,
-      thisTblStyle,
-      warpObj
-    )
-
-    const tcNodes = trNode['a:tc']
-    const tr = []
-
-    if (tcNodes.constructor === Array) {
-      for (let j = 0; j < tcNodes.length; j++) {
-        const tcNode = tcNodes[j]
-        let a_sorce
-        if (j === 0 && tblStylAttrObj['isFrstColAttr'] === 1) {
-          a_sorce = 'a:firstCol'
-          if (
-            tblStylAttrObj['isLstRowAttr'] === 1 &&
-            i === trNodes.length - 1 &&
-            getTextByPathList(thisTblStyle, ['a:seCell'])
-          ) {
-            a_sorce = 'a:seCell'
-          } else if (
-            tblStylAttrObj['isFrstRowAttr'] === 1 &&
-            i === 0 &&
-            getTextByPathList(thisTblStyle, ['a:neCell'])
-          ) {
-            a_sorce = 'a:neCell'
-          }
-        } else if (
-          j > 0 &&
-          tblStylAttrObj['isBandColAttr'] === 1 &&
-          !(tblStylAttrObj['isFrstColAttr'] === 1 && i === 0) &&
-          !(tblStylAttrObj['isLstRowAttr'] === 1 && i === trNodes.length - 1) &&
-          j !== tcNodes.length - 1
-        ) {
-          if (j % 2 !== 0) {
-            let aBandNode = getTextByPathList(thisTblStyle, ['a:band2V'])
-            if (aBandNode === undefined) {
-              aBandNode = getTextByPathList(thisTblStyle, ['a:band1V'])
-              if (aBandNode) a_sorce = 'a:band2V'
-            } else a_sorce = 'a:band2V'
-          }
-        }
-        if (j === tcNodes.length - 1 && tblStylAttrObj['isLstColAttr'] === 1) {
-          a_sorce = 'a:lastCol'
-          if (
-            tblStylAttrObj['isLstRowAttr'] === 1 &&
-            i === trNodes.length - 1 &&
-            getTextByPathList(thisTblStyle, ['a:swCell'])
-          ) {
-            a_sorce = 'a:swCell'
-          } else if (
-            tblStylAttrObj['isFrstRowAttr'] === 1 &&
-            i === 0 &&
-            getTextByPathList(thisTblStyle, ['a:nwCell'])
-          ) {
-            a_sorce = 'a:nwCell'
-          }
-        }
-        const text = genTextBody(
-          tcNode['a:txBody'],
-          tcNode,
-          undefined,
-          undefined,
-          warpObj
-        )
-        const cell = await getTableCellParams(
-          tcNode,
-          thisTblStyle,
-          a_sorce,
-          warpObj
-        )
-        const td = { text }
-        if (cell.rowSpan) td.rowSpan = cell.rowSpan
-        if (cell.colSpan) td.colSpan = cell.colSpan
-        if (cell.vMerge) td.vMerge = cell.vMerge
-        if (cell.hMerge) td.hMerge = cell.hMerge
-        if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
-        if (cell.fontColor || fontColor) { td.fontColor = cell.fontColor || fontColor }
-        if (cell.fillColor || fillColor || tbl_bgcolor) { td.fillColor = cell.fillColor || fillColor || tbl_bgcolor }
-        if (cell.borders) td.borders = cell.borders
-
-        tr.push(td)
-      }
-    } else {
-      let a_sorce
-      if (
-        tblStylAttrObj['isFrstColAttr'] === 1 &&
-        tblStylAttrObj['isLstRowAttr'] !== 1
-      ) {
-        a_sorce = 'a:firstCol'
-      } else if (
-        tblStylAttrObj['isBandColAttr'] === 1 &&
-        tblStylAttrObj['isLstRowAttr'] !== 1
-      ) {
-        let aBandNode = getTextByPathList(thisTblStyle, ['a:band2V'])
-        if (!aBandNode) {
-          aBandNode = getTextByPathList(thisTblStyle, ['a:band1V'])
-          if (aBandNode) a_sorce = 'a:band2V'
-        } else a_sorce = 'a:band2V'
-      }
-      if (
-        tblStylAttrObj['isLstColAttr'] === 1 &&
-        tblStylAttrObj['isLstRowAttr'] !== 1
-      ) {
-        a_sorce = 'a:lastCol'
-      }
-
-      const text = genTextBody(
-        tcNodes['a:txBody'],
-        tcNodes,
-        undefined,
-        undefined,
-        warpObj
-      )
-      const cell = await getTableCellParams(
-        tcNodes,
-        thisTblStyle,
-        a_sorce,
-        warpObj
-      )
-      const td = { text }
-      if (cell.rowSpan) td.rowSpan = cell.rowSpan
-      if (cell.colSpan) td.colSpan = cell.colSpan
-      if (cell.vMerge) td.vMerge = cell.vMerge
-      if (cell.hMerge) td.hMerge = cell.hMerge
-      if (cell.fontBold || fontBold) td.fontBold = cell.fontBold || fontBold
-      if (cell.fontColor || fontColor) { td.fontColor = cell.fontColor || fontColor }
-      if (cell.fillColor || fillColor || tbl_bgcolor) { td.fillColor = cell.fillColor || fillColor || tbl_bgcolor }
-      if (cell.borders) td.borders = cell.borders
-
-      tr.push(td)
-    }
-    data.push(tr)
-  }
-
-  return {
-    type: 'table',
-    top,
-    left,
-    width,
-    height,
-    data,
-    order,
-    borders,
-    rowHeights,
-    colWidths
-  }
-}
-
-async function genChart (node, warpObj) {
-  const order = node['attrs']['order']
-  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
-  const { top, left } = getPosition(xfrmNode, undefined, undefined)
-  const { width, height } = getSize(xfrmNode, undefined, undefined)
-
-  const rid = node['a:graphic']['a:graphicData']['c:chart']['attrs']['r:id']
-  let refName = getTextByPathList(warpObj['slideResObj'], [rid, 'target'])
-  if (!refName) { refName = getTextByPathList(warpObj['layoutResObj'], [rid, 'target']) }
-  if (!refName) { refName = getTextByPathList(warpObj['masterResObj'], [rid, 'target']) }
-  if (!refName) return {}
-
-  const content = await readXmlFile(warpObj['zip'], refName)
-  const plotArea = getTextByPathList(content, [
-    'c:chartSpace',
-    'c:chart',
-    'c:plotArea'
-  ])
-
-  const chart = getChartInfo(plotArea, warpObj)
-
-  if (!chart) return {}
-
-  const data = {
-    type: 'chart',
-    top,
-    left,
-    width,
-    height,
-    data: chart.data,
-    colors: chart.colors,
-    chartType: chart.type,
-    order
-  }
-  if (chart.marker !== undefined) data.marker = chart.marker
-  if (chart.barDir !== undefined) data.barDir = chart.barDir
-  if (chart.holeSize !== undefined) data.holeSize = chart.holeSize
-  if (chart.grouping !== undefined) data.grouping = chart.grouping
-  if (chart.style !== undefined) data.style = chart.style
-
-  return data
-}
-
-async function genDiagram (node, warpObj) {
-  const order = node['attrs']['order']
-  const xfrmNode = getTextByPathList(node, ['p:xfrm'])
-  const { left, top } = getPosition(xfrmNode, undefined, undefined)
-  const { width, height } = getSize(xfrmNode, undefined, undefined)
-
-  const dgmDrwSpArray = getTextByPathList(warpObj['digramFileContent'], [
-    'p:drawing',
-    'p:spTree',
-    'p:sp'
-  ])
-  const elements = []
-  if (dgmDrwSpArray) {
-    for (const item of dgmDrwSpArray) {
-      const el = await processSpNode(item, node, warpObj, 'diagramBg')
-      if (el) elements.push(el)
-    }
-  }
-
-  return {
-    type: 'diagram',
-    left,
-    top,
-    width,
-    height,
-    elements,
-    order
-  }
-}

+ 0 - 46
src/utils/pptxToJson/readXmlFile.js

@@ -1,46 +0,0 @@
-import * as txml from 'txml/dist/txml.mjs'
-
-let cust_attr_order = 0
-
-export function simplifyLostLess (children, parentAttributes = {}) {
-  const out = {}
-  if (!children.length) return out
-
-  if (children.length === 1 && typeof children[0] === 'string') {
-    return Object.keys(parentAttributes).length ? {
-      attrs: { order: cust_attr_order++, ...parentAttributes },
-      value: children[0]
-    } : children[0]
-  }
-  for (const child of children) {
-    if (typeof child !== 'object') return
-    if (child.tagName === '?xml') continue
-
-    if (!out[child.tagName]) out[child.tagName] = []
-
-    const kids = simplifyLostLess(child.children || [], child.attributes)
-
-    if (typeof kids === 'object') {
-      if (!kids.attrs) kids.attrs = { order: cust_attr_order++ }
-      else kids.attrs.order = cust_attr_order++
-    }
-    if (Object.keys(child.attributes || {}).length) {
-      kids.attrs = { ...kids.attrs, ...child.attributes }
-    }
-    out[child.tagName].push(kids)
-  }
-  for (const child in out) {
-    if (out[child].length === 1) out[child] = out[child][0]
-  }
-
-  return out
-}
-
-export async function readXmlFile (zip, filename) {
-  try {
-    const data = await zip.file(filename).async('string')
-    return simplifyLostLess(txml.parse(data))
-  } catch {
-    return null
-  }
-}

+ 0 - 55
src/utils/pptxToJson/schemeColor.js

@@ -1,55 +0,0 @@
-import { getTextByPathList } from './utils'
-
-export function getSchemeColorFromTheme (schemeClr, warpObj, clrMap, phClr) {
-  let color
-  let slideLayoutClrOvride
-  if (clrMap) slideLayoutClrOvride = clrMap
-  else {
-    let sldClrMapOvr = getTextByPathList(warpObj['slideContent'], ['p:sld', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-    if (sldClrMapOvr) slideLayoutClrOvride = sldClrMapOvr
-    else {
-      sldClrMapOvr = getTextByPathList(warpObj['slideLayoutContent'], ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
-      if (sldClrMapOvr) slideLayoutClrOvride = sldClrMapOvr
-      else {
-        slideLayoutClrOvride = getTextByPathList(warpObj['slideMasterContent'], ['p:sldMaster', 'p:clrMap', 'attrs'])
-      }
-    }
-  }
-  const schmClrName = schemeClr.substr(2)
-  if (schmClrName === 'phClr' && phClr) color = phClr
-  else {
-    if (slideLayoutClrOvride) {
-      switch (schmClrName) {
-        case 'tx1':
-        case 'tx2':
-        case 'bg1':
-        case 'bg2':
-          schemeClr = 'a:' + slideLayoutClrOvride[schmClrName]
-          break
-        default:
-          break
-      }
-    } else {
-      switch (schemeClr) {
-        case 'tx1':
-          schemeClr = 'a:dk1'
-          break
-        case 'tx2':
-          schemeClr = 'a:dk2'
-          break
-        case 'bg1':
-          schemeClr = 'a:lt1'
-          break
-        case 'bg2':
-          schemeClr = 'a:lt2'
-          break
-        default:
-          break
-      }
-    }
-    const refNode = getTextByPathList(warpObj['themeContent'], ['a:theme', 'a:themeElements', 'a:clrScheme', schemeClr])
-    color = getTextByPathList(refNode, ['a:srgbClr', 'attrs', 'val'])
-    if (!color && refNode) color = getTextByPathList(refNode, ['a:sysClr', 'attrs', 'lastClr'])
-  }
-  return color
-}

+ 0 - 19
src/utils/pptxToJson/shadow.js

@@ -1,19 +0,0 @@
-import { getSolidFill } from './fill'
-import { RATIO_EMUs_Points } from './constants'
-
-export function getShadow (node, warpObj) {
-  const chdwClrNode = getSolidFill(node, undefined, undefined, warpObj)
-  const outerShdwAttrs = node['attrs']
-  const dir = outerShdwAttrs['dir'] ? (parseInt(outerShdwAttrs['dir']) / 60000) : 0
-  const dist = parseInt(outerShdwAttrs['dist']) * RATIO_EMUs_Points
-  const blurRad = outerShdwAttrs['blurRad'] ? parseInt(outerShdwAttrs['blurRad']) * RATIO_EMUs_Points : ''
-  const vx = dist * Math.sin(dir * Math.PI / 180)
-  const hx = dist * Math.cos(dir * Math.PI / 180)
-
-  return {
-    h: hx,
-    v: vx,
-    blur: blurRad,
-    color: chdwClrNode
-  }
-}

+ 0 - 185
src/utils/pptxToJson/shape.js

@@ -1,185 +0,0 @@
-import { getTextByPathList } from './utils'
-
-export function shapeArc (cX, cY, rX, rY, stAng, endAng, isClose) {
-  let dData
-  let angle = stAng
-  if (endAng >= stAng) {
-    while (angle <= endAng) {
-      const radians = angle * (Math.PI / 180)
-      const x = cX + Math.cos(radians) * rX
-      const y = cY + Math.sin(radians) * rY
-      if (angle === stAng) {
-        dData = ' M' + x + ' ' + y
-      }
-      dData += ' L' + x + ' ' + y
-      angle++
-    }
-  } else {
-    while (angle > endAng) {
-      const radians = angle * (Math.PI / 180)
-      const x = cX + Math.cos(radians) * rX
-      const y = cY + Math.sin(radians) * rY
-      if (angle === stAng) {
-        dData = ' M ' + x + ' ' + y
-      }
-      dData += ' L ' + x + ' ' + y
-      angle--
-    }
-  }
-  dData += (isClose ? ' z' : '')
-  return dData
-}
-
-export function getCustomShapePath (custShapType, w, h) {
-  const pathLstNode = getTextByPathList(custShapType, ['a:pathLst'])
-  let pathNodes = getTextByPathList(pathLstNode, ['a:path'])
-
-  if (Array.isArray(pathNodes)) pathNodes = pathNodes.shift()
-
-  const maxX = parseInt(pathNodes['attrs']['w'])
-  const maxY = parseInt(pathNodes['attrs']['h'])
-  const cX = maxX === 0 ? 0 : (1 / maxX) * w
-  const cY = maxY === 0 ? 0 : (1 / maxY) * h
-  let d = ''
-
-  let moveToNode = getTextByPathList(pathNodes, ['a:moveTo'])
-
-  const lnToNodes = pathNodes['a:lnTo']
-  let cubicBezToNodes = pathNodes['a:cubicBezTo']
-  const arcToNodes = pathNodes['a:arcTo']
-  let closeNode = getTextByPathList(pathNodes, ['a:close'])
-  if (!Array.isArray(moveToNode)) moveToNode = [moveToNode]
-
-  const multiSapeAry = []
-  if (moveToNode.length > 0) {
-    Object.keys(moveToNode).forEach(key => {
-      const moveToPtNode = moveToNode[key]['a:pt']
-      if (moveToPtNode) {
-        Object.keys(moveToPtNode).forEach(key => {
-          const moveToNoPt = moveToPtNode[key]
-          const spX = moveToNoPt['attrs', 'x']
-          const spY = moveToNoPt['attrs', 'y']
-          const order = moveToNoPt['attrs', 'order']
-          multiSapeAry.push({
-            type: 'movto',
-            x: spX,
-            y: spY,
-            order
-          })
-        })
-      }
-    })
-    if (lnToNodes) {
-      Object.keys(lnToNodes).forEach(key => {
-        const lnToPtNode = lnToNodes[key]['a:pt']
-        if (lnToPtNode) {
-          Object.keys(lnToPtNode).forEach(key => {
-            const lnToNoPt = lnToPtNode[key]
-            const ptX = lnToNoPt['attrs', 'x']
-            const ptY = lnToNoPt['attrs', 'y']
-            const order = lnToNoPt['attrs', 'order']
-            multiSapeAry.push({
-              type: 'lnto',
-              x: ptX,
-              y: ptY,
-              order
-            })
-          })
-        }
-      })
-    }
-    if (cubicBezToNodes) {
-      const cubicBezToPtNodesAry = []
-      if (!Array.isArray(cubicBezToNodes)) {
-        cubicBezToNodes = [cubicBezToNodes]
-      }
-      Object.keys(cubicBezToNodes).forEach(key => {
-        cubicBezToPtNodesAry.push(cubicBezToNodes[key]['a:pt'])
-      })
-
-      cubicBezToPtNodesAry.forEach(key => {
-        const pts_ary = []
-        key.forEach(pt => {
-          const pt_obj = {
-            x: pt['attrs']['x'],
-            y: pt['attrs']['y']
-          }
-          pts_ary.push(pt_obj)
-        })
-        const order = key[0]['attrs']['order']
-        multiSapeAry.push({
-          type: 'cubicBezTo',
-          cubBzPt: pts_ary,
-          order
-        })
-      })
-    }
-    if (arcToNodes) {
-      const arcToNodesAttrs = arcToNodes['attrs']
-      const order = arcToNodesAttrs['order']
-      const hR = arcToNodesAttrs['hR']
-      const wR = arcToNodesAttrs['wR']
-      const stAng = arcToNodesAttrs['stAng']
-      const swAng = arcToNodesAttrs['swAng']
-      let shftX = 0
-      let shftY = 0
-      const arcToPtNode = getTextByPathList(arcToNodes, ['a:pt', 'attrs'])
-      if (arcToPtNode) {
-        shftX = arcToPtNode['x']
-        shftY = arcToPtNode['y']
-      }
-      multiSapeAry.push({
-        type: 'arcTo',
-        hR: hR,
-        wR: wR,
-        stAng: stAng,
-        swAng: swAng,
-        shftX: shftX,
-        shftY: shftY,
-        order
-      })
-    }
-    if (closeNode) {
-      if (!Array.isArray(closeNode)) closeNode = [closeNode]
-      Object.keys(closeNode).forEach(() => {
-        multiSapeAry.push({
-          type: 'close',
-          order: Infinity
-        })
-      })
-    }
-
-    multiSapeAry.sort((a, b) => a.order - b.order)
-
-    let k = 0
-    while (k < multiSapeAry.length) {
-      if (multiSapeAry[k].type === 'movto') {
-        const spX = parseInt(multiSapeAry[k].x) * cX
-        const spY = parseInt(multiSapeAry[k].y) * cY
-        d += ' M' + spX + ',' + spY
-      } else if (multiSapeAry[k].type === 'lnto') {
-        const Lx = parseInt(multiSapeAry[k].x) * cX
-        const Ly = parseInt(multiSapeAry[k].y) * cY
-        d += ' L' + Lx + ',' + Ly
-      } else if (multiSapeAry[k].type === 'cubicBezTo') {
-        const Cx1 = parseInt(multiSapeAry[k].cubBzPt[0].x) * cX
-        const Cy1 = parseInt(multiSapeAry[k].cubBzPt[0].y) * cY
-        const Cx2 = parseInt(multiSapeAry[k].cubBzPt[1].x) * cX
-        const Cy2 = parseInt(multiSapeAry[k].cubBzPt[1].y) * cY
-        const Cx3 = parseInt(multiSapeAry[k].cubBzPt[2].x) * cX
-        const Cy3 = parseInt(multiSapeAry[k].cubBzPt[2].y) * cY
-        d += ' C' + Cx1 + ',' + Cy1 + ' ' + Cx2 + ',' + Cy2 + ' ' + Cx3 + ',' + Cy3
-      } else if (multiSapeAry[k].type === 'arcTo') {
-        const hR = parseInt(multiSapeAry[k].hR) * cX
-        const wR = parseInt(multiSapeAry[k].wR) * cY
-        const stAng = parseInt(multiSapeAry[k].stAng) / 60000
-        const swAng = parseInt(multiSapeAry[k].swAng) / 60000
-        const endAng = stAng + swAng
-        d += shapeArc(wR, hR, wR, hR, stAng, endAng, false)
-      } else if (multiSapeAry[k].type === 'close') d += 'z'
-      k++
-    }
-  }
-
-  return d
-}

+ 0 - 198
src/utils/pptxToJson/table.js

@@ -1,198 +0,0 @@
-import { getShapeFill, getSolidFill } from './fill'
-import { getTextByPathList } from './utils'
-import { getBorder } from './border'
-
-export function getTableBorders (node, warpObj) {
-  const borders = {}
-  if (node['a:bottom']) {
-    const obj = {
-      'p:spPr': {
-        'a:ln': node['a:bottom']['a:ln']
-      }
-    }
-    const border = getBorder(obj, undefined, warpObj)
-    borders.bottom = border
-  }
-  if (node['a:top']) {
-    const obj = {
-      'p:spPr': {
-        'a:ln': node['a:top']['a:ln']
-      }
-    }
-    const border = getBorder(obj, undefined, warpObj)
-    borders.top = border
-  }
-  if (node['a:right']) {
-    const obj = {
-      'p:spPr': {
-        'a:ln': node['a:right']['a:ln']
-      }
-    }
-    const border = getBorder(obj, undefined, warpObj)
-    borders.right = border
-  }
-  if (node['a:left']) {
-    const obj = {
-      'p:spPr': {
-        'a:ln': node['a:left']['a:ln']
-      }
-    }
-    const border = getBorder(obj, undefined, warpObj)
-    borders.left = border
-  }
-  return borders
-}
-
-export async function getTableCellParams (tcNode, thisTblStyle, cellSource, warpObj) {
-  const rowSpan = getTextByPathList(tcNode, ['attrs', 'rowSpan'])
-  const colSpan = getTextByPathList(tcNode, ['attrs', 'gridSpan'])
-  const vMerge = getTextByPathList(tcNode, ['attrs', 'vMerge'])
-  const hMerge = getTextByPathList(tcNode, ['attrs', 'hMerge'])
-  let fillColor
-  let fontColor
-  let fontBold
-
-  const getCelFill = getTextByPathList(tcNode, ['a:tcPr'])
-  if (getCelFill) {
-    const cellObj = { 'p:spPr': getCelFill }
-    const fill = await getShapeFill(cellObj, undefined, false, warpObj, 'slide')
-
-    if (fill && fill.type === 'color' && fill.value) {
-      fillColor = fill.value
-    }
-  }
-  if (!fillColor) {
-    let bgFillschemeClr
-    if (cellSource) bgFillschemeClr = getTextByPathList(thisTblStyle, [cellSource, 'a:tcStyle', 'a:fill', 'a:solidFill'])
-    if (bgFillschemeClr) {
-      fillColor = getSolidFill(bgFillschemeClr, undefined, undefined, warpObj)
-    }
-  }
-
-  let rowTxtStyl
-  if (cellSource) rowTxtStyl = getTextByPathList(thisTblStyle, [cellSource, 'a:tcTxStyle'])
-  if (rowTxtStyl) {
-    fontColor = getSolidFill(rowTxtStyl, undefined, undefined, warpObj)
-    if (getTextByPathList(rowTxtStyl, ['attrs', 'b']) === 'on') fontBold = true
-  }
-
-  let lin_bottm = getTextByPathList(tcNode, ['a:tcPr', 'a:lnB'])
-  if (!lin_bottm) {
-    if (cellSource) lin_bottm = getTextByPathList(thisTblStyle[cellSource], ['a:tcStyle', 'a:tcBdr', 'a:bottom', 'a:ln'])
-    if (!lin_bottm) lin_bottm = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle', 'a:tcBdr', 'a:bottom', 'a:ln'])
-  }
-  let lin_top = getTextByPathList(tcNode, ['a:tcPr', 'a:lnT'])
-  if (!lin_top) {
-    if (cellSource) lin_top = getTextByPathList(thisTblStyle[cellSource], ['a:tcStyle', 'a:tcBdr', 'a:top', 'a:ln'])
-    if (!lin_top) lin_top = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle', 'a:tcBdr', 'a:top', 'a:ln'])
-  }
-  let lin_left = getTextByPathList(tcNode, ['a:tcPr', 'a:lnL'])
-  if (!lin_left) {
-    if (cellSource) lin_left = getTextByPathList(thisTblStyle[cellSource], ['a:tcStyle', 'a:tcBdr', 'a:left', 'a:ln'])
-    if (!lin_left) lin_left = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle', 'a:tcBdr', 'a:left', 'a:ln'])
-  }
-  let lin_right = getTextByPathList(tcNode, ['a:tcPr', 'a:lnR'])
-  if (!lin_right) {
-    if (cellSource) lin_right = getTextByPathList(thisTblStyle[cellSource], ['a:tcStyle', 'a:tcBdr', 'a:right', 'a:ln'])
-    if (!lin_right) lin_right = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle', 'a:tcBdr', 'a:right', 'a:ln'])
-  }
-
-  const borders = {}
-  if (lin_bottm) borders.bottom = getBorder(lin_bottm, undefined, warpObj)
-  if (lin_top) borders.top = getBorder(lin_top, undefined, warpObj)
-  if (lin_left) borders.left = getBorder(lin_left, undefined, warpObj)
-  if (lin_right) borders.right = getBorder(lin_right, undefined, warpObj)
-
-  return {
-    fillColor,
-    fontColor,
-    fontBold,
-    borders,
-    rowSpan: rowSpan ? +rowSpan : undefined,
-    colSpan: colSpan ? +colSpan : undefined,
-    vMerge: vMerge ? +vMerge : undefined,
-    hMerge: hMerge ? +hMerge : undefined
-  }
-}
-
-export function getTableRowParams (trNodes, i, tblStylAttrObj, thisTblStyle, warpObj) {
-  let fillColor
-  let fontColor
-  let fontBold
-
-  if (thisTblStyle && thisTblStyle['a:wholeTbl']) {
-    const bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcStyle', 'a:fill', 'a:solidFill'])
-    if (bgFillschemeClr) {
-      const local_fillColor = getSolidFill(bgFillschemeClr, undefined, undefined, warpObj)
-      if (local_fillColor) fillColor = local_fillColor
-    }
-    const rowTxtStyl = getTextByPathList(thisTblStyle, ['a:wholeTbl', 'a:tcTxStyle'])
-    if (rowTxtStyl) {
-      const local_fontColor = getSolidFill(rowTxtStyl, undefined, undefined, warpObj)
-      if (local_fontColor) fontColor = local_fontColor
-      if (getTextByPathList(rowTxtStyl, ['attrs', 'b']) === 'on') fontBold = true
-    }
-  }
-  if (i === 0 && tblStylAttrObj['isFrstRowAttr'] === 1 && thisTblStyle) {
-    const bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:firstRow', 'a:tcStyle', 'a:fill', 'a:solidFill'])
-    if (bgFillschemeClr) {
-      const local_fillColor = getSolidFill(bgFillschemeClr, undefined, undefined, warpObj)
-      if (local_fillColor) fillColor = local_fillColor
-    }
-    const rowTxtStyl = getTextByPathList(thisTblStyle, ['a:firstRow', 'a:tcTxStyle'])
-    if (rowTxtStyl) {
-      const local_fontColor = getSolidFill(rowTxtStyl, undefined, undefined, warpObj)
-      if (local_fontColor) fontColor = local_fontColor
-      if (getTextByPathList(rowTxtStyl, ['attrs', 'b']) === 'on') fontBold = true
-    }
-  } else if (i > 0 && tblStylAttrObj['isBandRowAttr'] === 1 && thisTblStyle) {
-    fillColor = ''
-    if ((i % 2) === 0 && thisTblStyle['a:band2H']) {
-      const bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:band2H', 'a:tcStyle', 'a:fill', 'a:solidFill'])
-      if (bgFillschemeClr) {
-        const local_fillColor = getSolidFill(bgFillschemeClr, undefined, undefined, warpObj)
-        if (local_fillColor) fillColor = local_fillColor
-      }
-      const rowTxtStyl = getTextByPathList(thisTblStyle, ['a:band2H', 'a:tcTxStyle'])
-      if (rowTxtStyl) {
-        const local_fontColor = getSolidFill(rowTxtStyl, undefined, undefined, warpObj)
-        if (local_fontColor) fontColor = local_fontColor
-      }
-      if (getTextByPathList(rowTxtStyl, ['attrs', 'b']) === 'on') fontBold = true
-    }
-    if ((i % 2) !== 0 && thisTblStyle['a:band1H']) {
-      const bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:band1H', 'a:tcStyle', 'a:fill', 'a:solidFill'])
-      if (bgFillschemeClr) {
-        const local_fillColor = getSolidFill(bgFillschemeClr, undefined, undefined, warpObj)
-        if (local_fillColor) fillColor = local_fillColor
-      }
-      const rowTxtStyl = getTextByPathList(thisTblStyle, ['a:band1H', 'a:tcTxStyle'])
-      if (rowTxtStyl) {
-        const local_fontColor = getSolidFill(rowTxtStyl, undefined, undefined, warpObj)
-        if (local_fontColor) fontColor = local_fontColor
-        if (getTextByPathList(rowTxtStyl, ['attrs', 'b']) === 'on') fontBold = true
-      }
-    }
-  }
-  if (i === (trNodes.length - 1) && tblStylAttrObj['isLstRowAttr'] === 1 && thisTblStyle) {
-    const bgFillschemeClr = getTextByPathList(thisTblStyle, ['a:lastRow', 'a:tcStyle', 'a:fill', 'a:solidFill'])
-    if (bgFillschemeClr) {
-      const local_fillColor = getSolidFill(bgFillschemeClr, undefined, undefined, warpObj)
-      if (local_fillColor) {
-        fillColor = local_fillColor
-      }
-    }
-    const rowTxtStyl = getTextByPathList(thisTblStyle, ['a:lastRow', 'a:tcTxStyle'])
-    if (rowTxtStyl) {
-      const local_fontColor = getSolidFill(rowTxtStyl, undefined, undefined, warpObj)
-      if (local_fontColor) fontColor = local_fontColor
-      if (getTextByPathList(rowTxtStyl, ['attrs', 'b']) === 'on') fontBold = true
-    }
-  }
-
-  return {
-    fillColor,
-    fontColor,
-    fontBold
-  }
-}

+ 0 - 284
src/utils/pptxToJson/text.js

@@ -1,284 +0,0 @@
-import { getHorizontalAlign } from './align'
-import { getTextByPathList } from './utils'
-
-import {
-  getFontType,
-  getFontColor,
-  getFontSize,
-  getFontBold,
-  getFontItalic,
-  getFontDecoration,
-  getFontDecorationLine,
-  getFontSpace,
-  getFontSubscript,
-  getFontShadow
-} from './fontStyle'
-
-export function genTextBody(
-  textBodyNode,
-  spNode,
-  slideLayoutSpNode,
-  type,
-  warpObj
-) {
-  if (!textBodyNode) return ''
-
-  let text = ''
-  const listCounters = {} // 添加列表计数器对象
-  const slideMasterTextStyles = warpObj['slideMasterTextStyles']
-  const pFontStyle = getTextByPathList(spNode, ['p:style', 'a:fontRef'])
-  const pNode = textBodyNode['a:p']
-  const pNodes = pNode.constructor === Array ? pNode : [pNode]
-  let isList = ''
-
-  for (const pNode of pNodes) {
-    let rNode = pNode['a:r']
-    let fldNode = pNode['a:fld']
-    let brNode = pNode['a:br']
-    if (rNode) {
-      rNode = rNode.constructor === Array ? rNode : [rNode]
-
-      if (fldNode) {
-        fldNode = fldNode.constructor === Array ? fldNode : [fldNode]
-        rNode = rNode.concat(fldNode)
-      }
-      if (brNode) {
-        brNode = brNode.constructor === Array ? brNode : [brNode]
-        brNode.forEach((item) => (item.type = 'br'))
-
-        if (brNode.length > 1) brNode.shift()
-        rNode = rNode.concat(brNode)
-        rNode.sort((a, b) => {
-          if (!a.attrs || !b.attrs) return true
-          return a.attrs.order - b.attrs.order
-        })
-      }
-    }
-
-    const align = getHorizontalAlign(pNode, spNode, type, warpObj)
-
-    const listType = getListType(pNode)
-    if (listType) {
-      const [tagName, className] = listType.split(' ')
-      const level = parseInt(pNode['a:pPr'].attrs?.lvl || '0') // 获取列表层级
-      const indentSize = (level + 1) * 20 // 根据层级计算缩进大小
-
-      if (!isList) {
-        text += `<${tagName} style="list-style: none; " class="${className}">`
-        isList = listType
-        listCounters[className] = 0
-      }
-      else if (isList && isList !== listType) {
-        text += `</${isList.split(' ')[0]}>`
-        text += `<${tagName} style="list-style: none; " class="${className}">`
-        isList = listType
-        listCounters[className] = 0
-      }
-
-      listCounters[className]++
-      const currentNumber = listCounters[className]
-
-      text += `<li style="text-align: ${align}; padding-left: ${indentSize}px;">`
-
-      if (className === 'custom-bullet') {
-        const bulletChar = pNode['a:pPr']['a:buChar'].attrs?.char || '•'
-        const symbolMap = {
-          'n': '■', // 实心方块
-          'l': '●', // 实心圆
-          'u': '◆', // 实心菱形
-          'p': '□', // 空心方块
-          'ü': '✔', // 对号
-          'Ø': '➢', // 箭头
-          '': '•' // 默认圆点
-        }
-        const displayChar = symbolMap[bulletChar] || bulletChar
-        // 获取字体大小,与内容保持一致
-        const fontSize = getFontSize(textBodyNode, slideLayoutSpNode, type, slideMasterTextStyles)
-        const fontSizeStyle = fontSize ? `font-size: ${fontSize};` : ''
-        text += `<span style="display: inline-block; width: 20px; ${fontSizeStyle}; margin-left: -20px;">${displayChar}</span>`
-      }
-      else {
-        let displayNumber = ''
-
-        switch (className) {
-          case 'circle-number':
-            const circleNums = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩']
-            displayNumber = circleNums[currentNumber - 1] || `${currentNumber}`
-            break
-          case 'roman-upper':
-            const romanNums = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X']
-            displayNumber = `${romanNums[currentNumber - 1]}.`
-            break
-          case 'alpha-upper':
-            displayNumber = `${String.fromCharCode(64 + currentNumber)}.`
-            break
-          case 'alpha-lower-paren':
-            displayNumber = `${String.fromCharCode(96 + currentNumber)})`
-            break
-          case 'alpha-lower':
-            displayNumber = `${String.fromCharCode(96 + currentNumber)}.`
-            break
-          case 'chinese-upper': // 添加中文数字
-            const chineseUpperNums = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
-            displayNumber = `${chineseUpperNums[currentNumber - 1]}.`
-            break
-          default:
-            displayNumber = `${currentNumber}.`
-        }
-        // 获取字体大小,与内容保持一致
-        const fontSize = getFontSize(textBodyNode, slideLayoutSpNode, type, slideMasterTextStyles)
-        const fontSizeStyle = fontSize ? `font-size: ${fontSize};` : ''
-        text += `<span style="display: inline-block; ${fontSizeStyle}; margin-left: -20px;">${displayNumber}</span>`
-      }
-    }
-    else {
-      if (isList) {
-        text += `</${isList.split(' ')[0]}>`
-        isList = ''
-      }
-      text += `<p style="text-align: ${align};">`
-    }
-
-    if (!rNode) {
-      text += genSpanElement(
-        pNode,
-        spNode,
-        textBodyNode,
-        pFontStyle,
-        slideLayoutSpNode,
-        type,
-        warpObj
-      )
-    }
-    else {
-      for (const rNodeItem of rNode) {
-        text += genSpanElement(
-          rNodeItem,
-          pNode,
-          textBodyNode,
-          pFontStyle,
-          slideLayoutSpNode,
-          type,
-          warpObj
-        )
-      }
-    }
-
-    if (listType) text += '</li>'
-    else text += '</p>'
-  }
-  return text
-}
-
-export function getListType(node) {
-  const pPrNode = node['a:pPr']
-  if (!pPrNode) return ''
-
-  if (pPrNode['a:buChar']) {
-    return 'ul custom-bullet'
-  }
-  if (pPrNode['a:buAutoNum']) {
-    const numType = pPrNode['a:buAutoNum'].attrs?.type || 'arabicPeriod'
-    // 根据不同的编号类型返回对应的样式
-    switch (numType) {
-      case 'circleNumDbPlain':
-        return 'ol circle-number' // ①②③
-      case 'romanUcPeriod':
-        return 'ol roman-upper' // I. II. III.
-      case 'alphaUcPeriod':
-        return 'ol alpha-upper' // A. B. C.
-      case 'alphaLcParen':
-        return 'ol alpha-lower-paren' // a) b) c)
-      case 'alphaLcPeriod':
-        return 'ol alpha-lower' // a. b. c.
-      case 'ea1JpnChsDbPeriod':
-        return 'ol chinese-upper' // 一. 二. 三.
-      default:
-        return 'ol decimal' // 1. 2. 3.
-    }
-  }
-  return ''
-}
-
-export function genSpanElement(
-  node,
-  pNode,
-  textBodyNode,
-  pFontStyle,
-  slideLayoutSpNode,
-  type,
-  warpObj
-) {
-  const lstStyle = textBodyNode['a:lstStyle']
-  const slideMasterTextStyles = warpObj['slideMasterTextStyles']
-
-  let lvl = 1
-  const pPrNode = pNode['a:pPr']
-  if (pPrNode) {
-    const lvlNode = getTextByPathList(pPrNode, ['attrs', 'lvl'])
-    if (lvlNode !== undefined) lvl = parseInt(lvlNode) + 1
-  }
-
-  let fontSize
-  const directSize = getTextByPathList(node, ['a:rPr', 'attrs', 'sz'])
-
-  if (directSize) {
-    // 如果节点本身有字体大小设置,直接使用
-    fontSize = getFontSize(node, slideLayoutSpNode, type, slideMasterTextStyles)
-  }
-  else {
-    // 如果节点没有字体大小设置,使用 textBodyNode
-    fontSize = getFontSize(textBodyNode, slideLayoutSpNode, type, slideMasterTextStyles)
-  }
-
-  let text = node['a:t']
-  if (typeof text !== 'string') text = getTextByPathList(node, ['a:fld', 'a:t'])
-  if (typeof text !== 'string') text = '&nbsp;'
-
-  let styleText = ''
-  const fontColor = getFontColor(
-    node,
-    pNode,
-    lstStyle,
-    pFontStyle,
-    lvl,
-    warpObj
-  )
-  const fontType = getFontType(node, type, warpObj)
-  const fontBold = getFontBold(node)
-  const fontItalic = getFontItalic(node)
-  const fontDecoration = getFontDecoration(node)
-  const fontDecorationLine = getFontDecorationLine(node)
-  const fontSpace = getFontSpace(node)
-  const shadow = getFontShadow(node, warpObj)
-  const subscript = getFontSubscript(node)
-
-  if (fontColor) styleText += `color: ${fontColor};`
-  if (fontSize) styleText += `font-size: ${fontSize};`
-  if (fontType) styleText += `font-family: ${fontType};`
-  if (fontBold) styleText += `font-weight: ${fontBold};`
-  if (fontItalic) styleText += `font-style: ${fontItalic};`
-  if (fontDecoration) styleText += `text-decoration: ${fontDecoration};`
-  if (fontDecorationLine) {
-    styleText += `text-decoration-line: ${fontDecorationLine};`
-  }
-  if (fontSpace) styleText += `letter-spacing: ${fontSpace};`
-  if (subscript) styleText += `vertical-align: ${subscript};`
-  if (shadow) styleText += `text-shadow: ${shadow};`
-
-  const linkID = getTextByPathList(node, [
-    'a:rPr',
-    'a:hlinkClick',
-    'attrs',
-    'r:id'
-  ])
-  if (linkID) {
-    const linkURL = warpObj['slideResObj'][linkID]['target']
-    return `<span style="${styleText}"><a href="${linkURL}" target="_blank">${text
-      .replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')
-      .replace(/\s/g, '&nbsp;')}</a></span>`
-  }
-  return `<span style="${styleText}">${text
-    .replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')
-    .replace(/\s/g, '&nbsp;')}</span>`
-}

+ 0 - 158
src/utils/pptxToJson/utils.js

@@ -1,158 +0,0 @@
-export function base64ArrayBuffer (arrayBuffer) {
-  const encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-  const bytes = new Uint8Array(arrayBuffer)
-  const byteLength = bytes.byteLength
-  const byteRemainder = byteLength % 3
-  const mainLength = byteLength - byteRemainder
-
-  let base64 = ''
-  let a, b, c, d
-  let chunk
-
-  for (let i = 0; i < mainLength; i = i + 3) {
-    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
-    a = (chunk & 16515072) >> 18
-    b = (chunk & 258048) >> 12
-    c = (chunk & 4032) >> 6
-    d = chunk & 63
-    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
-  }
-
-  if (byteRemainder === 1) {
-    chunk = bytes[mainLength]
-    a = (chunk & 252) >> 2
-    b = (chunk & 3) << 4
-    base64 += encodings[a] + encodings[b] + '=='
-  } else if (byteRemainder === 2) {
-    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
-    a = (chunk & 64512) >> 10
-    b = (chunk & 1008) >> 4
-    c = (chunk & 15) << 2
-    base64 += encodings[a] + encodings[b] + encodings[c] + '='
-  }
-
-  return base64
-}
-
-export function extractFileExtension (filename) {
-  return filename.substr((~-filename.lastIndexOf('.') >>> 0) + 2)
-}
-
-export function eachElement (node, func) {
-  if (!node) return node
-
-  let result = ''
-  if (node.constructor === Array) {
-    for (let i = 0; i < node.length; i++) {
-      result += func(node[i], i)
-    }
-  } else result += func(node, 0)
-
-  return result
-}
-
-export function getTextByPathList (node, path) {
-  if (!node) return node
-
-  for (const key of path) {
-    node = node[key]
-    if (!node) return node
-  }
-
-  return node
-}
-
-export function angleToDegrees (angle) {
-  if (!angle) return 0
-  return Math.round(angle / 60000)
-}
-
-export function escapeHtml (text) {
-  const map = {
-    '&': '&amp;',
-    '<': '&lt;',
-    '>': '&gt;',
-    '"': '&quot;',
-    "'": '&#039;'
-  }
-  return text.replace(/[&<>"']/g, m => map[m])
-}
-
-export function getMimeType (imgFileExt) {
-  let mimeType = ''
-  switch (imgFileExt.toLowerCase()) {
-    case 'jpg':
-    case 'jpeg':
-      mimeType = 'image/jpeg'
-      break
-    case 'png':
-      mimeType = 'image/png'
-      break
-    case 'gif':
-      mimeType = 'image/gif'
-      break
-    case 'emf':
-      mimeType = 'image/x-emf'
-      break
-    case 'wmf':
-      mimeType = 'image/x-wmf'
-      break
-    case 'svg':
-      mimeType = 'image/svg+xml'
-      break
-    case 'mp4':
-      mimeType = 'video/mp4'
-      break
-    case 'webm':
-      mimeType = 'video/webm'
-      break
-    case 'ogg':
-      mimeType = 'video/ogg'
-      break
-    case 'avi':
-      mimeType = 'video/avi'
-      break
-    case 'mpg':
-      mimeType = 'video/mpg'
-      break
-    case 'wmv':
-      mimeType = 'video/wmv'
-      break
-    case 'mp3':
-      mimeType = 'audio/mpeg'
-      break
-    case 'wav':
-      mimeType = 'audio/wav'
-      break
-    case 'tif':
-      mimeType = 'image/tiff'
-      break
-    case 'tiff':
-      mimeType = 'image/tiff'
-      break
-    default:
-  }
-  return mimeType
-}
-
-export function isVideoLink (vdoFile) {
-  const urlRegex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
-  return urlRegex.test(vdoFile)
-}
-
-export function toHex (n) {
-  let hex = n.toString(16)
-  while (hex.length < 2) {
-    hex = '0' + hex
-  }
-  return hex
-}
-
-export function hasValidText (htmlString) {
-  if (!DOMParser) return true
-
-  const parser = new DOMParser()
-  const doc = parser.parseFromString(htmlString, 'text/html')
-  const text = doc.body.textContent || doc.body.innerText
-  return text.trim() !== ''
-}

+ 7 - 236
src/views/index.vue

@@ -1,246 +1,17 @@
 <!--
  * @Author: LiZhiWei
- * @Date: 2025-04-23 16:56:47
+ * @Date: 2025-04-24 15:23:24
  * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-24 11:37:37
+ * @LastEditTime: 2025-04-24 15:26:25
  * @Description: 
 -->
 <template>
-  <div class="file-viewer-container">
-    <div class="header">
-      <el-select
-        v-model="downloadUrl"
-        filterable
-        allow-create
-        default-first-option
-        clearable
-        placeholder="请选择或输入文件预览地址"
-        class="input-with-button"
-      >
-        <el-option
-          v-for="item in urlOptions"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value"
-        >
-          <span class="url-label">{{ item.label }}</span>
-          <span class="url-value">{{ item.value }}</span>
-        </el-option>
-      </el-select>
-      <el-button
-        type="primary"
-        :loading="downloading"
-        @click="handlePreview"
-        style="margin-left: 10px"
-      >
-        预览文件
-      </el-button>
-      <el-upload
-        class="upload-demo"
-        action=""
-        :show-file-list="false"
-        :auto-upload="false"
-        :on-change="handleFileChange"
-      >
-        <el-button type="primary" style="margin-left: 10px"
-          >选择本地文件</el-button
-        >
-      </el-upload>
-    </div>
-    <view-file :file="previewFile" />
-  </div>
+  <div></div>
 </template>
 
-<script>
-import ViewFile from "@/components/view_file/index.vue"
-import file from "@/api/module/file.js"
-import { readBuffer } from "@/components/view_file/util"
+<script setup lang='ts'>
+import { ref, reactive } from 'vue'
 
-export default {
-  components: {
-    ViewFile,
-  },
-  data() {
-    return {
-      previewFile: {
-        filename: "", //文件名
-        type: "", //文件类型
-        fileBuffer: null, //文件字节流
-      },
-      downloadUrl: "", // 添加输入框绑定值
-      downloading: false, // 加载状态
-      urlOptions: [
-        {
-          value:
-            "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.pptx",
-          label: "PPT示例文件",
-        },
-        {
-          value:
-            "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.docx",
-          label: "Word示例文件",
-        },
-        {
-          value:
-            "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.pdf",
-          label: "PDF示例文件",
-        },
-        {
-          value:
-            "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.xlsx",
-          label: "Excel示例文件",
-        },
-        {
-          value:
-            "https://fastly.picsum.photos/id/641/800/600.jpg?hmac=DJCZbdxrCoJPFV0jAsSIG1Ny0oc48zL3iqeMFqtKlD4",
-          label: "图片示例文件",
-        },
-      ],
-    }
-  },
-  methods: {
-    handlePreview() {
-      if (!this.downloadUrl) {
-        this.$message.warning("请输入文件预览地址")
-        return
-      }
-      this.downloading = true
-
-      file
-        .previewCabinetFileByUrl(this.downloadUrl)
-        .then((res) => {
-          const urlParts = this.downloadUrl.split("/")
-          const fileName = urlParts[urlParts.length - 1]
-          const fileType =
-            fileName
-              .split("?")[0]
-              .match(/\.([^.]+)$/)?.[1]
-              ?.toLowerCase() || ""
-          this.previewFile.filename = fileName.split(".")[0]
-          this.previewFile.type = fileType
-          // 更新文件信息
-          return readBuffer(res.data).then((arrayBuffer) => {
-            this.previewFile.fileBuffer = arrayBuffer
-            return arrayBuffer
-          })
-        })
-        .then(() => {
-          this.$message.success("文件加载成功")
-        })
-        .catch((error) => {
-          this.$message.error("文件加载失败:" + error.message)
-        })
-        .finally(() => {
-          this.downloading = false
-        })
-    },
-    async handleFileChange(file) {
-      if (!file) {
-        this.$message.warning("请选择文件")
-        return
-      }
-      try {
-        // 获取文件类型
-        const fileName = file.name
-        const fileType = fileName.split(".").pop().toLowerCase()
-
-        // 检查文件类型是否支持
-        const typeObject = {
-          doc: ["docx"],
-          xlsx: ["xlsx"],
-          pdf: ["pdf"],
-          ppt: ["pptx"],
-          image: ["gif", "jpg", "jpeg", "bmp", "tiff", "tif", "png", "svg"],
-          text: [
-            "txt",
-            "json",
-            "js",
-            "css",
-            "java",
-            "py",
-            "html",
-            "jsx",
-            "ts",
-            "tsx",
-            "xml",
-            "md",
-            "log",
-          ],
-        }
-        const ablePreviewTypes = Object.values(typeObject).flat()
-
-        if (!ablePreviewTypes.includes(fileType)) {
-          throw new Error("不支持的文件类型")
-        }
-
-        this.previewFile.filename = fileName.split(".")[0]
-        this.previewFile.type = fileType
-        // 读取文件
-        const arrayBuffer = await new Promise((resolve, reject) => {
-          const reader = new FileReader()
-          reader.onload = () => resolve(reader.result)
-          reader.onerror = reject
-          reader.readAsArrayBuffer(file.raw)
-        })
-
-        // 设置文件缓冲区
-        this.previewFile.fileBuffer = arrayBuffer
-        this.$message.success("文件加载成功")
-      } catch (error) {
-        this.$message.error("文件加载失败:" + error.message)
-        this.showError = true
-      }
-    },
-  },
-}
 </script>
-
-<style lang="less" scoped>
-.file-viewer-container {
-  width: 100%;
-  height: 100%;
-  position: relative;
-}
-
-.header {
-  padding: 20px;
-  border-bottom: 1px solid #eee;
-}
-
-.loading-process {
-  width: 50%;
-  position: absolute;
-  top: 50%;
-  transform: translate(-50%, -50%);
-  left: 50%;
-  z-index: 10;
-  .load-text {
-    line-height: 28px;
-  }
-}
-
-.input-with-button {
-  width: 400px;
-
-  .url-label {
-    float: left;
-    color: #606266;
-  }
-
-  .url-value {
-    float: right;
-    color: #909399;
-    font-size: 13px;
-  }
-}
-
-.upload-demo {
-  display: inline-block;
-}
-
-:deep(.el-select-dropdown__item) {
-  padding: 0 20px;
-  height: 40px;
-  line-height: 40px;
-}
-</style>
+<style scoped lang='scss'>
+</style>

+ 1 - 0
src/vite-env.d.ts

@@ -0,0 +1 @@
+/// <reference types="vite/client" />

+ 14 - 0
tsconfig.app.json

@@ -0,0 +1,14 @@
+{
+  "extends": "@vue/tsconfig/tsconfig.dom.json",
+  "compilerOptions": {
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
+}

+ 10 - 23
tsconfig.json

@@ -1,24 +1,11 @@
 {
-  "compilerOptions": {
-    "target": "ES2020",
-    "useDefineForClassFields": true,
-    "module": "ESNext",
-    "lib": ["ES2020", "DOM", "DOM.Iterable"],
-    "skipLibCheck": true,
-
-    /* Bundler mode */
-    "moduleResolution": "bundler",
-    "allowImportingTsExtensions": true,
-    "isolatedModules": true,
-    "moduleDetection": "force",
-    "noEmit": true,
-
-    /* Linting */
-    "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
-    "noFallthroughCasesInSwitch": true,
-    "noUncheckedSideEffectImports": true
-  },
-  "include": ["src"]
-}
+    "files": [],
+    "references": [
+        {
+            "path": "./tsconfig.app.json"
+        },
+        {
+            "path": "./tsconfig.node.json"
+        }
+    ]
+}

+ 24 - 0
tsconfig.node.json

@@ -0,0 +1,24 @@
+{
+  "compilerOptions": {
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+    "target": "ES2022",
+    "lib": ["ES2023"],
+    "module": "ESNext",
+    "skipLibCheck": true,
+
+    /* Bundler mode */
+    "moduleResolution": "bundler",
+    "allowImportingTsExtensions": true,
+    "isolatedModules": true,
+    "moduleDetection": "force",
+    "noEmit": true,
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["vite.config.ts"]
+}

+ 5 - 22
vite.config.ts

@@ -1,24 +1,7 @@
-/*
- * @Author: LiZhiWei
- * @Date: 2025-04-09 09:05:25
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-15 15:39:42
- * @Description:
- */
-import { defineConfig } from "vite"
-import path from 'path'
-import { createVuePlugin } from "vite-plugin-vue2"
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vite.dev/config/
 export default defineConfig({
-    resolve: {
-        alias: {
-          '@': path.resolve(__dirname, 'src'),
-          '_c': path.resolve(__dirname, 'src/components'),
-          '_wc': path.resolve(__dirname, 'src/components/wisdom-city'),
-          '_vc': path.resolve(__dirname, 'src/view/components'),
-          '_conf': path.resolve(__dirname, 'src/config'),
-          '#': path.resolve(__dirname, 'types'),
-        },
-        extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
-      },
-    plugins: [createVuePlugin()],
+  plugins: [vue()],
 })

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov