jwyu 9 bulan lalu
melakukan
471628723d

+ 8 - 0
.env.development

@@ -0,0 +1,8 @@
+# 接口地址
+VITE_APP_API_URL="/v1"
+# 路由根地址
+VITE_APP_BASE_URL="/"
+# 打包输入文件名
+VITE_APP_OUTDIR="eta_mini_h5"
+# 参数解密key
+VITE_APP_RESPONSE_DES_KEY="MxuqSoUrTAmyRd9fb0TtlrPk"

+ 8 - 0
.env.production

@@ -0,0 +1,8 @@
+# 接口地址
+VITE_APP_API_URL="/adminapi"
+# 路由根地址
+VITE_APP_BASE_URL="/"
+# 打包输入文件名
+VITE_APP_OUTDIR="eta_mini_h5"
+# 参数解密key
+VITE_APP_RESPONSE_DES_KEY="MxuqSoUrTAmyRd9fb0TtlrPk"

+ 8 - 0
.env.test

@@ -0,0 +1,8 @@
+# 接口地址
+VITE_APP_API_URL="http://8.136.199.33:8705/adminapi/"
+# 路由根地址
+VITE_APP_BASE_URL="/"
+# 打包输入文件名
+VITE_APP_OUTDIR="eta_mini_h5"
+# 参数解密key
+VITE_APP_RESPONSE_DES_KEY="MxuqSoUrTAmyRd9fb0TtlrPk"

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+eta_mini_h5
+eta_mini_h5.zip
+
+# Editor directories and files
+.vscode
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 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.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously Volar) and disable Vetur

+ 14 - 0
index.html

@@ -0,0 +1,14 @@
+<!doctype html>
+<html lang="en">
+  <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></title>
+    <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 32 - 0
package.json

@@ -0,0 +1,32 @@
+{
+  "name": "eta_mini_h5",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build --mode production",
+    "build:test": "vite build --mode test",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "axios": "^1.7.2",
+    "highcharts": "^11.4.3",
+    "lodash": "^4.17.21",
+    "moment": "^2.30.1",
+    "normalize.css": "^8.0.1",
+    "tdesign-mobile-vue": "^1.2.3",
+    "vue": "^3.4.21",
+    "vue-router": "4"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^5.0.4",
+    "postcss-px-to-viewport": "^1.1.1",
+    "sass": "^1.77.4",
+    "unplugin-auto-import": "^0.17.6",
+    "unplugin-icons": "^0.19.0",
+    "unplugin-vue-components": "^0.27.0",
+    "vite": "^5.2.0",
+    "vite-plugin-svg-icons": "^2.0.1"
+  }
+}

+ 3161 - 0
pnpm-lock.yaml

@@ -0,0 +1,3161 @@
+lockfileVersion: '6.0'
+
+dependencies:
+  axios:
+    specifier: ^1.7.2
+    version: 1.7.2
+  highcharts:
+    specifier: ^11.4.3
+    version: 11.4.3
+  lodash:
+    specifier: ^4.17.21
+    version: 4.17.21
+  moment:
+    specifier: ^2.30.1
+    version: 2.30.1
+  normalize.css:
+    specifier: ^8.0.1
+    version: 8.0.1
+  tdesign-mobile-vue:
+    specifier: ^1.2.3
+    version: 1.2.3(vue@3.4.21)
+  vue:
+    specifier: ^3.4.21
+    version: 3.4.21
+  vue-router:
+    specifier: '4'
+    version: 4.3.2(vue@3.4.21)
+
+devDependencies:
+  '@vitejs/plugin-vue':
+    specifier: ^5.0.4
+    version: 5.0.4(vite@5.2.0)(vue@3.4.21)
+  postcss-px-to-viewport:
+    specifier: ^1.1.1
+    version: 1.1.1
+  sass:
+    specifier: ^1.77.4
+    version: 1.77.4
+  unplugin-auto-import:
+    specifier: ^0.17.6
+    version: 0.17.6
+  unplugin-icons:
+    specifier: ^0.19.0
+    version: 0.19.0
+  unplugin-vue-components:
+    specifier: ^0.27.0
+    version: 0.27.0(vue@3.4.21)
+  vite:
+    specifier: ^5.2.0
+    version: 5.2.0(sass@1.77.4)
+  vite-plugin-svg-icons:
+    specifier: ^2.0.1
+    version: 2.0.1(vite@5.2.0)
+
+packages:
+
+  /@antfu/install-pkg@0.1.1:
+    resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
+    dependencies:
+      execa: 5.1.1
+      find-up: 5.0.0
+    dev: true
+
+  /@antfu/install-pkg@0.3.3:
+    resolution: {integrity: sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==}
+    dependencies:
+      '@jsdevtools/ez-spawn': 3.0.4
+    dev: true
+
+  /@antfu/utils@0.7.8:
+    resolution: {integrity: sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==}
+    dev: true
+
+  /@babel/helper-string-parser@7.24.6:
+    resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/helper-validator-identifier@7.24.6:
+    resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/parser@7.24.6:
+    resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.24.6
+
+  /@babel/runtime@7.24.6:
+    resolution: {integrity: sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      regenerator-runtime: 0.14.1
+    dev: false
+
+  /@babel/types@7.24.6:
+    resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-string-parser': 7.24.6
+      '@babel/helper-validator-identifier': 7.24.6
+      to-fast-properties: 2.0.0
+
+  /@esbuild/aix-ppc64@0.20.2:
+    resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [aix]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-arm64@0.20.2:
+    resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-arm@0.20.2:
+    resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-x64@0.20.2:
+    resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-arm64@0.20.2:
+    resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-x64@0.20.2:
+    resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-arm64@0.20.2:
+    resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-x64@0.20.2:
+    resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm64@0.20.2:
+    resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm@0.20.2:
+    resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ia32@0.20.2:
+    resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-loong64@0.20.2:
+    resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==}
+    engines: {node: '>=12'}
+    cpu: [loong64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-mips64el@0.20.2:
+    resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==}
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ppc64@0.20.2:
+    resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-riscv64@0.20.2:
+    resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==}
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-s390x@0.20.2:
+    resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==}
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-x64@0.20.2:
+    resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/netbsd-x64@0.20.2:
+    resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/openbsd-x64@0.20.2:
+    resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/sunos-x64@0.20.2:
+    resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-arm64@0.20.2:
+    resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-ia32@0.20.2:
+    resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-x64@0.20.2:
+    resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@iconify/types@2.0.0:
+    resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+    dev: true
+
+  /@iconify/utils@2.1.24:
+    resolution: {integrity: sha512-H8r2KpL5uKyrkb3z9/3HD/22JcxqW3BJyjEWZhX2T7DehnYVZthEap1cNsEl/UtCDC3TlpNmwiPX8wg3y8E4dg==}
+    dependencies:
+      '@antfu/install-pkg': 0.1.1
+      '@antfu/utils': 0.7.8
+      '@iconify/types': 2.0.0
+      debug: 4.3.5
+      kolorist: 1.8.0
+      local-pkg: 0.5.0
+      mlly: 1.7.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@jridgewell/sourcemap-codec@1.4.15:
+    resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+
+  /@jsdevtools/ez-spawn@3.0.4:
+    resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==}
+    engines: {node: '>=10'}
+    dependencies:
+      call-me-maybe: 1.0.2
+      cross-spawn: 7.0.3
+      string-argv: 0.3.2
+      type-detect: 4.0.8
+    dev: true
+
+  /@nodelib/fs.scandir@2.1.5:
+    resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      run-parallel: 1.2.0
+    dev: true
+
+  /@nodelib/fs.stat@2.0.5:
+    resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /@nodelib/fs.walk@1.2.8:
+    resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.scandir': 2.1.5
+      fastq: 1.17.1
+    dev: true
+
+  /@rollup/pluginutils@5.1.0:
+    resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
+    engines: {node: '>=14.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+    peerDependenciesMeta:
+      rollup:
+        optional: true
+    dependencies:
+      '@types/estree': 1.0.5
+      estree-walker: 2.0.2
+      picomatch: 2.3.1
+    dev: true
+
+  /@rollup/rollup-android-arm-eabi@4.18.0:
+    resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-android-arm64@4.18.0:
+    resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-darwin-arm64@4.18.0:
+    resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-darwin-x64@4.18.0:
+    resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-arm-gnueabihf@4.18.0:
+    resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==}
+    cpu: [arm]
+    os: [linux]
+    libc: [glibc]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-arm-musleabihf@4.18.0:
+    resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==}
+    cpu: [arm]
+    os: [linux]
+    libc: [musl]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-arm64-gnu@4.18.0:
+    resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==}
+    cpu: [arm64]
+    os: [linux]
+    libc: [glibc]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-arm64-musl@4.18.0:
+    resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==}
+    cpu: [arm64]
+    os: [linux]
+    libc: [musl]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-powerpc64le-gnu@4.18.0:
+    resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==}
+    cpu: [ppc64]
+    os: [linux]
+    libc: [glibc]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-riscv64-gnu@4.18.0:
+    resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==}
+    cpu: [riscv64]
+    os: [linux]
+    libc: [glibc]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-s390x-gnu@4.18.0:
+    resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==}
+    cpu: [s390x]
+    os: [linux]
+    libc: [glibc]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-x64-gnu@4.18.0:
+    resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==}
+    cpu: [x64]
+    os: [linux]
+    libc: [glibc]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-x64-musl@4.18.0:
+    resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==}
+    cpu: [x64]
+    os: [linux]
+    libc: [musl]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-win32-arm64-msvc@4.18.0:
+    resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-win32-ia32-msvc@4.18.0:
+    resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-win32-x64-msvc@4.18.0:
+    resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@trysound/sax@0.2.0:
+    resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
+    engines: {node: '>=10.13.0'}
+    dev: true
+
+  /@types/estree@1.0.5:
+    resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+    dev: true
+
+  /@types/node@20.14.1:
+    resolution: {integrity: sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==}
+    dependencies:
+      undici-types: 5.26.5
+    dev: true
+
+  /@types/svgo@2.6.4:
+    resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==}
+    dependencies:
+      '@types/node': 20.14.1
+    dev: true
+
+  /@types/web-bluetooth@0.0.20:
+    resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+    dev: false
+
+  /@use-gesture/core@10.3.1:
+    resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==}
+    dev: false
+
+  /@use-gesture/vanilla@10.3.1:
+    resolution: {integrity: sha512-lT4scGLu59ovA3zmtUonukAGcA0AdOOh+iwNDS05Bsu7Lq9aZToDHhI6D8Q2qvsVraovtsLLYwPrWdG/noMAKw==}
+    dependencies:
+      '@use-gesture/core': 10.3.1
+    dev: false
+
+  /@vitejs/plugin-vue@5.0.4(vite@5.2.0)(vue@3.4.21):
+    resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    peerDependencies:
+      vite: ^5.0.0
+      vue: ^3.2.25
+    dependencies:
+      vite: 5.2.0(sass@1.77.4)
+      vue: 3.4.21
+    dev: true
+
+  /@vue/compiler-core@3.4.21:
+    resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==}
+    dependencies:
+      '@babel/parser': 7.24.6
+      '@vue/shared': 3.4.21
+      entities: 4.5.0
+      estree-walker: 2.0.2
+      source-map-js: 1.2.0
+
+  /@vue/compiler-dom@3.4.21:
+    resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==}
+    dependencies:
+      '@vue/compiler-core': 3.4.21
+      '@vue/shared': 3.4.21
+
+  /@vue/compiler-sfc@3.4.21:
+    resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==}
+    dependencies:
+      '@babel/parser': 7.24.6
+      '@vue/compiler-core': 3.4.21
+      '@vue/compiler-dom': 3.4.21
+      '@vue/compiler-ssr': 3.4.21
+      '@vue/shared': 3.4.21
+      estree-walker: 2.0.2
+      magic-string: 0.30.10
+      postcss: 8.4.38
+      source-map-js: 1.2.0
+
+  /@vue/compiler-ssr@3.4.21:
+    resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==}
+    dependencies:
+      '@vue/compiler-dom': 3.4.21
+      '@vue/shared': 3.4.21
+
+  /@vue/devtools-api@6.6.2:
+    resolution: {integrity: sha512-134clD8u7cBBXdmBbXI282gHGF7T/eAbD/G7mAK2llQF62IbI4ny28IVamZVMoJSvfImC2Xxnj732hXkJvUj6g==}
+    dev: false
+
+  /@vue/reactivity@3.4.21:
+    resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==}
+    dependencies:
+      '@vue/shared': 3.4.21
+
+  /@vue/runtime-core@3.4.21:
+    resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==}
+    dependencies:
+      '@vue/reactivity': 3.4.21
+      '@vue/shared': 3.4.21
+
+  /@vue/runtime-dom@3.4.21:
+    resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==}
+    dependencies:
+      '@vue/runtime-core': 3.4.21
+      '@vue/shared': 3.4.21
+      csstype: 3.1.3
+
+  /@vue/server-renderer@3.4.21(vue@3.4.21):
+    resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==}
+    peerDependencies:
+      vue: 3.4.21
+    dependencies:
+      '@vue/compiler-ssr': 3.4.21
+      '@vue/shared': 3.4.21
+      vue: 3.4.21
+
+  /@vue/shared@3.4.21:
+    resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==}
+
+  /@vueuse/core@10.7.0(vue@3.4.21):
+    resolution: {integrity: sha512-4EUDESCHtwu44ZWK3Gc/hZUVhVo/ysvdtwocB5vcauSV4B7NiGY5972WnsojB3vRNdxvAt7kzJWE2h9h7C9d5w==}
+    dependencies:
+      '@types/web-bluetooth': 0.0.20
+      '@vueuse/metadata': 10.7.0
+      '@vueuse/shared': 10.7.0(vue@3.4.21)
+      vue-demi: 0.14.8(vue@3.4.21)
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
+  /@vueuse/metadata@10.7.0:
+    resolution: {integrity: sha512-GlaH7tKP2iBCZ3bHNZ6b0cl9g0CJK8lttkBNUX156gWvNYhTKEtbweWLm9rxCPIiwzYcr/5xML6T8ZUEt+DkvA==}
+    dev: false
+
+  /@vueuse/shared@10.7.0(vue@3.4.21):
+    resolution: {integrity: sha512-kc00uV6CiaTdc3i1CDC4a3lBxzaBE9AgYNtFN87B5OOscqeWElj/uza8qVDmk7/U8JbqoONLbtqiLJ5LGRuqlw==}
+    dependencies:
+      vue-demi: 0.14.8(vue@3.4.21)
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
+  /acorn@8.11.3:
+    resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /ansi-regex@2.1.1:
+    resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /ansi-styles@2.2.1:
+    resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /anymatch@3.1.3:
+    resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+    engines: {node: '>= 8'}
+    dependencies:
+      normalize-path: 3.0.0
+      picomatch: 2.3.1
+    dev: true
+
+  /arr-diff@4.0.0:
+    resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /arr-flatten@1.1.0:
+    resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /arr-union@3.1.0:
+    resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /array-buffer-byte-length@1.0.1:
+    resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      is-array-buffer: 3.0.4
+    dev: true
+
+  /array-unique@0.3.2:
+    resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /arraybuffer.prototype.slice@1.0.3:
+    resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      array-buffer-byte-length: 1.0.1
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-abstract: 1.23.3
+      es-errors: 1.3.0
+      get-intrinsic: 1.2.4
+      is-array-buffer: 3.0.4
+      is-shared-array-buffer: 1.0.3
+    dev: true
+
+  /assign-symbols@1.0.0:
+    resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /asynckit@0.4.0:
+    resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+    dev: false
+
+  /atob@2.1.2:
+    resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
+    engines: {node: '>= 4.5.0'}
+    hasBin: true
+    dev: true
+
+  /available-typed-arrays@1.0.7:
+    resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      possible-typed-array-names: 1.0.0
+    dev: true
+
+  /axios@1.7.2:
+    resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==}
+    dependencies:
+      follow-redirects: 1.15.6
+      form-data: 4.0.0
+      proxy-from-env: 1.1.0
+    transitivePeerDependencies:
+      - debug
+    dev: false
+
+  /balanced-match@1.0.2:
+    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+    dev: true
+
+  /base@0.11.2:
+    resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      cache-base: 1.0.1
+      class-utils: 0.3.6
+      component-emitter: 1.3.1
+      define-property: 1.0.0
+      isobject: 3.0.1
+      mixin-deep: 1.3.2
+      pascalcase: 0.1.1
+    dev: true
+
+  /big.js@5.2.2:
+    resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
+    dev: true
+
+  /binary-extensions@2.3.0:
+    resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /bluebird@3.7.2:
+    resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
+    dev: true
+
+  /boolbase@1.0.0:
+    resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+    dev: true
+
+  /brace-expansion@2.0.1:
+    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+    dependencies:
+      balanced-match: 1.0.2
+    dev: true
+
+  /braces@2.3.2:
+    resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-flatten: 1.1.0
+      array-unique: 0.3.2
+      extend-shallow: 2.0.1
+      fill-range: 4.0.0
+      isobject: 3.0.1
+      repeat-element: 1.1.4
+      snapdragon: 0.8.2
+      snapdragon-node: 2.1.1
+      split-string: 3.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /braces@3.0.3:
+    resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+    engines: {node: '>=8'}
+    dependencies:
+      fill-range: 7.1.1
+    dev: true
+
+  /cache-base@1.0.1:
+    resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      collection-visit: 1.0.0
+      component-emitter: 1.3.1
+      get-value: 2.0.6
+      has-value: 1.0.0
+      isobject: 3.0.1
+      set-value: 2.0.1
+      to-object-path: 0.3.0
+      union-value: 1.0.1
+      unset-value: 1.0.0
+    dev: true
+
+  /call-bind@1.0.7:
+    resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-define-property: 1.0.0
+      es-errors: 1.3.0
+      function-bind: 1.1.2
+      get-intrinsic: 1.2.4
+      set-function-length: 1.2.2
+    dev: true
+
+  /call-me-maybe@1.0.2:
+    resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
+    dev: true
+
+  /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: true
+
+  /chokidar@3.6.0:
+    resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+    engines: {node: '>= 8.10.0'}
+    dependencies:
+      anymatch: 3.1.3
+      braces: 3.0.3
+      glob-parent: 5.1.2
+      is-binary-path: 2.1.0
+      is-glob: 4.0.3
+      normalize-path: 3.0.0
+      readdirp: 3.6.0
+    optionalDependencies:
+      fsevents: 2.3.3
+    dev: true
+
+  /class-utils@0.3.6:
+    resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-union: 3.1.0
+      define-property: 0.2.5
+      isobject: 3.0.1
+      static-extend: 0.1.2
+    dev: true
+
+  /clone@2.1.2:
+    resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
+    engines: {node: '>=0.8'}
+    dev: true
+
+  /collection-visit@1.0.0:
+    resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      map-visit: 1.0.0
+      object-visit: 1.0.1
+    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
+
+  /commander@7.2.0:
+    resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+    engines: {node: '>= 10'}
+    dev: true
+
+  /component-emitter@1.3.1:
+    resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
+    dev: true
+
+  /confbox@0.1.7:
+    resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==}
+    dev: true
+
+  /copy-descriptor@0.1.1:
+    resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /cors@2.8.5:
+    resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
+    engines: {node: '>= 0.10'}
+    dependencies:
+      object-assign: 4.1.1
+      vary: 1.1.2
+    dev: true
+
+  /cross-spawn@7.0.3:
+    resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+    engines: {node: '>= 8'}
+    dependencies:
+      path-key: 3.1.1
+      shebang-command: 2.0.0
+      which: 2.0.2
+    dev: true
+
+  /css-select@4.3.0:
+    resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
+    dependencies:
+      boolbase: 1.0.0
+      css-what: 6.1.0
+      domhandler: 4.3.1
+      domutils: 2.8.0
+      nth-check: 2.1.1
+    dev: true
+
+  /css-tree@1.1.3:
+    resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      mdn-data: 2.0.14
+      source-map: 0.6.1
+    dev: true
+
+  /css-what@6.1.0:
+    resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /csso@4.2.0:
+    resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      css-tree: 1.1.3
+    dev: true
+
+  /csstype@3.1.3:
+    resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+  /data-view-buffer@1.0.1:
+    resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      is-data-view: 1.0.1
+    dev: true
+
+  /data-view-byte-length@1.0.1:
+    resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      is-data-view: 1.0.1
+    dev: true
+
+  /data-view-byte-offset@1.0.0:
+    resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      is-data-view: 1.0.1
+    dev: true
+
+  /dayjs@1.11.11:
+    resolution: {integrity: sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==}
+    dev: false
+
+  /debug@2.6.9:
+    resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.0.0
+    dev: true
+
+  /debug@4.3.5:
+    resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+    dev: true
+
+  /decode-uri-component@0.2.2:
+    resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
+    engines: {node: '>=0.10'}
+    dev: true
+
+  /define-data-property@1.1.4:
+    resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-define-property: 1.0.0
+      es-errors: 1.3.0
+      gopd: 1.0.1
+    dev: true
+
+  /define-properties@1.2.1:
+    resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.4
+      has-property-descriptors: 1.0.2
+      object-keys: 1.1.1
+    dev: true
+
+  /define-property@0.2.5:
+    resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-descriptor: 0.1.7
+    dev: true
+
+  /define-property@1.0.0:
+    resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-descriptor: 1.0.3
+    dev: true
+
+  /define-property@2.0.2:
+    resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-descriptor: 1.0.3
+      isobject: 3.0.1
+    dev: true
+
+  /delayed-stream@1.0.0:
+    resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+    engines: {node: '>=0.4.0'}
+    dev: false
+
+  /dom-serializer@0.2.2:
+    resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
+    dependencies:
+      domelementtype: 2.3.0
+      entities: 2.2.0
+    dev: true
+
+  /dom-serializer@1.4.1:
+    resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
+    dependencies:
+      domelementtype: 2.3.0
+      domhandler: 4.3.1
+      entities: 2.2.0
+    dev: true
+
+  /domelementtype@1.3.1:
+    resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
+    dev: true
+
+  /domelementtype@2.3.0:
+    resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+    dev: true
+
+  /domhandler@2.4.2:
+    resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==}
+    dependencies:
+      domelementtype: 1.3.1
+    dev: true
+
+  /domhandler@4.3.1:
+    resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
+    engines: {node: '>= 4'}
+    dependencies:
+      domelementtype: 2.3.0
+    dev: true
+
+  /domutils@1.7.0:
+    resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
+    dependencies:
+      dom-serializer: 0.2.2
+      domelementtype: 1.3.1
+    dev: true
+
+  /domutils@2.8.0:
+    resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
+    dependencies:
+      dom-serializer: 1.4.1
+      domelementtype: 2.3.0
+      domhandler: 4.3.1
+    dev: true
+
+  /emojis-list@3.0.0:
+    resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
+    engines: {node: '>= 4'}
+    dev: true
+
+  /entities@1.1.2:
+    resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==}
+    dev: true
+
+  /entities@2.2.0:
+    resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
+    dev: true
+
+  /entities@4.5.0:
+    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+    engines: {node: '>=0.12'}
+
+  /es-abstract@1.23.3:
+    resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      array-buffer-byte-length: 1.0.1
+      arraybuffer.prototype.slice: 1.0.3
+      available-typed-arrays: 1.0.7
+      call-bind: 1.0.7
+      data-view-buffer: 1.0.1
+      data-view-byte-length: 1.0.1
+      data-view-byte-offset: 1.0.0
+      es-define-property: 1.0.0
+      es-errors: 1.3.0
+      es-object-atoms: 1.0.0
+      es-set-tostringtag: 2.0.3
+      es-to-primitive: 1.2.1
+      function.prototype.name: 1.1.6
+      get-intrinsic: 1.2.4
+      get-symbol-description: 1.0.2
+      globalthis: 1.0.4
+      gopd: 1.0.1
+      has-property-descriptors: 1.0.2
+      has-proto: 1.0.3
+      has-symbols: 1.0.3
+      hasown: 2.0.2
+      internal-slot: 1.0.7
+      is-array-buffer: 3.0.4
+      is-callable: 1.2.7
+      is-data-view: 1.0.1
+      is-negative-zero: 2.0.3
+      is-regex: 1.1.4
+      is-shared-array-buffer: 1.0.3
+      is-string: 1.0.7
+      is-typed-array: 1.1.13
+      is-weakref: 1.0.2
+      object-inspect: 1.13.1
+      object-keys: 1.1.1
+      object.assign: 4.1.5
+      regexp.prototype.flags: 1.5.2
+      safe-array-concat: 1.1.2
+      safe-regex-test: 1.0.3
+      string.prototype.trim: 1.2.9
+      string.prototype.trimend: 1.0.8
+      string.prototype.trimstart: 1.0.8
+      typed-array-buffer: 1.0.2
+      typed-array-byte-length: 1.0.1
+      typed-array-byte-offset: 1.0.2
+      typed-array-length: 1.0.6
+      unbox-primitive: 1.0.2
+      which-typed-array: 1.1.15
+    dev: true
+
+  /es-define-property@1.0.0:
+    resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      get-intrinsic: 1.2.4
+    dev: true
+
+  /es-errors@1.3.0:
+    resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /es-object-atoms@1.0.0:
+    resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-errors: 1.3.0
+    dev: true
+
+  /es-set-tostringtag@2.0.3:
+    resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      get-intrinsic: 1.2.4
+      has-tostringtag: 1.0.2
+      hasown: 2.0.2
+    dev: true
+
+  /es-to-primitive@1.2.1:
+    resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-callable: 1.2.7
+      is-date-object: 1.0.5
+      is-symbol: 1.0.4
+    dev: true
+
+  /esbuild@0.20.2:
+    resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      '@esbuild/aix-ppc64': 0.20.2
+      '@esbuild/android-arm': 0.20.2
+      '@esbuild/android-arm64': 0.20.2
+      '@esbuild/android-x64': 0.20.2
+      '@esbuild/darwin-arm64': 0.20.2
+      '@esbuild/darwin-x64': 0.20.2
+      '@esbuild/freebsd-arm64': 0.20.2
+      '@esbuild/freebsd-x64': 0.20.2
+      '@esbuild/linux-arm': 0.20.2
+      '@esbuild/linux-arm64': 0.20.2
+      '@esbuild/linux-ia32': 0.20.2
+      '@esbuild/linux-loong64': 0.20.2
+      '@esbuild/linux-mips64el': 0.20.2
+      '@esbuild/linux-ppc64': 0.20.2
+      '@esbuild/linux-riscv64': 0.20.2
+      '@esbuild/linux-s390x': 0.20.2
+      '@esbuild/linux-x64': 0.20.2
+      '@esbuild/netbsd-x64': 0.20.2
+      '@esbuild/openbsd-x64': 0.20.2
+      '@esbuild/sunos-x64': 0.20.2
+      '@esbuild/win32-arm64': 0.20.2
+      '@esbuild/win32-ia32': 0.20.2
+      '@esbuild/win32-x64': 0.20.2
+    dev: true
+
+  /escape-string-regexp@1.0.5:
+    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+    engines: {node: '>=0.8.0'}
+    dev: true
+
+  /escape-string-regexp@5.0.0:
+    resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /estree-walker@2.0.2:
+    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+  /estree-walker@3.0.3:
+    resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+    dependencies:
+      '@types/estree': 1.0.5
+    dev: true
+
+  /etag@1.8.1:
+    resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+    engines: {node: '>= 0.6'}
+    dev: true
+
+  /execa@5.1.1:
+    resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+    engines: {node: '>=10'}
+    dependencies:
+      cross-spawn: 7.0.3
+      get-stream: 6.0.1
+      human-signals: 2.1.0
+      is-stream: 2.0.1
+      merge-stream: 2.0.0
+      npm-run-path: 4.0.1
+      onetime: 5.1.2
+      signal-exit: 3.0.7
+      strip-final-newline: 2.0.0
+    dev: true
+
+  /expand-brackets@2.1.4:
+    resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      debug: 2.6.9
+      define-property: 0.2.5
+      extend-shallow: 2.0.1
+      posix-character-classes: 0.1.1
+      regex-not: 1.0.2
+      snapdragon: 0.8.2
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /extend-shallow@2.0.1:
+    resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extendable: 0.1.1
+    dev: true
+
+  /extend-shallow@3.0.2:
+    resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      assign-symbols: 1.0.0
+      is-extendable: 1.0.1
+    dev: true
+
+  /extglob@2.0.4:
+    resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      array-unique: 0.3.2
+      define-property: 1.0.0
+      expand-brackets: 2.1.4
+      extend-shallow: 2.0.1
+      fragment-cache: 0.2.1
+      regex-not: 1.0.2
+      snapdragon: 0.8.2
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /fast-glob@3.3.2:
+    resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+    engines: {node: '>=8.6.0'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      '@nodelib/fs.walk': 1.2.8
+      glob-parent: 5.1.2
+      merge2: 1.4.1
+      micromatch: 4.0.7
+    dev: true
+
+  /fastq@1.17.1:
+    resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+    dependencies:
+      reusify: 1.0.4
+    dev: true
+
+  /fill-range@4.0.0:
+    resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      extend-shallow: 2.0.1
+      is-number: 3.0.0
+      repeat-string: 1.6.1
+      to-regex-range: 2.1.1
+    dev: true
+
+  /fill-range@7.1.1:
+    resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+    engines: {node: '>=8'}
+    dependencies:
+      to-regex-range: 5.0.1
+    dev: true
+
+  /find-up@5.0.0:
+    resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+    engines: {node: '>=10'}
+    dependencies:
+      locate-path: 6.0.0
+      path-exists: 4.0.0
+    dev: true
+
+  /follow-redirects@1.15.6:
+    resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      debug: '*'
+    peerDependenciesMeta:
+      debug:
+        optional: true
+    dev: false
+
+  /for-each@0.3.3:
+    resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+    dependencies:
+      is-callable: 1.2.7
+    dev: true
+
+  /for-in@1.0.2:
+    resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /form-data@4.0.0:
+    resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+    engines: {node: '>= 6'}
+    dependencies:
+      asynckit: 0.4.0
+      combined-stream: 1.0.8
+      mime-types: 2.1.35
+    dev: false
+
+  /fragment-cache@0.2.1:
+    resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      map-cache: 0.2.2
+    dev: true
+
+  /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
+
+  /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
+
+  /function-bind@1.1.2:
+    resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+    dev: true
+
+  /function.prototype.name@1.1.6:
+    resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-abstract: 1.23.3
+      functions-have-names: 1.2.3
+    dev: true
+
+  /functions-have-names@1.2.3:
+    resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+    dev: true
+
+  /get-intrinsic@1.2.4:
+    resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-errors: 1.3.0
+      function-bind: 1.1.2
+      has-proto: 1.0.3
+      has-symbols: 1.0.3
+      hasown: 2.0.2
+    dev: true
+
+  /get-stream@6.0.1:
+    resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /get-symbol-description@1.0.2:
+    resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      get-intrinsic: 1.2.4
+    dev: true
+
+  /get-value@2.0.6:
+    resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /glob-parent@5.1.2:
+    resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+    engines: {node: '>= 6'}
+    dependencies:
+      is-glob: 4.0.3
+    dev: true
+
+  /globalthis@1.0.4:
+    resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-properties: 1.2.1
+      gopd: 1.0.1
+    dev: true
+
+  /gopd@1.0.1:
+    resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+    dependencies:
+      get-intrinsic: 1.2.4
+    dev: true
+
+  /graceful-fs@4.2.11:
+    resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+    dev: true
+
+  /has-ansi@2.0.0:
+    resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      ansi-regex: 2.1.1
+    dev: true
+
+  /has-bigints@1.0.2:
+    resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+    dev: true
+
+  /has-flag@1.0.0:
+    resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /has-property-descriptors@1.0.2:
+    resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+    dependencies:
+      es-define-property: 1.0.0
+    dev: true
+
+  /has-proto@1.0.3:
+    resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /has-symbols@1.0.3:
+    resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /has-tostringtag@1.0.2:
+    resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-symbols: 1.0.3
+    dev: true
+
+  /has-value@0.3.1:
+    resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      get-value: 2.0.6
+      has-values: 0.1.4
+      isobject: 2.1.0
+    dev: true
+
+  /has-value@1.0.0:
+    resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      get-value: 2.0.6
+      has-values: 1.0.0
+      isobject: 3.0.1
+    dev: true
+
+  /has-values@0.1.4:
+    resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /has-values@1.0.0:
+    resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-number: 3.0.0
+      kind-of: 4.0.0
+    dev: true
+
+  /hasown@2.0.2:
+    resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      function-bind: 1.1.2
+    dev: true
+
+  /he@1.2.0:
+    resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+    hasBin: true
+    dev: true
+
+  /highcharts@11.4.3:
+    resolution: {integrity: sha512-rMmvYvcdwyUVfnRPfiZ0PnW6TgVhoS0FTBI8fc4Fp8l8ocoC9dMecvxS6E6tm7h7LrnSGoEo3b/0IRHuLatD2w==}
+    dev: false
+
+  /htmlparser2@3.10.1:
+    resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
+    dependencies:
+      domelementtype: 1.3.1
+      domhandler: 2.4.2
+      domutils: 1.7.0
+      entities: 1.1.2
+      inherits: 2.0.4
+      readable-stream: 3.6.2
+    dev: true
+
+  /human-signals@2.1.0:
+    resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+    engines: {node: '>=10.17.0'}
+    dev: true
+
+  /image-size@0.5.5:
+    resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
+    engines: {node: '>=0.10.0'}
+    hasBin: true
+    dev: true
+
+  /immutable@4.3.6:
+    resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==}
+    dev: true
+
+  /inherits@2.0.4:
+    resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+    dev: true
+
+  /internal-slot@1.0.7:
+    resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-errors: 1.3.0
+      hasown: 2.0.2
+      side-channel: 1.0.6
+    dev: true
+
+  /is-accessor-descriptor@1.0.1:
+    resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==}
+    engines: {node: '>= 0.10'}
+    dependencies:
+      hasown: 2.0.2
+    dev: true
+
+  /is-array-buffer@3.0.4:
+    resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      get-intrinsic: 1.2.4
+    dev: true
+
+  /is-bigint@1.0.4:
+    resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+    dependencies:
+      has-bigints: 1.0.2
+    dev: true
+
+  /is-binary-path@2.1.0:
+    resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+    engines: {node: '>=8'}
+    dependencies:
+      binary-extensions: 2.3.0
+    dev: true
+
+  /is-boolean-object@1.1.2:
+    resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-buffer@1.1.6:
+    resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
+    dev: true
+
+  /is-callable@1.2.7:
+    resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /is-core-module@2.13.1:
+    resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
+    dependencies:
+      hasown: 2.0.2
+    dev: true
+
+  /is-data-descriptor@1.0.1:
+    resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      hasown: 2.0.2
+    dev: true
+
+  /is-data-view@1.0.1:
+    resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-typed-array: 1.1.13
+    dev: true
+
+  /is-date-object@1.0.5:
+    resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-descriptor@0.1.7:
+    resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-accessor-descriptor: 1.0.1
+      is-data-descriptor: 1.0.1
+    dev: true
+
+  /is-descriptor@1.0.3:
+    resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-accessor-descriptor: 1.0.1
+      is-data-descriptor: 1.0.1
+    dev: true
+
+  /is-extendable@0.1.1:
+    resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /is-extendable@1.0.1:
+    resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-plain-object: 2.0.4
+    dev: true
+
+  /is-extglob@2.1.1:
+    resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /is-glob@4.0.3:
+    resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extglob: 2.1.1
+    dev: true
+
+  /is-negative-zero@2.0.3:
+    resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /is-number-object@1.0.7:
+    resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-number@3.0.0:
+    resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      kind-of: 3.2.2
+    dev: true
+
+  /is-number@7.0.0:
+    resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+    engines: {node: '>=0.12.0'}
+    dev: true
+
+  /is-plain-obj@1.1.0:
+    resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /is-plain-object@2.0.4:
+    resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      isobject: 3.0.1
+    dev: true
+
+  /is-regex@1.1.4:
+    resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-shared-array-buffer@1.0.3:
+    resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+    dev: true
+
+  /is-stream@2.0.1:
+    resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /is-string@1.0.7:
+    resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-symbol@1.0.4:
+    resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-symbols: 1.0.3
+    dev: true
+
+  /is-typed-array@1.1.13:
+    resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      which-typed-array: 1.1.15
+    dev: true
+
+  /is-weakref@1.0.2:
+    resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+    dependencies:
+      call-bind: 1.0.7
+    dev: true
+
+  /is-windows@1.0.2:
+    resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /isarray@1.0.0:
+    resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+    dev: true
+
+  /isarray@2.0.5:
+    resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+    dev: true
+
+  /isexe@2.0.0:
+    resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+    dev: true
+
+  /isobject@2.1.0:
+    resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      isarray: 1.0.0
+    dev: true
+
+  /isobject@3.0.1:
+    resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /js-base64@2.6.4:
+    resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
+    dev: true
+
+  /js-tokens@9.0.0:
+    resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==}
+    dev: true
+
+  /json5@1.0.2:
+    resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+    hasBin: true
+    dependencies:
+      minimist: 1.2.8
+    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
+
+  /kind-of@3.2.2:
+    resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-buffer: 1.1.6
+    dev: true
+
+  /kind-of@4.0.0:
+    resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-buffer: 1.1.6
+    dev: true
+
+  /kind-of@5.1.0:
+    resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /kind-of@6.0.3:
+    resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /kolorist@1.8.0:
+    resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+    dev: true
+
+  /loader-utils@1.4.2:
+    resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==}
+    engines: {node: '>=4.0.0'}
+    dependencies:
+      big.js: 5.2.2
+      emojis-list: 3.0.0
+      json5: 1.0.2
+    dev: true
+
+  /local-pkg@0.5.0:
+    resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
+    engines: {node: '>=14'}
+    dependencies:
+      mlly: 1.7.0
+      pkg-types: 1.1.1
+    dev: true
+
+  /locate-path@6.0.0:
+    resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+    engines: {node: '>=10'}
+    dependencies:
+      p-locate: 5.0.0
+    dev: true
+
+  /lodash@4.17.21:
+    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+    dev: false
+
+  /magic-string@0.30.10:
+    resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.4.15
+
+  /map-cache@0.2.2:
+    resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /map-visit@1.0.0:
+    resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      object-visit: 1.0.1
+    dev: true
+
+  /mdn-data@2.0.14:
+    resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
+    dev: true
+
+  /merge-options@1.0.1:
+    resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==}
+    engines: {node: '>=4'}
+    dependencies:
+      is-plain-obj: 1.1.0
+    dev: true
+
+  /merge-stream@2.0.0:
+    resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+    dev: true
+
+  /merge2@1.4.1:
+    resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /micromatch@3.1.0:
+    resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-diff: 4.0.0
+      array-unique: 0.3.2
+      braces: 2.3.2
+      define-property: 1.0.0
+      extend-shallow: 2.0.1
+      extglob: 2.0.4
+      fragment-cache: 0.2.1
+      kind-of: 5.1.0
+      nanomatch: 1.2.13
+      object.pick: 1.3.0
+      regex-not: 1.0.2
+      snapdragon: 0.8.2
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /micromatch@4.0.7:
+    resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
+    engines: {node: '>=8.6'}
+    dependencies:
+      braces: 3.0.3
+      picomatch: 2.3.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
+
+  /mimic-fn@2.1.0:
+    resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /minimatch@9.0.4:
+    resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
+    engines: {node: '>=16 || 14 >=14.17'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: true
+
+  /minimist@1.2.8:
+    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+    dev: true
+
+  /mixin-deep@1.3.2:
+    resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      for-in: 1.0.2
+      is-extendable: 1.0.1
+    dev: true
+
+  /mlly@1.7.0:
+    resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==}
+    dependencies:
+      acorn: 8.11.3
+      pathe: 1.1.2
+      pkg-types: 1.1.1
+      ufo: 1.5.3
+    dev: true
+
+  /moment@2.30.1:
+    resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
+    dev: false
+
+  /ms@2.0.0:
+    resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+    dev: true
+
+  /ms@2.1.2:
+    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+    dev: true
+
+  /nanoid@3.3.7:
+    resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+
+  /nanomatch@1.2.13:
+    resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-diff: 4.0.0
+      array-unique: 0.3.2
+      define-property: 2.0.2
+      extend-shallow: 3.0.2
+      fragment-cache: 0.2.1
+      is-windows: 1.0.2
+      kind-of: 6.0.3
+      object.pick: 1.3.0
+      regex-not: 1.0.2
+      snapdragon: 0.8.2
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /normalize-path@3.0.0:
+    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /normalize.css@8.0.1:
+    resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
+    dev: false
+
+  /npm-run-path@4.0.1:
+    resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
+    engines: {node: '>=8'}
+    dependencies:
+      path-key: 3.1.1
+    dev: true
+
+  /nth-check@2.1.1:
+    resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+    dependencies:
+      boolbase: 1.0.0
+    dev: true
+
+  /object-assign@4.1.1:
+    resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /object-copy@0.1.0:
+    resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      copy-descriptor: 0.1.1
+      define-property: 0.2.5
+      kind-of: 3.2.2
+    dev: true
+
+  /object-inspect@1.13.1:
+    resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
+    dev: true
+
+  /object-keys@1.1.1:
+    resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /object-visit@1.0.1:
+    resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      isobject: 3.0.1
+    dev: true
+
+  /object.assign@4.1.5:
+    resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      has-symbols: 1.0.3
+      object-keys: 1.1.1
+    dev: true
+
+  /object.pick@1.3.0:
+    resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      isobject: 3.0.1
+    dev: true
+
+  /onetime@5.1.2:
+    resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+    engines: {node: '>=6'}
+    dependencies:
+      mimic-fn: 2.1.0
+    dev: true
+
+  /p-limit@3.1.0:
+    resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      yocto-queue: 0.1.0
+    dev: true
+
+  /p-locate@5.0.0:
+    resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+    engines: {node: '>=10'}
+    dependencies:
+      p-limit: 3.1.0
+    dev: true
+
+  /pascalcase@0.1.1:
+    resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /path-exists@4.0.0:
+    resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /path-key@3.1.1:
+    resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /path-parse@1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+    dev: true
+
+  /pathe@0.2.0:
+    resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
+    dev: true
+
+  /pathe@1.1.2:
+    resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+    dev: true
+
+  /picocolors@1.0.1:
+    resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
+
+  /picomatch@2.3.1:
+    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+    engines: {node: '>=8.6'}
+    dev: true
+
+  /pkg-types@1.1.1:
+    resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
+    dependencies:
+      confbox: 0.1.7
+      mlly: 1.7.0
+      pathe: 1.1.2
+    dev: true
+
+  /posix-character-classes@0.1.1:
+    resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /possible-typed-array-names@1.0.0:
+    resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /postcss-prefix-selector@1.16.1(postcss@5.2.18):
+    resolution: {integrity: sha512-Umxu+FvKMwlY6TyDzGFoSUnzW+NOfMBLyC1tAkIjgX+Z/qGspJeRjVC903D7mx7TuBpJlwti2ibXtWuA7fKMeQ==}
+    peerDependencies:
+      postcss: '>4 <9'
+    dependencies:
+      postcss: 5.2.18
+    dev: true
+
+  /postcss-px-to-viewport@1.1.1:
+    resolution: {integrity: sha512-2x9oGnBms+e0cYtBJOZdlwrFg/mLR4P1g2IFu7jYKvnqnH/HLhoKyareW2Q/x4sg0BgklHlP1qeWo2oCyPm8FQ==}
+    dependencies:
+      object-assign: 4.1.1
+      postcss: 8.4.38
+    dev: true
+
+  /postcss@5.2.18:
+    resolution: {integrity: sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==}
+    engines: {node: '>=0.12'}
+    dependencies:
+      chalk: 1.1.3
+      js-base64: 2.6.4
+      source-map: 0.5.7
+      supports-color: 3.2.3
+    dev: true
+
+  /postcss@8.4.38:
+    resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.3.7
+      picocolors: 1.0.1
+      source-map-js: 1.2.0
+
+  /posthtml-parser@0.2.1:
+    resolution: {integrity: sha512-nPC53YMqJnc/+1x4fRYFfm81KV2V+G9NZY+hTohpYg64Ay7NemWWcV4UWuy/SgMupqQ3kJ88M/iRfZmSnxT+pw==}
+    dependencies:
+      htmlparser2: 3.10.1
+      isobject: 2.1.0
+    dev: true
+
+  /posthtml-rename-id@1.0.12:
+    resolution: {integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==}
+    dependencies:
+      escape-string-regexp: 1.0.5
+    dev: true
+
+  /posthtml-render@1.4.0:
+    resolution: {integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /posthtml-svg-mode@1.0.3:
+    resolution: {integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==}
+    dependencies:
+      merge-options: 1.0.1
+      posthtml: 0.9.2
+      posthtml-parser: 0.2.1
+      posthtml-render: 1.4.0
+    dev: true
+
+  /posthtml@0.9.2:
+    resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      posthtml-parser: 0.2.1
+      posthtml-render: 1.4.0
+    dev: true
+
+  /proxy-from-env@1.1.0:
+    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+    dev: false
+
+  /query-string@4.3.4:
+    resolution: {integrity: sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      object-assign: 4.1.1
+      strict-uri-encode: 1.1.0
+    dev: true
+
+  /queue-microtask@1.2.3:
+    resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+    dev: true
+
+  /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: true
+
+  /readdirp@3.6.0:
+    resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+    engines: {node: '>=8.10.0'}
+    dependencies:
+      picomatch: 2.3.1
+    dev: true
+
+  /regenerator-runtime@0.14.1:
+    resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+    dev: false
+
+  /regex-not@1.0.2:
+    resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      extend-shallow: 3.0.2
+      safe-regex: 1.1.0
+    dev: true
+
+  /regexp.prototype.flags@1.5.2:
+    resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-errors: 1.3.0
+      set-function-name: 2.0.2
+    dev: true
+
+  /repeat-element@1.1.4:
+    resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /repeat-string@1.6.1:
+    resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==}
+    engines: {node: '>=0.10'}
+    dev: true
+
+  /resolve-url@0.2.1:
+    resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==}
+    deprecated: https://github.com/lydell/resolve-url#deprecated
+    dev: true
+
+  /resolve@1.22.8:
+    resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+    hasBin: true
+    dependencies:
+      is-core-module: 2.13.1
+      path-parse: 1.0.7
+      supports-preserve-symlinks-flag: 1.0.0
+    dev: true
+
+  /ret@0.1.15:
+    resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==}
+    engines: {node: '>=0.12'}
+    dev: true
+
+  /reusify@1.0.4:
+    resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+    engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+    dev: true
+
+  /rollup@4.18.0:
+    resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==}
+    engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+    hasBin: true
+    dependencies:
+      '@types/estree': 1.0.5
+    optionalDependencies:
+      '@rollup/rollup-android-arm-eabi': 4.18.0
+      '@rollup/rollup-android-arm64': 4.18.0
+      '@rollup/rollup-darwin-arm64': 4.18.0
+      '@rollup/rollup-darwin-x64': 4.18.0
+      '@rollup/rollup-linux-arm-gnueabihf': 4.18.0
+      '@rollup/rollup-linux-arm-musleabihf': 4.18.0
+      '@rollup/rollup-linux-arm64-gnu': 4.18.0
+      '@rollup/rollup-linux-arm64-musl': 4.18.0
+      '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0
+      '@rollup/rollup-linux-riscv64-gnu': 4.18.0
+      '@rollup/rollup-linux-s390x-gnu': 4.18.0
+      '@rollup/rollup-linux-x64-gnu': 4.18.0
+      '@rollup/rollup-linux-x64-musl': 4.18.0
+      '@rollup/rollup-win32-arm64-msvc': 4.18.0
+      '@rollup/rollup-win32-ia32-msvc': 4.18.0
+      '@rollup/rollup-win32-x64-msvc': 4.18.0
+      fsevents: 2.3.3
+    dev: true
+
+  /run-parallel@1.2.0:
+    resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+    dependencies:
+      queue-microtask: 1.2.3
+    dev: true
+
+  /safe-array-concat@1.1.2:
+    resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
+    engines: {node: '>=0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      get-intrinsic: 1.2.4
+      has-symbols: 1.0.3
+      isarray: 2.0.5
+    dev: true
+
+  /safe-buffer@5.2.1:
+    resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+    dev: true
+
+  /safe-regex-test@1.0.3:
+    resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      is-regex: 1.1.4
+    dev: true
+
+  /safe-regex@1.1.0:
+    resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==}
+    dependencies:
+      ret: 0.1.15
+    dev: true
+
+  /sass@1.77.4:
+    resolution: {integrity: sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==}
+    engines: {node: '>=14.0.0'}
+    hasBin: true
+    dependencies:
+      chokidar: 3.6.0
+      immutable: 4.3.6
+      source-map-js: 1.2.0
+    dev: true
+
+  /scule@1.3.0:
+    resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
+    dev: true
+
+  /set-function-length@1.2.2:
+    resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.4
+      es-errors: 1.3.0
+      function-bind: 1.1.2
+      get-intrinsic: 1.2.4
+      gopd: 1.0.1
+      has-property-descriptors: 1.0.2
+    dev: true
+
+  /set-function-name@2.0.2:
+    resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.4
+      es-errors: 1.3.0
+      functions-have-names: 1.2.3
+      has-property-descriptors: 1.0.2
+    dev: true
+
+  /set-value@2.0.1:
+    resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      extend-shallow: 2.0.1
+      is-extendable: 0.1.1
+      is-plain-object: 2.0.4
+      split-string: 3.1.0
+    dev: true
+
+  /shebang-command@2.0.0:
+    resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+    engines: {node: '>=8'}
+    dependencies:
+      shebang-regex: 3.0.0
+    dev: true
+
+  /shebang-regex@3.0.0:
+    resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /side-channel@1.0.6:
+    resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      get-intrinsic: 1.2.4
+      object-inspect: 1.13.1
+    dev: true
+
+  /signal-exit@3.0.7:
+    resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+    dev: true
+
+  /snapdragon-node@2.1.1:
+    resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      define-property: 1.0.0
+      isobject: 3.0.1
+      snapdragon-util: 3.0.1
+    dev: true
+
+  /snapdragon-util@3.0.1:
+    resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      kind-of: 3.2.2
+    dev: true
+
+  /snapdragon@0.8.2:
+    resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      base: 0.11.2
+      debug: 2.6.9
+      define-property: 0.2.5
+      extend-shallow: 2.0.1
+      map-cache: 0.2.2
+      source-map: 0.5.7
+      source-map-resolve: 0.5.3
+      use: 3.1.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /source-map-js@1.2.0:
+    resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
+    engines: {node: '>=0.10.0'}
+
+  /source-map-resolve@0.5.3:
+    resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==}
+    deprecated: See https://github.com/lydell/source-map-resolve#deprecated
+    dependencies:
+      atob: 2.1.2
+      decode-uri-component: 0.2.2
+      resolve-url: 0.2.1
+      source-map-url: 0.4.1
+      urix: 0.1.0
+    dev: true
+
+  /source-map-url@0.4.1:
+    resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==}
+    deprecated: See https://github.com/lydell/source-map-url#deprecated
+    dev: true
+
+  /source-map@0.5.7:
+    resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /source-map@0.6.1:
+    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /split-string@3.1.0:
+    resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      extend-shallow: 3.0.2
+    dev: true
+
+  /stable@0.1.8:
+    resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
+    deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
+    dev: true
+
+  /static-extend@0.1.2:
+    resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      define-property: 0.2.5
+      object-copy: 0.1.0
+    dev: true
+
+  /strict-uri-encode@1.1.0:
+    resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /string-argv@0.3.2:
+    resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
+    engines: {node: '>=0.6.19'}
+    dev: true
+
+  /string.prototype.trim@1.2.9:
+    resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-abstract: 1.23.3
+      es-object-atoms: 1.0.0
+    dev: true
+
+  /string.prototype.trimend@1.0.8:
+    resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-object-atoms: 1.0.0
+    dev: true
+
+  /string.prototype.trimstart@1.0.8:
+    resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-object-atoms: 1.0.0
+    dev: true
+
+  /string_decoder@1.3.0:
+    resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+    dependencies:
+      safe-buffer: 5.2.1
+    dev: true
+
+  /strip-ansi@3.0.1:
+    resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      ansi-regex: 2.1.1
+    dev: true
+
+  /strip-final-newline@2.0.0:
+    resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /strip-literal@2.1.0:
+    resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
+    dependencies:
+      js-tokens: 9.0.0
+    dev: true
+
+  /supports-color@2.0.0:
+    resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==}
+    engines: {node: '>=0.8.0'}
+    dev: true
+
+  /supports-color@3.2.3:
+    resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==}
+    engines: {node: '>=0.8.0'}
+    dependencies:
+      has-flag: 1.0.0
+    dev: true
+
+  /supports-preserve-symlinks-flag@1.0.0:
+    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /svg-baker@1.7.0:
+    resolution: {integrity: sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==}
+    dependencies:
+      bluebird: 3.7.2
+      clone: 2.1.2
+      he: 1.2.0
+      image-size: 0.5.5
+      loader-utils: 1.4.2
+      merge-options: 1.0.1
+      micromatch: 3.1.0
+      postcss: 5.2.18
+      postcss-prefix-selector: 1.16.1(postcss@5.2.18)
+      posthtml-rename-id: 1.0.12
+      posthtml-svg-mode: 1.0.3
+      query-string: 4.3.4
+      traverse: 0.6.9
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /svgo@2.8.0:
+    resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    dependencies:
+      '@trysound/sax': 0.2.0
+      commander: 7.2.0
+      css-select: 4.3.0
+      css-tree: 1.1.3
+      csso: 4.2.0
+      picocolors: 1.0.1
+      stable: 0.1.8
+    dev: true
+
+  /tdesign-icons-vue-next@0.2.2(vue@3.4.21):
+    resolution: {integrity: sha512-ZKleBME7ZF1IVgnRXmIBPjfNa2Mef1nrK56f2xwn1Aa5mvXxB3fSxEzwhObR7bhzf/K42mz/Knnbll5Y7vCBjg==}
+    peerDependencies:
+      vue: ^3.0.0
+    dependencies:
+      '@babel/runtime': 7.24.6
+      vue: 3.4.21
+    dev: false
+
+  /tdesign-mobile-vue@1.2.3(vue@3.4.21):
+    resolution: {integrity: sha512-UPS0stFfwfj8bf7wkJAyYcmuJtaBG0M6l/hdcHY5v22XnOAWy4PKi+K1HElWlIFGfPIRDC6+ZixenL7TPxYjAQ==}
+    engines: {node: '>=12.0.0'}
+    peerDependencies:
+      vue: ^3.2.6
+    dependencies:
+      '@babel/runtime': 7.24.6
+      '@use-gesture/vanilla': 10.3.1
+      '@vueuse/core': 10.7.0(vue@3.4.21)
+      dayjs: 1.11.11
+      lodash: 4.17.21
+      tdesign-icons-vue-next: 0.2.2(vue@3.4.21)
+      validator: 13.12.0
+      vue: 3.4.21
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+    dev: false
+
+  /to-fast-properties@2.0.0:
+    resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+    engines: {node: '>=4'}
+
+  /to-object-path@0.3.0:
+    resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      kind-of: 3.2.2
+    dev: true
+
+  /to-regex-range@2.1.1:
+    resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-number: 3.0.0
+      repeat-string: 1.6.1
+    dev: true
+
+  /to-regex-range@5.0.1:
+    resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+    engines: {node: '>=8.0'}
+    dependencies:
+      is-number: 7.0.0
+    dev: true
+
+  /to-regex@3.0.2:
+    resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      define-property: 2.0.2
+      extend-shallow: 3.0.2
+      regex-not: 1.0.2
+      safe-regex: 1.1.0
+    dev: true
+
+  /traverse@0.6.9:
+    resolution: {integrity: sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      gopd: 1.0.1
+      typedarray.prototype.slice: 1.0.3
+      which-typed-array: 1.1.15
+    dev: true
+
+  /type-detect@4.0.8:
+    resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /typed-array-buffer@1.0.2:
+    resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      es-errors: 1.3.0
+      is-typed-array: 1.1.13
+    dev: true
+
+  /typed-array-byte-length@1.0.1:
+    resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      for-each: 0.3.3
+      gopd: 1.0.1
+      has-proto: 1.0.3
+      is-typed-array: 1.1.13
+    dev: true
+
+  /typed-array-byte-offset@1.0.2:
+    resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.7
+      call-bind: 1.0.7
+      for-each: 0.3.3
+      gopd: 1.0.1
+      has-proto: 1.0.3
+      is-typed-array: 1.1.13
+    dev: true
+
+  /typed-array-length@1.0.6:
+    resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      for-each: 0.3.3
+      gopd: 1.0.1
+      has-proto: 1.0.3
+      is-typed-array: 1.1.13
+      possible-typed-array-names: 1.0.0
+    dev: true
+
+  /typedarray.prototype.slice@1.0.3:
+    resolution: {integrity: sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.7
+      define-properties: 1.2.1
+      es-abstract: 1.23.3
+      es-errors: 1.3.0
+      typed-array-buffer: 1.0.2
+      typed-array-byte-offset: 1.0.2
+    dev: true
+
+  /ufo@1.5.3:
+    resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
+    dev: true
+
+  /unbox-primitive@1.0.2:
+    resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+    dependencies:
+      call-bind: 1.0.7
+      has-bigints: 1.0.2
+      has-symbols: 1.0.3
+      which-boxed-primitive: 1.0.2
+    dev: true
+
+  /undici-types@5.26.5:
+    resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+    dev: true
+
+  /unimport@3.7.2:
+    resolution: {integrity: sha512-91mxcZTadgXyj3lFWmrGT8GyoRHWuE5fqPOjg5RVtF6vj+OfM5G6WCzXjuYtSgELE5ggB34RY4oiCSEP8I3AHw==}
+    dependencies:
+      '@rollup/pluginutils': 5.1.0
+      acorn: 8.11.3
+      escape-string-regexp: 5.0.0
+      estree-walker: 3.0.3
+      fast-glob: 3.3.2
+      local-pkg: 0.5.0
+      magic-string: 0.30.10
+      mlly: 1.7.0
+      pathe: 1.1.2
+      pkg-types: 1.1.1
+      scule: 1.3.0
+      strip-literal: 2.1.0
+      unplugin: 1.10.1
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
+  /union-value@1.0.1:
+    resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-union: 3.1.0
+      get-value: 2.0.6
+      is-extendable: 0.1.1
+      set-value: 2.0.1
+    dev: true
+
+  /universalify@2.0.1:
+    resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+    engines: {node: '>= 10.0.0'}
+    dev: true
+
+  /unplugin-auto-import@0.17.6:
+    resolution: {integrity: sha512-dmX0Pex5DzMzVuALkexboOZvh51fL/BD6aoPO7qHoTYGlQp0GRKsREv2KMF1lzYI9SXKQiRxAjwzbQnrFFNydQ==}
+    engines: {node: '>=14'}
+    peerDependencies:
+      '@nuxt/kit': ^3.2.2
+      '@vueuse/core': '*'
+    peerDependenciesMeta:
+      '@nuxt/kit':
+        optional: true
+      '@vueuse/core':
+        optional: true
+    dependencies:
+      '@antfu/utils': 0.7.8
+      '@rollup/pluginutils': 5.1.0
+      fast-glob: 3.3.2
+      local-pkg: 0.5.0
+      magic-string: 0.30.10
+      minimatch: 9.0.4
+      unimport: 3.7.2
+      unplugin: 1.10.1
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
+  /unplugin-icons@0.19.0:
+    resolution: {integrity: sha512-u5g/gIZPZEj1wUGEQxe9nzftOSqmblhusc+sL3cawIRoIt/xWpE6XYcPOfAeFTYNjSbRrX/3QiX89PFiazgU1w==}
+    peerDependencies:
+      '@svgr/core': '>=7.0.0'
+      '@svgx/core': ^1.0.1
+      '@vue/compiler-sfc': ^3.0.2 || ^2.7.0
+      vue-template-compiler: ^2.6.12
+      vue-template-es2015-compiler: ^1.9.0
+    peerDependenciesMeta:
+      '@svgr/core':
+        optional: true
+      '@svgx/core':
+        optional: true
+      '@vue/compiler-sfc':
+        optional: true
+      vue-template-compiler:
+        optional: true
+      vue-template-es2015-compiler:
+        optional: true
+    dependencies:
+      '@antfu/install-pkg': 0.3.3
+      '@antfu/utils': 0.7.8
+      '@iconify/utils': 2.1.24
+      debug: 4.3.5
+      kolorist: 1.8.0
+      local-pkg: 0.5.0
+      unplugin: 1.10.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /unplugin-vue-components@0.27.0(vue@3.4.21):
+    resolution: {integrity: sha512-77eTEy23sQ0UpzGWnZ9I2mY3cnmXwklz4ITcn3JfxjCoX643ghImkiZ4nFm58sxbdVcc4Fo/o4LIoFnlqEqsSg==}
+    engines: {node: '>=14'}
+    peerDependencies:
+      '@babel/parser': ^7.15.8
+      '@nuxt/kit': ^3.2.2
+      vue: 2 || 3
+    peerDependenciesMeta:
+      '@babel/parser':
+        optional: true
+      '@nuxt/kit':
+        optional: true
+    dependencies:
+      '@antfu/utils': 0.7.8
+      '@rollup/pluginutils': 5.1.0
+      chokidar: 3.6.0
+      debug: 4.3.5
+      fast-glob: 3.3.2
+      local-pkg: 0.5.0
+      magic-string: 0.30.10
+      minimatch: 9.0.4
+      resolve: 1.22.8
+      unplugin: 1.10.1
+      vue: 3.4.21
+    transitivePeerDependencies:
+      - rollup
+      - supports-color
+    dev: true
+
+  /unplugin@1.10.1:
+    resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==}
+    engines: {node: '>=14.0.0'}
+    dependencies:
+      acorn: 8.11.3
+      chokidar: 3.6.0
+      webpack-sources: 3.2.3
+      webpack-virtual-modules: 0.6.1
+    dev: true
+
+  /unset-value@1.0.0:
+    resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      has-value: 0.3.1
+      isobject: 3.0.1
+    dev: true
+
+  /urix@0.1.0:
+    resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==}
+    deprecated: Please see https://github.com/lydell/urix#deprecated
+    dev: true
+
+  /use@3.1.1:
+    resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /util-deprecate@1.0.2:
+    resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+    dev: true
+
+  /validator@13.12.0:
+    resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==}
+    engines: {node: '>= 0.10'}
+    dev: false
+
+  /vary@1.1.2:
+    resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+    engines: {node: '>= 0.8'}
+    dev: true
+
+  /vite-plugin-svg-icons@2.0.1(vite@5.2.0):
+    resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==}
+    peerDependencies:
+      vite: '>=2.0.0'
+    dependencies:
+      '@types/svgo': 2.6.4
+      cors: 2.8.5
+      debug: 4.3.5
+      etag: 1.8.1
+      fs-extra: 10.1.0
+      pathe: 0.2.0
+      svg-baker: 1.7.0
+      svgo: 2.8.0
+      vite: 5.2.0(sass@1.77.4)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /vite@5.2.0(sass@1.77.4):
+    resolution: {integrity: sha512-xMSLJNEjNk/3DJRgWlPADDwaU9AgYRodDH2t6oENhJnIlmU9Hx1Q6VpjyXua/JdMw1WJRbnAgHJ9xgET9gnIAg==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': ^18.0.0 || >=20.0.0
+      less: '*'
+      lightningcss: ^1.21.0
+      sass: '*'
+      stylus: '*'
+      sugarss: '*'
+      terser: ^5.4.0
+    peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      less:
+        optional: true
+      lightningcss:
+        optional: true
+      sass:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+    dependencies:
+      esbuild: 0.20.2
+      postcss: 8.4.38
+      rollup: 4.18.0
+      sass: 1.77.4
+    optionalDependencies:
+      fsevents: 2.3.3
+    dev: true
+
+  /vue-demi@0.14.8(vue@3.4.21):
+    resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    peerDependencies:
+      '@vue/composition-api': ^1.0.0-rc.1
+      vue: ^3.0.0-0 || ^2.6.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+    dependencies:
+      vue: 3.4.21
+    dev: false
+
+  /vue-router@4.3.2(vue@3.4.21):
+    resolution: {integrity: sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@vue/devtools-api': 6.6.2
+      vue: 3.4.21
+    dev: false
+
+  /vue@3.4.21:
+    resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@vue/compiler-dom': 3.4.21
+      '@vue/compiler-sfc': 3.4.21
+      '@vue/runtime-dom': 3.4.21
+      '@vue/server-renderer': 3.4.21(vue@3.4.21)
+      '@vue/shared': 3.4.21
+
+  /webpack-sources@3.2.3:
+    resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
+    engines: {node: '>=10.13.0'}
+    dev: true
+
+  /webpack-virtual-modules@0.6.1:
+    resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==}
+    dev: true
+
+  /which-boxed-primitive@1.0.2:
+    resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+    dependencies:
+      is-bigint: 1.0.4
+      is-boolean-object: 1.1.2
+      is-number-object: 1.0.7
+      is-string: 1.0.7
+      is-symbol: 1.0.4
+    dev: true
+
+  /which-typed-array@1.1.15:
+    resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.7
+      call-bind: 1.0.7
+      for-each: 0.3.3
+      gopd: 1.0.1
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /which@2.0.2:
+    resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+    engines: {node: '>= 8'}
+    hasBin: true
+    dependencies:
+      isexe: 2.0.0
+    dev: true
+
+  /yocto-queue@0.1.0:
+    resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+    engines: {node: '>=10'}
+    dev: true

+ 21 - 0
postcss.config.cjs

@@ -0,0 +1,21 @@
+module.exports = {
+  plugins: {
+    "postcss-px-to-viewport": {
+      unitToConvert: "px", // 需要转换的单位,默认为"px"
+      viewportWidth: 750, //  设计稿的视口宽度
+      unitPrecision: 5, // 单位转换后保留的精度
+      propList: ["*"], // 能转化为vw的属性列表
+      viewportUnit: "vw", //  希望使用的视口单位
+      fontViewportUnit: "vw", // 字体使用的视口单位
+      selectorBlackList: [], // 需要忽略的CSS选择器
+      minPixelValue: 1, // 最小的转换数值,如果为1的话,只有大于1的值会被转换
+      mediaQuery: false, // 媒体查询里的单位是否需要转换单位
+      replace: true, // 是否直接更换属性值,而不添加备用属性
+      exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件
+      include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件 (include: /\/src\/mobile\//)
+      landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
+      landscapeUnit: "px", // 横屏时使用的单位
+      landscapeWidth: 568, // 横屏时使用的视口宽度
+    },
+  },
+};

+ 1 - 0
public/vite.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

+ 8 - 0
src/App.vue

@@ -0,0 +1,8 @@
+<script setup>
+
+</script>
+
+<template>
+  <router-view></router-view>
+</template>
+

+ 6 - 0
src/api/customer/index.js

@@ -0,0 +1,6 @@
+import apiCustomerUser from './modules/user'
+
+export {
+  apiCustomerUser,
+}
+

+ 35 - 0
src/api/customer/modules/user.js

@@ -0,0 +1,35 @@
+import { get, post } from "@/api/index";
+
+export default {
+  //用户列表数据
+  userList: params => {
+    return get("/user/list", params);
+  },
+  userInfo: params => {
+    return get("/user/detail", params);
+  },
+  // 新增用户
+  userAdd:params=>{
+    return post("/user/add", params);
+  },
+  // 编辑用户
+  userEdit:params=>{
+    return post("/user/edit", params);
+  },
+  userPermissionData:params=>{
+    return get('/chart_permission/list',params)
+  },
+  // 用户操作记录
+  userOperationRecord:params=>{
+    return get('/user/change_list',params)
+  },
+  // 启用\禁用用户
+  setUserStatus:params=>{
+    return post('/user/editEnabled',params)
+  },
+  //删除用户
+  userDelete:params=>{
+    return post('/user/delete',params)
+  }
+  
+};

+ 92 - 0
src/api/index.js

@@ -0,0 +1,92 @@
+"use strict";
+import axios from "axios";
+import CryptoJS from '@/utils/crypto'
+import { Toast } from 'tdesign-mobile-vue';
+// Full config:  https://github.com/axios/axios#request-config
+// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
+// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
+// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+
+let config = {
+  baseURL: import.meta.env.VITE_APP_API_URL,
+  timeout: 10*60 * 1000, // Timeout
+  // withCredentials: true, // Check cross-site Access-Control
+};
+
+const _axios = axios.create(config);
+
+_axios.interceptors.request.use(
+  function (config) {
+    // Do something before request is sent
+    let auth = localStorage.getItem('token')
+    if(auth) {
+      config.headers.Authorization = auth;
+    }
+    // config.headers.Authorization=localStorage.getItem('token')||''
+    return config;
+  },
+  function (error) {
+    // Do something with request error
+    return Promise.reject(error);
+  }
+);
+
+// Add a response interceptor
+_axios.interceptors.response.use(
+  function (response) {
+    // Do something with response data
+    let data
+    if(import.meta.env.MODE==='production'){
+      data=JSON.parse(CryptoJS.Des3Decrypt(response.data,import.meta.env.VITE_APP_RESPONSE_DES_KEY));//解密
+    }else{
+      data=response.data
+    }
+    
+
+    if(response.status!==200){
+      setTimeout(() => {
+        Toast('网络异常')
+      }, 100);
+    }
+
+    if(!data){
+      setTimeout(() => {
+        Toast('服务器开了个小差')
+      }, 100);
+    }
+    if(data.Ret===408){//token失效
+      Toast(data.Msg)
+    }
+    if(data.Ret===403){
+      setTimeout(() => {
+        Toast(data.Msg||'网络异常')
+      }, 100);
+    }
+
+    return data;
+  },
+  function (error) {
+    console.log(error);
+    Toast(error.message)
+    // Do something with response error
+    return Promise.reject(error);
+  }
+);
+
+/**
+ * 导出get请求方法
+ * @url 请求地址
+ * @params get请求参数
+ */
+export const get = (url, params) => {
+  return _axios.get(url, { params });
+};
+
+/**
+ * 导出post请求方法
+ * @url 请求地址
+ * @params post请求参数
+ */
+export const post = (url, params) => {
+  return _axios.post(url, params);
+};

+ 12 - 0
src/api/system/common.js

@@ -0,0 +1,12 @@
+import {get,post} from '@/api/index'
+
+export default{
+    //登录
+    login:(params)=>{
+        return post('/sys_user/login',params)
+    },
+    // 手机号区号
+    phoneAreaCode:()=>{
+        return get('/sys_user/area_code/list',{})
+    }
+}

+ 24 - 0
src/api/system/depart.js

@@ -0,0 +1,24 @@
+import { get, post } from "@/api/index";
+
+export default {
+  //部门数据
+  departList: () => {
+    return get("/department/list", {});
+  },
+  // 部门排序
+  departSort:params=>{
+    return post('/department/set_sort',params)
+  },
+  // 部门删除
+  departDel:params=>{
+    return post('/department/delete',params)
+  },
+  // 部门新增
+  departAdd:params=>{
+    return post('/department/add',params)
+  },
+  // 部门编辑
+  departEdit:params=>{
+    return post('/department/edit',params)
+  }
+};

+ 14 - 0
src/api/system/index.js

@@ -0,0 +1,14 @@
+import apiSystemCommon from './common'
+import apiSystemDepart from './depart'
+import apiSystemUser from './user'
+import apiSystemRole from './role'
+import apiSystemMessage from './message'
+
+export {
+    apiSystemCommon,
+    apiSystemDepart,
+    apiSystemUser,
+    apiSystemRole,
+    apiSystemMessage
+}
+

+ 12 - 0
src/api/system/message.js

@@ -0,0 +1,12 @@
+import { get, post } from "@/api/index";
+
+export default {
+  //系统消息
+  list: () => {
+    return get("/sys_message/list", {});
+  },
+  // 手机号区号
+  msgRead: (params) => {
+    return post("/sys_message/read", params);
+  },
+};

+ 34 - 0
src/api/system/role.js

@@ -0,0 +1,34 @@
+import { get, post } from "@/api/index";
+
+export default {
+  //角色列表
+  roleList: () => {
+    return get("/role/list", {});
+  },
+  //角色新增
+  roleAdd: params => {
+    return post("/role/add", params);
+  },
+  //角色编辑
+  roleEdit: params => {
+    return post("/role/edit", params);
+  },
+  //角色删除
+  roleDel: params => {
+    return post("/role/delete", params);
+  },
+  // 角色对应的权限
+  roleAuthList:params=>{
+    return get('/role/menu/auth_list',params)
+  },
+  //设置角色的权限
+  roleAuthSet:params=>{
+    return post('/role/menu/auth_save',params)
+  },
+  // 角色对应的菜单数据
+  menuData:()=>{
+    return get('/role/menu/list',{})
+  }
+  
+  
+};

+ 38 - 0
src/api/system/user.js

@@ -0,0 +1,38 @@
+import { get, post } from "@/api/index";
+
+export default {
+  //用户列表数据
+  userList: params => {
+    return get("/sys_user/list", params);
+  },
+  // 新增用户
+  userAdd:params=>{
+    return post("/sys_user/add", params);
+  },
+  // 编辑用户
+  userEdit:params=>{
+    return post("/sys_user/edit", params);
+  },
+  // 重置用户密码
+  resetUserPwd:params=>{
+    return post("/sys_user/reset_pass", params);
+  },
+  // 移动用户分组
+  moveUserDepart:params=>{
+    return post("/sys_user/moveToDepartment", params);
+  },
+  // 启用\禁用用户
+  setUserEnableStatus:params=>{
+    return post("/sys_user/editEnabled", params);
+  },
+  // 系统用户的按钮权限数据
+  userPermissionData:()=>{
+    return get('/role/menu/buttons',{})
+  },
+  // 获取系统中所有用户 按部门分级
+  allUserForDepart:params=>{
+    return get('/seller/list',params)
+  }
+
+  
+};

TEMPAT SAMPAH
src/assets/imgs/404.png


TEMPAT SAMPAH
src/assets/imgs/lock-img.png


+ 5 - 0
src/assets/svg/backtop.svg

@@ -0,0 +1,5 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="100" height="100" rx="50" fill="#053CC9"/>
+<path d="M24 29.2819H76V25H24V29.2819Z" fill="white"/>
+<path d="M29.9708 60.2414L47.7796 42.969L47.7797 80L52.1601 79.9997L52.16 42.9461L70.2749 60.4036L73.3675 57.4042L50.6611 35.522C50.2729 35.1478 49.658 35.1488 49.2709 35.5242L26.8686 57.2518L29.9708 60.2414Z" fill="white"/>
+</svg>

+ 4 - 0
src/assets/svg/collect.svg

@@ -0,0 +1,4 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="100" height="100" rx="50" fill="#FFAE4F"/>
+<path d="M56.1663 43.521L50.0058 31.0384L43.8453 43.521L30.07 45.5227L40.0379 55.239L37.6848 68.9586L50.0058 62.481L62.3268 68.9586L59.9736 55.239L69.9416 45.5227L56.1663 43.521ZM76.1312 42.3801C77.1156 42.5231 77.5084 43.7327 76.7964 44.4269L64.2716 56.6355L67.2284 73.8742C67.3964 74.8546 66.3676 75.6022 65.4872 75.1394L50.0058 67.0002L34.5244 75.1394C33.6441 75.6022 32.6152 74.8546 32.7833 73.8742L35.74 56.6355L23.2153 44.4269C22.503 43.7327 22.896 42.5231 23.8803 42.3801L41.189 39.865L48.9297 24.1806C49.3699 23.2887 50.6417 23.2888 51.0819 24.1806L58.8224 39.865L76.1312 42.3801Z" fill="white"/>
+</svg>

+ 4 - 0
src/assets/svg/collected.svg

@@ -0,0 +1,4 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="100" height="100" rx="50" fill="#FFAE4F"/>
+<path d="M48.3905 25.271C49.0507 23.9331 50.9584 23.9331 51.6187 25.271L58.8214 39.8652L74.927 42.2054C76.4034 42.42 76.993 44.2343 75.9246 45.2757L64.2702 56.6356L67.0214 72.676C67.2738 74.1468 65.7302 75.268 64.4098 74.5736L50.0046 67.0004L35.5993 74.5736C34.2788 75.268 32.7354 74.1468 32.9876 72.6764L35.7388 56.6356L24.0846 45.2757C23.0163 44.2343 23.6058 42.42 25.0822 42.2054L41.1878 39.8652L48.3905 25.271Z" fill="white"/>
+</svg>

+ 3 - 0
src/assets/svg/icon01.svg

@@ -0,0 +1,3 @@
+<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M26.5439 24.9503H16.6326V17.9426C16.6326 15.0837 16.8853 12.8408 17.3909 11.2138C17.8965 9.58682 18.4222 8.50069 19.7978 7.19909C21.1734 5.89749 22.1279 5.5069 24.147 5L25.5577 7.97425C24.147 8.50267 23.2876 8.73835 21.9622 10.0864C20.6367 11.4345 20.5389 12.7384 20.5389 13.8591H26.5439V24.9503ZM12.9114 24.9503H3V17.9426C3 15.0837 3.25278 12.8408 3.75834 11.2138C4.26391 9.58682 4.78965 8.50069 6.16526 7.19909C7.54087 5.89749 8.49532 5.5069 10.5145 5L11.9251 7.97425C10.5145 8.50267 9.65508 8.73835 8.3296 10.0864C7.00412 11.4345 6.90635 12.7384 6.90635 13.8591H12.9114V24.9503Z" fill="#666666"/>
+</svg>

+ 17 - 0
src/components/DisclaimersWrap.vue

@@ -0,0 +1,17 @@
+<script setup>
+
+const show=defineModel('show',{type:Boolean,default:false})
+
+</script>
+
+<template>
+  <!-- 免责声明 -->
+  <t-dialog
+    v-model:visible="show"
+    title="免责声明"
+    closeBtn
+    closeOnOverlayClick
+  >
+    <div>免责声明说明文案</div>
+  </t-dialog>
+</template>

+ 29 - 0
src/components/SvgIcon.vue

@@ -0,0 +1,29 @@
+<script setup>
+import { computed } from 'vue'
+const props = defineProps({
+  // prefix: {
+  //   type: String,
+  //   default: 'icon'
+  // },
+  name: {
+    type: String,
+    required: true
+  },
+  color: {
+    type: String,
+    default: '#333'
+  },
+  size: {
+    type: String,
+    default: '1em'
+  }
+})
+
+const symbolId = computed(() => `#${props.name}`)
+</script>
+
+<template>
+  <svg aria-hidden="true" class="svg-icon" :width="props.size" :height="props.size">
+    <use :xlink:href="symbolId" :fill="props.color" />
+  </svg>
+</template>

+ 15 - 0
src/components/globalComponents.js

@@ -0,0 +1,15 @@
+import { defineAsyncComponent } from 'vue';
+
+// 自动注册src/components目录下的所有.vue文件
+export default function registerGlobalComponents(app) {
+  const components = import.meta.glob('./components/**/*.vue');
+
+  for (const path in components) {
+    const componentName = path
+      .split('/')
+      .pop()
+      .replace(/\.\w+$/, '');
+
+    app.component(componentName, defineAsyncComponent(components[path]));
+  }
+}

+ 13 - 0
src/hooks/chart/commonFun.js

@@ -0,0 +1,13 @@
+
+
+export function setExtremumDate(dataList){
+  let startDateList = dataList.map(it => it.StartDate)
+                                  .filter(Boolean)
+                                  .sort((a,b)=> new Date(a).getTime() - new Date(b).getTime())
+  //过滤、排序 拿到最新日期
+  let endDateList = dataList.map(it => it.LatestDate)
+                                .filter(Boolean)
+                                .sort((a,b)=> new Date(b).getTime() - new Date(a).getTime())
+
+  return {earliestDate:startDateList[0],latestDate:endDateList[0]}
+}

+ 245 - 0
src/hooks/chart/config.js

@@ -0,0 +1,245 @@
+
+//图模块公共配置
+
+// 图默认配置
+export const chartDefaultOpts={
+    //图表配置
+	chart: {
+		spacingTop: 30,
+		backgroundColor: "rgba(0,0,0,0)",
+	},
+	title: {
+		enabled: false
+	},
+	exporting: {
+		enabled: false,
+	},
+	boost: {
+        useGPUTranslations: true,
+    },
+	//默认颜色配置
+	colors:['#00f','#f00','#999','#000','#7cb5ec', '#90ed7d', '#f7a35c', '#8085e9', 
+	'#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1'],
+	//版权信息
+	credits: {enabled:false},
+	//数据列通用配置
+	plotOptions: {
+		series: {
+			turboThreshold: 0, //不限制数据点个数 
+			boostThreshold:0,
+			dataGrouping: {
+        enabled: false,
+      },//取消数据大自动数据合并
+			animation: {
+				duration: 1000
+			}
+		},
+		areaspline: {
+			lineWidth: 1,
+			stacking: 'normal',
+			marker: {
+					enabled: false,
+			},
+			// fillOpacity: 0.5,
+		},
+		column:{
+			pointPadding: 0.05,
+			stacking: 'normal',
+		},
+		scatter: {
+			turboThreshold: 0,
+			marker: {
+					symbol: 'circle',
+					radius: 5,
+					states: {
+							hover: {
+									enabled: true,
+							}
+					}
+			},
+			states: {
+				hover: {
+					marker: {
+						enabled: true
+					}
+				}
+			}
+		}
+	},
+	//范围选择器
+	rangeSelector: {
+		enabled: false,
+		selected: 2,
+	},
+	//悬浮提示框
+	tooltip: {
+		split: false,
+		shared: true,
+		dateTimeLabelFormats: {
+			// 时间格式化字符
+			day: '%Y/%m/%d',
+			week: "%Y/%m",
+			month: '%Y/%m',
+			year: '%Y/%m',
+		},
+		xDateFormat:'%Y/%m/%d',
+		className:'chart-tooltips-box'
+		// formatter:function(e){
+		// 	return `<p>${this.x}</p><p>aaa</p>`
+		// 	// return e
+		// }
+		// outside: true,
+		// valueDecimals: 4,
+	},
+	//图例
+	legend: {
+		enabled: true,
+		verticalAlign: 'top',
+		margin:3,
+		// layout: 'vertical'
+	},
+	//滚动条
+	scrollbar: {
+		enabled: false,
+	},
+	//导航器
+	navigator: {
+		enabled: false,
+	},
+	//范围选择器
+	rangeSelector: {
+		enabled: false,
+	},
+	xAxis: {
+		tickPosition: 'inside',
+		lineColor: '#bfbfbf',
+    	tickColor: '#bfbfbf',
+		tickLength:5,
+		type: 'datetime',
+		ordinal: false,
+		dateTimeLabelFormats: {
+			day: '%y/%m',
+			week: '%y/%m',
+			month: '%y/%m',
+			year: '%y/%m',
+		}
+		// gridLineWidth:0
+	}
+}
+
+/* 季节性图配置 */
+export const seasonOptions = {
+	//默认颜色配置
+	colors:['#4B0082','#7FFFAA','#FF4500','#808000','#EEE8AA','#849EC1','#8A4294','#578B5A','#FDA8C7','#53B3FF','#999999','#000000','#FFDF0C','#FF0000','#0033FF'],
+	yAxis: {
+		lineWidth: 1,
+		lineColor: '#bfbfbf',
+		tickColor: '#bfbfbf',
+		offset: 0,
+		opposite: false,
+		reversed: false,
+		visible: true,
+		gridLineWidth: 0,
+		tickWidth: 1,
+		tickLength:5,
+		tickPosition: 'inside',
+		endOnTick: false,
+		startOnTick: false,
+		showLastLabel: true, //显示最后刻度值
+		tickPixelInterval: 50
+	}
+}
+
+// 散点x轴
+export const scatterXAxis = {
+    tickPosition: 'inside',
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    tickLength:5,
+    ordinal: false,
+    type: 'linear',
+}
+
+// 基础y轴配置
+export const basicYAxis = {
+    tickWidth: 1,
+    tickLength: 5,
+    lineWidth: 1,
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    // offset: 0,
+    visible: true,
+    gridLineWidth: 0,
+    tickPosition: 'inside',
+    endOnTick: false,
+    startOnTick: false,
+    showLastLabel: true,
+    tickPixelInterval: 50,
+}
+
+//基础x轴配置
+export const basicXAxis={
+    tickPosition: 'inside',
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    tickLength:5,
+    type: 'datetime',
+    ordinal: false,
+    dateTimeLabelFormats: {
+        day: '%y/%m',
+        week: '%y/%m',
+        month: '%y/%m',
+        year: '%y/%m',
+    },
+    xDateFormat:'%Y-%m-%d'
+}
+
+//领先频度对应英文
+export const leadUnitEnMap={
+	'年': 'Y',
+    '季': 'Q',
+    '月': 'M',
+    '周': 'W',
+    '天': 'D',
+}
+
+//相关性图表单位英文Map
+export const relevanceUnitEnMap={
+	'年': 'Year',
+    '季': 'Season',
+    '月': 'Month',
+    '周': 'Week',
+    '天': 'Day',
+}
+
+//图表年份筛选项
+export const yearSelectOpt = [
+	{
+		name: '15年至今',
+		value: 3,
+	},
+	// {
+	// 	name: '18年至今',
+	// 	value: 7,
+	// },
+	// {
+	// 	name: '19年至今',
+	// 	value: 8,
+	// },
+	{
+		name: '20年至今',
+		value: 9,
+	},
+	{
+		name: '21年至今',
+		value: 4,
+	},
+	{
+		name: '22年至今',
+		value: 11
+	},
+]
+
+// 拥有相同配置的图表类型集合
+export const sameOptionType=[1,3,4,5,6]
+

+ 240 - 0
src/hooks/chart/highcahrts-zh_CN.js

@@ -0,0 +1,240 @@
+/**
+ * Highcharts-zh_CN ES6 版本 plugins v1.2.1 (2020-07-29)
+ *
+ * (c) 2020 Jianshu Technology Co.,LTD (https://jianshukeji.com)
+ *
+ * Author : john@jianshukeji.com, Blue Monkey
+ *
+ * License: Creative Commons Attribution (CC)
+ */
+
+export default (H) => {
+  let protocol = window.location.protocol;
+
+  if (!/^http(s)?:&/.test(protocol)) {
+    protocol = 'http:';
+  }
+
+  let defaultOptionsZhCn = {
+    lang: {
+      // Highcharts
+      contextButtonTitle: '图表导出菜单',
+      decimalPoint: '.',
+      downloadJPEG: '下载 JPEG 图片',
+      downloadPDF: '下载 PDF 文件',
+      downloadPNG: '下载 PNG 文件',
+      downloadSVG: '下载 SVG 文件',
+      downloadXLS: '下载 XLS 文件',
+      drillUpText: '◁ 返回 {series.name}',
+      exitFullscreen: '退出全屏',
+      exportData: {
+        categoryDatetimeHeader: '时间',
+        categoryHeader: '类别',
+      },
+      openInCloud: '在 Highcharts Cloud 中打开',
+      invalidDate: '无效的时间',
+      loading: '加载中...',
+      months: [
+        '一月',
+        '二月',
+        '三月',
+        '四月',
+        '五月',
+        '六月',
+        '七月',
+        '八月',
+        '九月',
+        '十月',
+        '十一月',
+        '十二月',
+      ],
+      navigation: {
+        popup: {
+          addButton: '新增',
+          arrowLine: '直线',
+          arrowRay: '射线',
+          arrowSegment: '线段',
+          background: '背景',
+          backgroundColor: '背景颜色',
+          backgroundColors: '背景颜色',
+          borderColor: '边框颜色',
+          borderRadius: '圆角',
+          borderWidth: '边框大小',
+          circle: '圆',
+          color: '颜色',
+          connector: '连接',
+          crooked3: 'Crooked 3 line',
+          crooked5: 'Crooked 5 line',
+          crosshairX: '竖直准星线',
+          crosshairY: '水平准星线',
+          editButton: '编辑',
+          elliott3: 'Elliott 3 line',
+          elliott5: 'Elliott 5 line',
+          fibonacci: '斐波纳契',
+          fill: '填充颜色',
+          flags: '标志',
+          fontSize: '字体大小',
+          format: '文本',
+          height: '高度',
+          horizontalLine: '水平线',
+          infinityLine: '无限线',
+          innerBackground: '内背景',
+          label: '文字标签',
+          labelOptions: '文字标签配置',
+          labels: '文字标签',
+          line: '线',
+          lines: '线条',
+          measure: 'Measure',
+          measureX: 'Measure X',
+          measureXY: 'Measure XY',
+          measureY: 'Measure Y',
+          name: '名字',
+          outerBackground: '外背景',
+          padding: '内间距',
+          parallelChannel: '并行通道',
+          pitchfork: '杈子',
+          ray: '射线',
+          rectangle: '矩形',
+          removeButton: '删除',
+          saveButton: '保存',
+          segment: '段落',
+          series: '数据列',
+          shapeOptions: '图形配置',
+          shapes: '图形',
+          simpleShapes: '简单图形',
+          stroke: '线条颜色',
+          strokeWidth: '线条粗细',
+          style: '样式',
+          title: '标题',
+          tunnel: '通道',
+          typeOptions: '详情',
+          verticalArrow: '竖直箭头',
+          verticalCounter: '竖直计数器',
+          verticalLabel: '竖直标签',
+          verticalLine: '竖直线',
+          volume: '成交量',
+        },
+      },
+      noData: '暂无数据',
+      numericSymbols: null,
+      printChart: '打印图表',
+      resetZoom: '重置缩放比例',
+      resetZoomTitle: '重置为原始大小',
+      shortMonths: [
+        '一月',
+        '二月',
+        '三月',
+        '四月',
+        '五月',
+        '六月',
+        '七月',
+        '八月',
+        '九月',
+        '十月',
+        '十一月',
+        '十二月',
+      ],
+      thousandsSep: ',',
+      viewData: '查看数据表格',
+      viewFullscreen: '全屏查看',
+      weekdays: [
+        '星期天',
+        '星期一',
+        '星期二',
+        '星期三',
+        '星期四',
+        '星期五',
+        '星期六',
+      ],
+      viewData: '查看数据表格',
+      // Highstock
+      rangeSelectorFrom: '开始时间',
+      rangeSelectorTo: '结束时间',
+      rangeSelectorZoom: '范围',
+
+      // Highmaps
+      zoomIn: '缩小',
+      zoomOut: '放大',
+    },
+
+    global: {
+      // 不使用 UTC时间
+      useUTC: false,
+      timezoneOffset: -8 * 60,
+      canvasToolsURL:
+        protocol + '//cdn.hcharts.cn/highcharts/modules/canvas-tools.js',
+      VMLRadialGradientURL:
+        protocol + +'//cdn.hcharts.cn/highcharts/gfx/vml-radial-gradient.png',
+    },
+
+    exporting: {
+      url: protocol + '//export.highcharts.com.cn',
+    },
+
+    credits: {
+      text: 'Highcharts.com.cn',
+      href: 'https://www.highcharts.com.cn',
+    },
+
+    /**
+     * Highstock
+     */
+
+    rangeSelector: {
+      inputDateFormat: '%Y-%m-%d',
+      buttons: [
+        {
+          type: 'month',
+          count: 1,
+          text: '月',
+        },
+        {
+          type: 'month',
+          count: 3,
+          text: '季度',
+        },
+        {
+          type: 'month',
+          count: 6,
+          text: '半年',
+        },
+        {
+          type: 'ytd',
+          text: 'YTD',
+        },
+        {
+          type: 'year',
+          count: 1,
+          text: '年',
+        },
+        {
+          type: 'all',
+          text: '所有',
+        },
+      ],
+    },
+
+    plotOptions: {
+      series: {
+        dataGrouping: {
+          dateTimeLabelFormats: {
+            /* millisecond: [
+              '%Y-%m-%d %H:%M:%S.%L',
+              '%Y-%m-%d %H:%M:%S.%L',
+              ' ~ %H:%M:%S.%L',
+            ],
+            second: ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S', ' ~ %H:%M:%S'],
+            minute: ['%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M', ' ~ %H:%M'],
+            hour: ['%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M', ' ~ %H:%M'], */
+            day: ['%Y/%m/%d', '%Y/%m/%d', ' ~ %Y/%m/%d'],
+            week: ['%Y/%m/%d', '%Y/%m/%d', ' ~ %Y/%m/%d'],
+            month: ['%Y/%m', '%Y/%m', ' ~ %Y/%m'],
+            year: ['%Y', '%Y', ' ~ %Y'],
+          },
+        },
+      },
+    },
+  };
+
+  H.setOptions(defaultOptionsZhCn);
+};

+ 2419 - 0
src/hooks/chart/render.js

@@ -0,0 +1,2419 @@
+// 图渲染逻辑模块
+
+import {onMounted,ref,nextTick,reactive} from 'vue'
+import {chartDefaultOpts,scatterXAxis,basicYAxis,basicXAxis,leadUnitEnMap,relevanceUnitEnMap} from './config'
+import Highcharts from 'highcharts/highstock';
+import HighchartsFormat from 'highcharts';
+import HighchartsMore from 'highcharts/highcharts-more';
+import HightchartsExport from 'highcharts/modules/exporting';
+import Boost from 'highcharts/modules/boost'
+import HighchartszhCN  from './highcahrts-zh_CN.js'
+import moment from 'moment'
+import _ from 'lodash';
+HighchartszhCN(Highcharts)
+HightchartsExport(Highcharts)
+HighchartsMore(Highcharts)
+Boost(Highcharts)
+
+
+/**
+ * 渲染图方法
+ * @param data 图详情数据
+ * @param renderId 图表在dom中的id
+ * @param lang 图表显示为中文/英文 默认 zh中文 en英文
+ * @param changeLangIsCheck 切换中英文时 是否要校验
+ * @param showChartTitle 是否显示图表标题 默认true
+ */
+let ChartIns=null//图表实例
+let chartData=ref(null)//图的所有数据
+let LangType=ref('zh')//当前图表显示的语言版本
+let RenderDomId=ref('')//图表渲染的domid
+let options=ref(null)//渲染图的数据
+const axisLimitState = reactive({//极值数据
+    leftIndex:-1,//左侧上下限对应下标
+    rightIndex: -1, //右侧上下限对应下标
+    rightTwoIndex: -1,//右2上下限对应下标
+
+    hasLeftAxis:false,
+    hasRightAxis:false,
+    hasRightTwoAxis:false,
+    hasXAxis:false,
+    leftMin:0,
+    leftMax:0,
+    rightMin:0,
+    rightMax:0,
+    rightTwoMin:0,
+    rightTwoMax:0,
+    xMin:0,
+    xMax:0,
+})
+//仅ETA图库内图表需要使用自定义上下限
+let useSelfLimit = false
+let isUseSelfLimit = ref(false)
+
+const screen = ref(document.body.clientWidth < 1200 ? 'phone' : 'pc');
+// webcomponent的EtaChart.ce.vue文件用到了这里的逻辑
+// 有修改了 chartRender,setLimitData 这俩方法的,需要重新编辑下webcomponent(npm run build.lib),然后替换掉report项目的对应文件eta_comp.js
+export function useChartRender(){
+    return {
+        options,
+        axisLimitState,
+        chartRender,
+        setLimitData,
+        isUseSelfLimit
+    }
+}
+
+/**备注一下 越多越乱 
+ * @params
+ * Source 1 ; chartType只在source:1用到 1曲线 2季节 3面积 4堆积柱 5散点 6组合 7柱形 10截面散点 11雷达图
+ * 2 商品价格
+ * 3 相关性
+ * 4 滚动相关性
+ * 5 商品利润
+ * 6 拟合方程
+ * 7 统计特征/标准差
+ * 8 统计特征/百分位
+ * 9 统计特征/频率
+ * 10 跨品种分析
+ */
+export function chartRender({data,renderId,lang='zh',changeLangIsCheck,showChartTitle=true,shouldUseSelfLimit=false}){
+    // 初始化掉极值数据
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+    axisLimitState.hasLeftAxis=false
+    axisLimitState.hasRightAxis=false
+    axisLimitState.hasRightTwoAxis=false
+    axisLimitState.hasXAxis=false
+
+    //使用自定义上下限时,不需要初始化极值
+    if(!isUseSelfLimit.value){
+        axisLimitState.leftMin=0
+        axisLimitState.leftMax=0
+        axisLimitState.rightMin=0
+        axisLimitState.rightMax=0
+        axisLimitState.rightTwoMin=0
+        axisLimitState.rightTwoMax=0
+        axisLimitState.xMin=0
+        axisLimitState.xMax=0
+    }
+    
+
+
+    let chartOpt={}
+    LangType.value=lang
+    RenderDomId.value=renderId
+    chartData.value=data
+   /*  useSelfLimit = ['/myETA/chartdetail','/chartETA/chartdetail'].includes(window.location.pathname) */
+   useSelfLimit = shouldUseSelfLimit
+    if([1,11].includes(data.ChartInfo.Source)){
+        const chartSetMap = {
+            1: setSplineOpt,
+            2: setSeasonOpt,
+            3: setStackOrCombinChart,
+            4: setStackOrCombinChart,
+            5: setScatterOptions,
+            6: setStackOrCombinChart,
+            7: initBarData,
+            10: setSectionScatterChart,
+            11: setRadarChart
+        };
+        chartOpt=chartSetMap[data.ChartInfo.ChartType](data)
+    }else if([2,5].includes(data.ChartInfo.Source)){//商品价格曲线
+        chartOpt=initCommodityData(data);
+    }else if([3].includes(data.ChartInfo.Source)){//相关性 滚动相关性
+        chartOpt=initRelevanceChart(data);
+    }else if([4,6,7,8].includes(data.ChartInfo.Source)){//滚动相关性 拟合方程 标准差 百分比
+        chartOpt=setSplineOpt(data);
+    }else if([9].includes(data.ChartInfo.Source)){//统计频率
+        chartOpt=setStatisticFrequency(data);
+    }else if(data.ChartInfo.Source===10) {
+
+        /* 历史数据chartInfo里上下限全是空 兼容下历史数据不崩 */
+        axisLimitState.hasLeftAxis=true
+        axisLimitState.leftMin=data.ChartInfo.LeftMin?Number(data.ChartInfo.LeftMin):Number(data.DataResp.YMinValue)
+        axisLimitState.leftMax=data.ChartInfo.LeftMax?Number(data.ChartInfo.LeftMax):Number(data.DataResp.YMaxValue)
+        
+        axisLimitState.hasXAxis=true
+        axisLimitState.xMin= data.ChartInfo.XMin?Number(data.ChartInfo.XMin):Number(data.DataResp.XMinValue)
+        axisLimitState.xMax=data.ChartInfo.XMax?Number(data.ChartInfo.XMax):Number(data.DataResp.XMaxValue),
+
+        chartOpt = setCrossVarietyChart(data)
+    }
+
+    /* 
+        eta1.4.1增加了主题色
+		仍然以defaultOpts为最底层配置 外层配置在这里统一设置了如legend chart背景色
+			x轴y轴系列等样式还是需要在具体的options中单独设置
+    */
+
+    let themeOptions = setThemeOptions();
+
+    options.value={...chartDefaultOpts,...themeOptions, ...chartOpt}
+    // 设置图标题
+    setChartTitle(showChartTitle)
+    
+    // 设置语言
+    setChartLang(changeLangIsCheck)
+    
+    //stock不支持线形图只支持时间图 某些用chart
+    let is_linear = chartOpt.series 
+    ? chartOpt.series.some(_ => _.chartType === 'linear')
+    : false ;
+
+    is_linear ?ChartIns=Highcharts.chart(RenderDomId.value,options.value) : ChartIns=Highcharts.stockChart(RenderDomId.value,options.value);
+
+    return ChartIns
+}
+
+//主题色一些外层公用配置  目前只有绘图区和legend和colors
+function setThemeOptions() {
+    if(!chartData.value.ChartInfo.ChartThemeStyle) return {}
+
+    let chartTheme = JSON.parse(chartData.value.ChartInfo.ChartThemeStyle)
+
+    return {
+        legend: {
+            ...chartDefaultOpts.legend,
+            ...chartTheme.legendOptions
+        },
+        chart: {
+            ...chartDefaultOpts.chart,
+            ...chartTheme.drawOption
+        },
+        colors: chartTheme.colorsOptions
+    }
+}
+
+ /* 处理轴的标识线结构 在指定轴位置上拼接标识线 
+    0:右轴 1:左轴 2:右2轴 x轴固定3
+    axisType表示x轴类型 处理时间轴的值 datetime/null 
+*/
+function setAxisPlotLines(axis,axisType) {
+    const { MarkersLines,ChartType } = chartData.value.ChartInfo;
+    const { EdbInfoList } = chartData.value;
+    if(!MarkersLines) return []
+
+    let markerLines = JSON.parse(MarkersLines);
+
+    let arr = markerLines.filter(_ => _.isShow&&_.axis===axis)
+    let plotLines = arr.map(_ => {
+        //是否是x时间轴
+        let isXDateAxis = axis===3&&axisType==='datetime';
+        let markerValue;
+        if(isXDateAxis) {
+            //季节图x轴额外拼个年份
+            let nowYear = ChartType===2 ? new Date(EdbInfoList[0].DataList[1].DataList
+                [0].DataTimestamp).getFullYear() : '';
+            markerValue = ChartType===2 
+                ? new Date(`${nowYear}-${_.value}`).getTime()
+                : new Date(_.value).getTime()
+        }else {
+            markerValue = Number(_.value)
+        }
+
+        return { 
+        value: markerValue,
+        dashStyle: _.dashStyle,
+        width: Number(_.lineWidth),
+        color: _.color,
+        label: {
+            text: _.text||'',
+            verticalAlign: _.textPosition,
+            style: {
+            color: _.textColor,
+            fontSize: _.textFontSize
+            }
+        }
+        }
+    })
+    return plotLines
+}
+
+/* 处理标识区拼接 axisType表示x轴类型处理时间轴的值 datetime/null */
+function setAxisPlotAreas(axis,axisType) {
+    const { MarkersAreas,ChartType } = chartData.value.ChartInfo;
+    const { EdbInfoList } = chartData.value;
+    if(!MarkersAreas) return []
+
+    let markerAreas = JSON.parse(MarkersAreas);
+
+    let arr = markerAreas.filter(_ => _.isShow&&_.axis===axis)
+    let plotBands = arr.map(_ => {
+        //是否是x时间轴
+        let isXDateAxis = axis===3&&axisType==='datetime';
+        let fromMarkerValue,toMarkerValue;
+        if(isXDateAxis) {
+            //季节图x轴额外拼个年份
+            let nowYear = ChartType===2 ? new Date(EdbInfoList[0].DataList[1].DataList
+                [0].DataTimestamp).getFullYear() : '';
+            fromMarkerValue = ChartType===2 
+                ? new Date(`${nowYear}-${_.fromValue}`).getTime()
+                : new Date(_.fromValue).getTime()
+
+            toMarkerValue = ChartType===2 
+                ? new Date(`${nowYear}-${_.toValue}`).getTime()
+                : new Date(_.toValue).getTime()
+        }else {
+            fromMarkerValue = Number(_.fromValue);
+            toMarkerValue = Number(_.toValue);
+        }
+
+        //默认label有些偏移 重新归正下
+        let positionMapValue = {
+            'top': 12,
+            'middle': 0,
+            'bottom': -10
+        }
+
+        return { 
+            from: fromMarkerValue,
+            to: toMarkerValue,
+            color: _.color,
+            label: {
+                text: _.text||'',
+                verticalAlign: _.textPosition,
+                y: positionMapValue[_.textPosition],
+                style: {
+                    color: _.textColor,
+                    fontSize: _.textFontSize
+                }
+            }
+        }
+    })
+
+    return plotBands
+}
+
+
+/* 预测配置 分区 */
+function getPredictParams ({LatestDate,PredictChartColor}) {
+    return {
+    zoneAxis: 'x',
+    zones: [{
+        value: new Date(LatestDate).getTime()+1
+    }, {
+        dashStyle: 'ShortDot',
+        color: PredictChartColor
+    }]
+    }
+}
+
+/* 季节图预测数据 年份=分割点年份做分割 年份>分割点年份全为预测 */
+function getSeasonPredictParams (timestamp){
+    return timestamp
+    ? {
+        zoneAxis: 'x',
+        zones: [{
+            value: new Date(timestamp).getTime()+1
+        }, {
+            dashStyle: 'ShortDot',
+        }]
+        }
+    : {}
+}
+
+// 查询范围为1年内 x轴显示为月/日 否则默认年/月
+function xTimeDiffer(minTime,maxTime,dateType){
+    //年限差
+    let year_differ=moment(maxTime).diff(moment(minTime),'years',true)
+    // console.log('年限差',year_differ)
+    if ([5, 6].includes(dateType) && year_differ <= 1) {
+        return true
+    } else {
+        return false
+    }
+}
+
+/* 拼接动态的指标名称小标签 */
+function concatDynamicTag(item,lang){
+    const { IsAxis,IsOrder,EdbInfoType,LeadValue,LeadUnit }  = item;
+    // IsAxis左轴1 右轴0 2右2轴 
+    //IsOrder正序false 逆序true 
+      //IsOrder正序false 逆序true 
+    //IsOrder正序false 逆序true 
+    //EdbInfoType是否是领先指标
+    const axisLabelMap =lang=='zh'? {
+        0: '右轴',
+        2: '右2轴'
+    }:{
+        0: 'RHS',
+        2: '2-RHS'
+    }
+    const orderLabelMap =lang=='zh'? {
+        1: '逆序'
+    }:{
+        1: 'REV'
+    }
+    const edbInfoMap =lang=='zh'? {
+        0: '领先'
+    }:{
+        0: 'Lead'
+    }
+
+    //英文领先单位转换
+    const leadUnit = lang==='zh' ? LeadUnit : leadUnitEnMap[LeadUnit];
+
+    let axis_tag = axisLabelMap[IsAxis] || '';
+      //逆序拼接
+    let order_tag = orderLabelMap[Number(IsOrder)] ? `${axis_tag ? ',': ''}${orderLabelMap[Number(IsOrder)]}` : ''
+      //领先拼接
+    let edb_tag = edbInfoMap[EdbInfoType] ? `${(axis_tag||order_tag) ? ',' : '' }${edbInfoMap[EdbInfoType]}${LeadValue}${leadUnit}` : '';
+
+    let dynamic_tag = (axis_tag || order_tag || edb_tag) ? `(${axis_tag}${order_tag}${edb_tag})` : '';
+
+    return dynamic_tag
+}
+/* 拼接数据列动态name */
+function setDyncmicSerieName (item,dynamic_arr,lang='zh') {
+    let temName =''
+    /* if(lang=='zh'){
+        temName= dynamic_arr.length > 1
+            ? `${item.EdbName}(${item.SourceName})${concatDynamicTag(item,'zh')}`
+            : `${item.EdbName}${concatDynamicTag(item,'zh')}`
+    }else{
+        temName=item.EdbNameEn?`${item.EdbNameEn}${concatDynamicTag(item,'en')}`:''
+    } */
+    const temNameEn = item.EdbNameEn?`${item.EdbNameEn}${concatDynamicTag(item,'en')}`:''
+    const temNameZh = dynamic_arr.length > 1
+    ? `${item.EdbAliasName||item.EdbName}(${item.SourceName})${concatDynamicTag(item,'zh')}`
+    : `${item.EdbAliasName||item.EdbName}${concatDynamicTag(item,'zh')}`
+    temName = lang=='zh'?temNameZh:temNameEn?temNameEn:temNameZh
+
+    if(temName.length>20){
+        let temArr=[]
+        for(let i=0;i<temName.length/20;i++){
+            temArr.push(temName.slice(i*20,i*20+20))
+        }
+        temName=temArr.join('<br>')
+    }
+
+    return temName
+}
+
+/* 指标顺序调整  IsAxis: 0右轴 1左轴 2右2*/
+function changeEdbOrder (data){
+    // 左轴指标
+    let left_edbs = data.filter(_ => _.IsAxis===1);
+    //右轴指标
+    let right_edbs = data.filter(_ => !_.IsAxis);
+    // 右2轴指标
+    let right_two_edbs = data.filter(_ => _.IsAxis === 2);
+    // 按 左 右 右2顺序排列
+    return [left_edbs,right_edbs,right_two_edbs].flat(Infinity);
+}
+
+//检查图表英文配置是否完整
+function checkChartEnData(){
+    let result = true
+    //图表名称:this.chartInfo.ChartNameEn
+    if(!chartData.value.ChartInfo.ChartNameEn){
+      result = false
+    }
+    //指标名称:this.dataList[].EdbNameEn
+    //指标单位:this.dataList[].UnitEn
+    chartData.value.EdbInfoList.forEach(item=>{
+      if(!item.EdbNameEn){
+        result = false
+      }
+      if(chartData.value.ChartInfo.ChartType!==10&&item.Unit&&!item.UnitEn){
+        result = false
+      }
+    })
+    return result   
+}
+
+// 设置图表显示的语言
+function setChartLang(changeLangIsCheck){
+    if(changeLangIsCheck&&!checkChartEnData()) return
+    const {ChartType,Source} = chartData.value.ChartInfo
+    if(Source==1){
+        // 散点图
+        if(ChartType == 5){
+            options.value.yAxis.title.text = LangType.value == 'zh' ? options.value.yAxis.title.textZh : options.value.yAxis.title.textEn;
+            // options.value.yAxis.title.style = LangType.value == 'zh' ? {} : options.value.yAxis.title.styleEn;
+            options.value.xAxis.title.text = LangType.value == 'zh' ? options.value.xAxis.title.textZh : options.value.xAxis.title.textEn
+            // options.value.xAxis.title.style = LangType.value == 'zh' ? {} : options.value.xAxis.title.styleEn;
+            options.value.series.forEach(item => {
+                item.name = LangType.value == 'zh' ? item.nameZh : item.nameEn;
+            });
+            options.value.tooltip.formatter = LangType.value == 'zh' ? options.value.tooltip.formatterZh : options.value.tooltip.formatterEn;
+        }else{
+            // 单位
+            options.value.yAxis.forEach(item => {
+                item.title.text = LangType.value == 'zh' ? item.title.textZh : item.title.textEn;
+                // item.title.style = LangType.value == 'zh' ? {} : (item.title.styleEn || {})
+            });
+            // 图例  名称
+            if(ChartType != 2){
+                // 季节图 不更改图例名称
+                options.value.series.forEach(item => {
+                    item.name = LangType.value == 'zh' 
+                        ? item.nameZh 
+                        : (item.nameEn!='无英文名称'?item.nameEn:`<span style="color:#999">${item.nameEn}</span>`)
+                });
+            }
+            //截面散点 x轴标题
+            if(ChartType === 10){
+                options.value.xAxis.title.text = LangType.value == 'zh' ? options.value.xAxis.title.textZh : options.value.xAxis.title.textEn;
+                // options.value.xAxis.title.style = LangType.value == 'zh' ? {} : options.value.xAxis.title.styleEn;
+                options.value.tooltip.formatter = LangType.value == 'zh' ? options.value.tooltip.formatterCh : options.value.tooltip.formatterEn;
+                options.value.series.forEach(item => {
+                    if(!item.linkedTo) {
+                        item.data.forEach(point => {
+                            point.dataLabels.format = LangType.value == 'zh' ? point.dataLabels.formatZh : (point.dataLabels.formatEn||'无英文标签');
+                            point.dataLabels.color = (LangType.value==='en' && !point.dataLabels.formatEn) ? '#999' : '#333'
+                        })
+                    }
+                });
+            } 
+
+            //柱形图额外设置x轴中英文
+            if([7,11].includes(ChartType)){
+                //x轴
+                options.value.xAxis.categories = chartData.value.XEdbIdValue.map(_ => LangType.value == 'zh' 
+                ? chartData.value.EdbInfoList.find(edb => edb.EdbInfoId===_).EdbAliasName || chartData.value.EdbInfoList.find(edb => edb.EdbInfoId===_).EdbName
+                : chartData.value.EdbInfoList.find(edb => edb.EdbInfoId===_).EdbNameEn)
+            }
+        }
+    }
+    if([2,3,4].includes(Source)){
+        options.value.yAxis.forEach(item => {
+            item.title.text =  LangType.value == 'zh' ? item.title.textZh: item.title.textEn
+        });
+        //图例
+        options.value.series.forEach(item => {
+            item.name = LangType.value == 'en' ?item.nameEn : item.nameZh 
+        });
+        //tooltip
+        options.value.tooltip.formatter = LangType.value == 'en'?options.value.tooltip.formatterEn:options.value.tooltip.formatterZh
+        //x轴
+        if(Source==2){
+            options.value.xAxis.categories = commodityXData.value.map(_ => {
+                LangType.value == 'en'?_.NameEn:_.Name
+            });
+        }
+        if([3].includes(Source)){
+            options.value.xAxis.title.text=LangType.value == 'en'?options.value.xAxis.title.textEn:options.value.xAxis.title.textZh
+        }
+    }
+}
+
+// 设置图标题
+function setChartTitle(showChartTitle){
+    if(showChartTitle){
+        const ChartInfo=chartData.value.ChartInfo
+        options.value.title.textZh=ChartInfo.ChartName
+        options.value.title.textEn=ChartInfo.ChartNameEn
+        options.value.title.text=LangType.value == 'zh' ?options.value.title.textZh:options.value.title.textEn||options.value.title.textZh
+    }else{
+        options.value.title.text=''
+    }
+}
+
+//统计频率图
+function setStatisticFrequency(e){
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+     /* 主题样式*/
+    const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+    const { DataList,LeftMaxValue,LeftMinValue,RightMaxValue,RightMinValue } = e.DataResp;
+
+    const xAxis = {
+        ...scatterXAxis,
+        tickWidth: 1,
+        labels: {
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        }
+    }
+
+    //y和系列
+    let yAxis = [],series = [];
+    DataList.forEach((item,index) => {
+      let y_item = {
+        ...basicYAxis,
+        title: {
+            text: item.Unit,
+            textCh:item.Unit,// 中文
+            textEn:item.UnitEn||item.Unit,
+            align: 'high',
+            rotation: 0,
+            y: -15,
+            reserveSpace: false,
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        opposite: item.IsAxis===1?false:true,
+        min: index===0? Number(LeftMinValue):Number(RightMinValue),
+        max: index===0? Number(LeftMaxValue):Number(RightMaxValue),
+        tickWidth: 1,
+      }
+
+      let series_item = {
+        data: item.Value.map(_ =>[_.X,_.Y]),
+        dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+        type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+        yAxis: index,
+        name: item.Name,
+        nameZh: item.Name,
+        nameEn: item.NameEn||item.Name,
+        color: item.Color,
+        lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth)||3,
+        chartType: 'linear',
+        zIndex:1
+      }
+
+      series.push(series_item);
+      yAxis.push(y_item)
+    })
+
+    let tooltip = {
+        formatter: function() {
+          let xList = DataList[0].Value.map(_ =>_.X);
+          let step = xList[1]-xList[0];
+          let data_interval = `[${this.x},${this.x+step}]`;
+
+          let str=`<b>${ data_interval }</b>`;
+          this.points.forEach(item => {
+            str += `<br><span style="color:${item.color}">\u25CF</span>${item.series.name}: ${item.y}%<br>`
+          })
+          return str
+        },
+        shared: true
+    }
+
+    return {
+        title: {
+            text:''
+          },
+        tooltip,
+        series,
+        yAxis,
+        xAxis
+    }
+}
+
+//曲线图
+function setSplineOpt(e){
+    //其他Source也会用到曲线图,这里需要兼容
+    const isETASource = e.ChartInfo.Source===1
+    const data=[4,6,7,8].includes(e.ChartInfo.Source)?[e.DataResp]:e.EdbInfoList
+    let series=[]
+    let yAxis=[]
+    let xAxis = {}
+
+    let temYLeftArr=[]
+    let temYRightArr=[]
+    let temYRightTwoArr = []
+    let temYLeftIndex=data.findIndex((item) => item.IsAxis===1)
+    let temYRightIndex=data.findIndex((item) => !item.IsAxis)
+    let temYRightTwoIndex = data.findIndex((item) => item.IsAxis===2)
+    axisLimitState.leftIndex=temYLeftIndex
+    axisLimitState.rightIndex=temYRightIndex
+    axisLimitState.rightTwoIndex=temYRightTwoIndex
+
+     /* 主题样式*/
+    const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+
+    let minAndMaxTimeTemArr=[]//存放所有指标的最大最小时间
+
+    //有右二轴时排个序 按照左 右 右2的顺序
+    let newData = data.some(_ =>_.IsAxis===2) ? changeEdbOrder(data) : data;
+
+    newData.forEach((item,index)=>{
+
+         //轴位置值相同的下标
+        let sameSideIndex = newData.findIndex(i => i.IsAxis === item.IsAxis);
+
+        let dynamic_title = item.EdbName;
+        let dynamic_arr = newData.filter(
+          (item) => dynamic_title === item.EdbName
+        );
+        //处理数据列name
+        let temName= setDyncmicSerieName(item,dynamic_arr,'zh')  
+        let temNameEN=setDyncmicSerieName(item,dynamic_arr,'en')  
+        //预测指标配置
+        let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item) : {};
+
+        let seriesItemObj={
+            data:[],
+            dataGrouping:{
+                enabled:false
+            },
+            type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+            dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+            yAxis:index,
+            name:temName,
+            nameZh:temName,
+            nameEn:temNameEN,
+            color: item.ChartColor,
+            lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth)||1,
+            visible:true,
+            LatestDate:item.LatestDate,
+            LatestValue:item.LatestValue,
+            ...predict_params
+        }
+        item.DataList = item.DataList || [];
+        for (let i of item.DataList) {
+          seriesItemObj.data.push([i.DataTimestamp, i.Value]);
+        }
+        series.push(seriesItemObj)
+        
+
+        // 设置y轴
+        if(item.IsAxis){
+            temYLeftArr.push(item)
+        }else{
+            temYRightArr.push(item)
+        }
+
+        //获取上下限
+        console.log('useSelfLimit',useSelfLimit)
+        let minLimit = 0,maxLimit = 0
+        if(!useSelfLimit||!isETASource){
+            minLimit = item.MinData
+            maxLimit = item.MaxData
+        }
+        if(useSelfLimit&&isETASource){
+            const limitMap = {
+                0:['rightMin','rightMax'],
+                1:['leftMin','leftMax'],
+                2:['rightTwoMin','rightTwoMax']
+            }
+            if(limitMap[item.IsAxis]){
+                minLimit = axisLimitState[`${limitMap[item.IsAxis][0]}`]||0
+                maxLimit = axisLimitState[`${limitMap[item.IsAxis][1]}`]||0
+            }
+        }
+        const textZh = item.ConvertUnit||item.Unit
+        const textEn = item.ConvertEnUnit||item.UnitEn||item.ConvertUnit||item.Unit
+        let yItem={
+            ...basicYAxis,
+            IsAxis:item.IsAxis,
+            labels: {
+                formatter: function (ctx) {
+                    return sameSideIndex !== index ? '' : ctx.value;
+                },
+                align: 'center',
+                x: [0,2].includes(item.IsAxis) ? 5 : -5,
+                style:{
+                    ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+            },
+            tickWidth: sameSideIndex !== index ? 0 : 1,
+            title: {
+                text:  sameSideIndex !== index ? '' : `${textZh}`,
+                textZh:textZh,//中文单位
+                textEn:textZh?textEn:'',//英文单位,但如果无中文单位则不显示
+                align: 'high',
+                rotation: 0,
+                y: -15,
+                x: (item.IsAxis===0 && temYRightTwoIndex>-1) ? -newData[temYRightTwoIndex].Unit.length*12 : 0,
+                textAlign: item.IsAxis===1 ? 'left' : 'right',
+                reserveSpace: false,
+                style:{
+                    ...chartTheme&&chartTheme.yAxisOptions.style
+                }
+            },
+            opposite: [0,2].includes(item.IsAxis),
+            reversed: item.IsOrder,
+            min: Number(minLimit),
+            max: Number(maxLimit),
+            visible: sameSideIndex === index,
+            chartEdbInfo:item,//指标数据用于在保存时读取指标数据
+            plotBands: setAxisPlotAreas(item.IsAxis),
+            plotLines: setAxisPlotLines(item.IsAxis)
+        }
+        yAxis.push(yItem)
+        if(item.DataList.length>0){
+            minAndMaxTimeTemArr.push(item.DataList[0].DataTimestamp)
+            minAndMaxTimeTemArr.push(item.DataList[item.DataList.length-1].DataTimestamp)
+        }
+        
+    })
+    
+    
+    // 设置x轴
+    // 找出所有指标的最大和最小时间 分成6段
+    let minTime=Math.min.apply(null,minAndMaxTimeTemArr)
+    let maxTime=Math.max.apply(null,minAndMaxTimeTemArr)
+
+
+    const isLessThanOneYear = xTimeDiffer(minTime,maxTime,e.ChartInfo.DateType)
+
+    xAxis={
+        ...basicXAxis,
+        labels: {
+            formatter: function (ctx) {
+                return isLessThanOneYear
+                ? HighchartsFormat.dateFormat('%m/%d', ctx.value)
+                : HighchartsFormat.dateFormat('%y/%m', ctx.value);
+            },
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        tickInterval:screen.value === 'phone'?((maxTime-minTime)/6)/(24*3600*1000)>30?(maxTime-minTime)/6:24*3600*1000*30:undefined,
+        plotBands: setAxisPlotAreas(3,'datetime'),
+        plotLines: setAxisPlotLines(3,'datetime')
+    }
+    
+
+    yAxis.forEach(item=>{
+        if(item.IsAxis===1){//左轴
+            axisLimitState.hasLeftAxis=true
+            if(!useSelfLimit||!isETASource){
+                axisLimitState.leftMin=data[temYLeftIndex].MinData
+                axisLimitState.leftMax=data[temYLeftIndex].MaxData
+
+                item.min=data[temYLeftIndex].MinData
+                item.max=data[temYLeftIndex].MaxData
+            }
+        }else if (item.IsAxis===2){ // 右2轴
+            axisLimitState.hasRightTwoAxis=true
+            if(!useSelfLimit||!isETASource){
+                axisLimitState.rightTwoMin=data[temYRightTwoIndex].MinData
+                axisLimitState.rightTwoMax=data[temYRightTwoIndex].MaxData
+
+                item.min=data[temYRightTwoIndex].MinData
+                item.max=data[temYRightTwoIndex].MaxData
+            }
+        }else{
+            axisLimitState.hasRightAxis=true
+            if(!useSelfLimit||!isETASource){
+                axisLimitState.rightMin=data[temYRightIndex].MinData
+                axisLimitState.rightMax=data[temYRightIndex].MaxData
+
+                item.min=data[temYRightIndex].MinData
+                item.max=data[temYRightIndex].MaxData
+            }
+        }
+    })
+    return {
+        series,
+        xAxis:[xAxis],
+        yAxis,
+        rangeSelector:{ enabled: false}
+    }
+}
+
+
+//季节图
+function setSeasonOpt(e){
+    axisLimitState.leftIndex=0
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+     /* 主题样式*/
+    const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+    let chartData={}
+    const data=e.EdbInfoList[0]
+    const calendarType=e.ChartInfo.Calendar||'公历'
+
+    const colorsArr=chartTheme&&chartTheme.colorsOptions.reverse();
+    let series=[],yAxis=[]
+    //农历默认选中一年数据并隐藏按钮  公历显示全部数据
+    // let rangeSelector={}
+    // 农历数据需要去除第一项  农历和公历处理逻辑一样
+    const chartDataHandle=calendarType === '农历'?
+                        data.DataList.filter((item, index) => index > 0):
+                        data.DataList
+    // if(calendarType==='公历'){
+        chartDataHandle.forEach((item,index)=>{
+             //预测指标配置
+            let predict_params =  data.EdbInfoCategoryType === 1 ? getSeasonPredictParams(item.CuttingDataTimestamp) : {};
+
+            let seriesItem={
+                data:[],
+                dataGrouping:{
+                    enabled:false
+                },
+                type: (chartTheme&&chartTheme.lineOptions.lineType) || data.ChartStyle,
+                dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+                yAxis:0,
+                name:item.ChartLegend,
+                lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+                color:colorsArr.slice(-chartDataHandle.length)[index],                
+                visible:true,
+                ...predict_params
+            }
+            item.DataList=item.DataList||[]
+            for(let i of item.DataList){
+                seriesItem.data.push([i.DataTimestamp, i.Value])
+            }
+            series.push(seriesItem)
+        })
+    
+    //获取上下限
+    let minLimit = 0,maxLimit = 0
+    //非ETA图库不使用自定义上下限
+    if(!useSelfLimit){
+        minLimit = data.MinData
+        maxLimit = data.MaxData
+    }else{
+        minLimit = axisLimitState.leftMin||0
+        maxLimit = axisLimitState.leftMax||0
+    }
+    const textZh = data.ConvertUnit||data.Unit
+    const textEn = data.ConvertEnUnit||data.UnitEn||data.ConvertUnit||data.Unit
+    yAxis=[{
+        IsAxis:data.IsAxis,
+        labels: {
+            align: 'center',
+            y:5,
+            style: {
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            }
+        },
+        title: {
+            text:  `${textZh}`,
+            textZh:textZh, // 中文
+            // 中文不存在,无论英文有无都显示空
+            textEn:textZh?textEn||'英文单位':'', // 英文
+            align: 'high',
+            rotation: 0,
+            y: -5,
+            x: 0,
+            textAlign: 'left',
+            reserveSpace: false,
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        max: Number(maxLimit),
+        min: Number(minLimit),
+        plotBands: setAxisPlotAreas(1),
+        plotLines: setAxisPlotLines(1),
+        lineWidth: 1,
+        lineColor: '#bfbfbf',
+        tickColor: '#bfbfbf',
+        offset: 0,
+        opposite: false,
+        reversed: false,
+        visible: true,
+        gridLineWidth: 0,
+        tickWidth: 1,
+        tickLength:5,
+        tickPosition: 'inside',
+        endOnTick: false,
+        startOnTick: false,
+        showLastLabel: true, //显示最后刻度值
+        tickPixelInterval: 50,
+        // chartEdbInfo:item//指标数据
+    }]
+
+    chartData.series=series
+    chartData.yAxis=yAxis
+    // chartData.rangeSelector=rangeSelector
+    // 设置坐标轴极值
+    axisLimitState.hasLeftAxis=true
+    if(!useSelfLimit){
+        axisLimitState.leftMin=Number(data.MinData)
+        axisLimitState.leftMax=Number(data.MaxData)
+    }
+    
+
+    // 季节图x轴显示月/日
+    let xAxis={
+        tickPosition: 'inside',
+		lineColor: '#bfbfbf',
+    	tickColor: '#bfbfbf',
+		tickLength:5,
+		type: 'datetime',
+		ordinal: false,
+		dateTimeLabelFormats: {
+			day: '%y/%m',
+			week: '%y/%m',
+			month: '%y/%m',
+			year: '%y/%m',
+		},
+        labels: {
+            formatter: (ctx)=> {
+                return HighchartsFormat.dateFormat('%m/%d', ctx.value)
+            },
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        tickInterval:screen.value === 'phone'?24*3600*1000*60:undefined,//季节图
+        plotBands: setAxisPlotAreas(3,'datetime'),
+        plotLines: setAxisPlotLines(3,'datetime')
+    }
+    
+
+    chartData.xAxis=[xAxis]
+
+    // 季节图提示框显示 月/日
+    chartData.tooltip={
+        split: false,
+        shared: true,
+        dateTimeLabelFormats: {
+          // 时间格式化字符
+          day: '%m/%d',
+          week: '%m/%d',
+          month: '%m/%d',
+          year: '%m/%d',
+        },
+        xDateFormat: '%m/%d',
+    }
+
+    return {
+        ...chartData,
+        // title: {
+		//     enabled: true,
+        //     text:e.ChartInfo.ChartName
+        // },
+        // legend:{
+        //     enabled:true,
+        //     verticalAlign: 'top',
+        //     y:-10,
+        //     x:(10 * data.Unit.length)/2
+        // }
+    }
+}
+
+
+//堆叠图/组合图设置
+//本来和曲线图逻辑基本一致兼容下即可 为了以后便于维护和阅读还是拆开写吧
+function setStackOrCombinChart(e){
+    const data=e.EdbInfoList
+    //图表类型
+    const chartTypeMap = {
+        3: 'areaspline',
+        4: 'column',
+        6: ''
+    };
+    let chartStyle = chartTypeMap[e.ChartInfo.ChartType];
+
+    /* 主题样式*/
+    const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+    let series=[]
+    let yAxis=[]
+    let xAxis = {}
+
+    let temYLeftArr=[]
+    let temYRightArr=[]
+    let temYRightTwoArr = []
+    let temYLeftIndex,temYRightIndex,temYRightTwoIndex;
+
+    let minAndMaxTimeTemArr=[]//存放所有指标的最大最小时间
+
+    //有右二轴时排个序 按照左 右 右2的顺序
+    let newData = data.some(_ =>_.IsAxis===2) ? changeEdbOrder(data) : data;
+
+
+    newData.forEach((item,index)=>{
+
+        //轴位置值相同的下标
+        let sameSideIndex = newData.findIndex(i => i.IsAxis === item.IsAxis);
+
+        //堆叠图的yAxis必须一致 数据列所对应的y轴
+        let serie_yIndex = index;
+        if([3,4].includes(e.ChartInfo.ChartType)) {
+            // 类型为堆叠图时公用第一个指标y轴 
+            serie_yIndex =  0;
+        } else if(e.ChartInfo.ChartType ===6 && ['areaspline','column'].includes(item.ChartStyle)) {
+            // 组合图找第一个堆叠柱状或面积的作为公用
+            serie_yIndex = newData.findIndex(i => i.ChartStyle === item.ChartStyle);
+        }
+        //数据对应的y轴是公用轴则配置也共享
+        item.IsAxis = serie_yIndex === index ? item.IsAxis : newData[serie_yIndex].IsAxis;
+        item.IsOrder = serie_yIndex === index ? item.IsOrder : newData[serie_yIndex].IsOrder;
+
+        temYLeftIndex = [3,4].includes(e.ChartInfo.ChartType) 
+            ? (newData[serie_yIndex].IsAxis ? serie_yIndex : -1)
+            : data.findIndex((item) => item.IsAxis===1);
+        temYRightIndex = [3,4].includes(e.ChartInfo.ChartType) 
+            ? (newData[serie_yIndex].IsAxis ? -1 : serie_yIndex)
+            : data.findIndex((item) => !item.IsAxis);
+        temYRightTwoIndex = [3,4].includes(e.ChartInfo.ChartType) 
+            ? -1
+            : data.findIndex((item) => item.IsAxis===2);
+        
+        axisLimitState.leftIndex=temYLeftIndex
+        axisLimitState.rightIndex=temYRightIndex
+        axisLimitState.rightTwoIndex=temYRightTwoIndex
+
+        let dynamic_title = item.EdbName;
+        let dynamic_arr = newData.filter(
+          (item) => dynamic_title === item.EdbName
+        );
+        //处理数据列name
+        let temName= setDyncmicSerieName(item,dynamic_arr,'zh')
+        let temNameEN=setDyncmicSerieName(item,dynamic_arr,'en')  
+
+        //预测指标配置
+        let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item) : {};
+
+        let seriesItemObj={
+            data:[],
+            dataGrouping:{
+                enabled:false
+            },
+            type: chartStyle || item.ChartStyle,
+            yAxis:serie_yIndex,
+            name:temName,
+            nameZh:temName,
+            nameEn:temNameEN,
+            color: item.ChartColor,
+            lineWidth:  Number(item.ChartWidth),
+            fillColor: (e.ChartInfo.ChartType === 3 || (e.ChartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
+            visible:true,
+            LatestDate:item.LatestDate,
+            LatestValue:item.LatestValue,
+            ...predict_params
+        }
+        item.DataList = item.DataList || [];
+        for (let i of item.DataList) {
+          seriesItemObj.data.push([i.DataTimestamp, i.Value]);
+        }
+        series.push(seriesItemObj)
+        
+        //获取上下限
+        let minLimit = 0,maxLimit = 0
+        //非ETA图库不使用自定义上下限
+        if(!useSelfLimit){
+            minLimit = newData[sameSideIndex].MinData
+            maxLimit = newData[sameSideIndex].MaxData
+        }else{
+            const limitMap = {
+                0:['rightMin','rightMax'],
+                1:['leftMin','leftMax'],
+                2:['rightTwoMin','rightTwoMax']
+            }
+            if(limitMap[item.IsAxis]){
+                minLimit = axisLimitState[`${limitMap[item.IsAxis][0]}`]||0
+                maxLimit = axisLimitState[`${limitMap[item.IsAxis][1]}`]||0
+            }
+        }
+
+        // 设置y轴
+        if(item.IsAxis){
+            temYLeftArr.push(item)
+        }else{
+            temYRightArr.push(item)
+        }
+
+        const textZh = item.ConvertUnit||item.Unit
+        const textEn = item.ConvertEnUnit||item.UnitEn||item.ConvertUnit||item.Unit
+        let yItem={
+            ...basicYAxis,
+            IsAxis:item.IsAxis,
+            labels: {
+                formatter: function (ctx) {
+                    return sameSideIndex !== index ? '' : ctx.value;
+                },
+                align: 'center',
+                x: [0,2].includes(item.IsAxis) ? 5 : -5,
+                style:{
+                    ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+            },
+            title: {
+                // text:  sameSideIndex !== index ? '' : `${item.Unit}`,
+                text: textZh,
+                textZh:textZh, // 中文
+                // 中文不存在,无论英文有无都显示空
+                textEn:textZh?textEn||'英文单位':'', // 英文
+                align: 'high',
+                rotation: 0,
+                y: -15,
+                x: (item.IsAxis===0 && temYRightTwoIndex>-1) ? -newData[temYRightTwoIndex].Unit.length*12 : 0,
+                textAlign: item.IsAxis===1 ? 'left' : 'right',
+                reserveSpace: false,
+                style:{
+                    ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+            },
+            opposite: [0,2].includes(item.IsAxis),
+            reversed: item.IsOrder,
+            min: Number(minLimit),
+            max: Number(maxLimit),
+            tickWidth: sameSideIndex !== index ? 0 : 1,
+            visible: serie_yIndex === index && sameSideIndex ===index,
+            plotBands: setAxisPlotAreas(item.IsAxis),
+            plotLines: setAxisPlotLines(item.IsAxis),
+            chartEdbInfo:item//指标数据用于在保存时读取指标数据
+        }
+        yAxis.push(yItem)
+        
+        if(item.DataList.length>0){
+            minAndMaxTimeTemArr.push(item.DataList[0].DataTimestamp)
+            minAndMaxTimeTemArr.push(item.DataList[item.DataList.length-1].DataTimestamp)
+        }
+        
+    })
+    
+    
+    // 设置x轴
+    // 找出所有指标的最大和最小时间 分成6段
+    let minTime=Math.min.apply(null,minAndMaxTimeTemArr)
+    let maxTime=Math.max.apply(null,minAndMaxTimeTemArr)
+
+    const isLessThanOneYear = xTimeDiffer(minTime,maxTime,e.ChartInfo.DateType)
+    xAxis={
+        ...basicXAxis,
+        labels: {
+            formatter: function (ctx) {
+                return isLessThanOneYear
+                ? HighchartsFormat.dateFormat('%m/%d', ctx.value)
+                : HighchartsFormat.dateFormat('%y/%m', ctx.value);
+            },
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        tickInterval:screen.value === 'phone'?((maxTime-minTime)/6)/(24*3600*1000)>30?(maxTime-minTime)/6:24*3600*1000*30:undefined,
+        plotBands: setAxisPlotAreas(3,'datetime'),
+        plotLines: setAxisPlotLines(3,'datetime')
+    }
+    
+    yAxis.forEach(item=>{
+        if(item.IsAxis === 1){//左轴
+            axisLimitState.hasLeftAxis=true
+            if(!useSelfLimit){
+                axisLimitState.leftMin=data[temYLeftIndex].MinData
+                axisLimitState.leftMax=data[temYLeftIndex].MaxData
+
+                item.min=data[temYLeftIndex].MinData
+                item.max=data[temYLeftIndex].MaxData
+            }
+        }else if (item.IsAxis===2){ // 右2轴
+            axisLimitState.hasRightTwoAxis=true
+            if(!useSelfLimit){
+                axisLimitState.rightTwoMin=data[temYRightTwoIndex].MinData
+                axisLimitState.rightTwoMax=data[temYRightTwoIndex].MaxData
+
+                item.min=data[temYRightTwoIndex].MinData
+                item.max=data[temYRightTwoIndex].MaxData
+            }
+            
+        }else{
+            axisLimitState.hasRightAxis=true
+            if(!useSelfLimit){
+                axisLimitState.rightMin=data[temYRightIndex].MinData
+                axisLimitState.rightMax=data[temYRightIndex].MaxData
+
+                item.min=data[temYRightIndex].MinData
+                item.max=data[temYRightIndex].MaxData
+            }
+            
+        }
+    })
+    
+   
+
+    return {
+        series,
+        xAxis:xAxis,
+        yAxis,
+        rangeSelector:{ enabled: false}
+    }
+}
+
+
+/* 散点图 第一个指标值为x轴 第二个指标为y轴*/
+function setScatterOptions(data){
+    axisLimitState.leftIndex=1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+    const dataList=data.EdbInfoList
+    const { ChartInfo } = data;
+
+     /* 主题样式*/
+    const chartTheme = ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    //上下限设置的是y轴,也就是第二个指标的值,改回来
+    axisLimitState.hasLeftAxis=true
+    /* axisLimitState.leftMin=Number(dataList[1].MinData)
+    axisLimitState.leftMax=Number(dataList[1].MaxData)
+
+    axisLimitData.leftMin=Number(dataList[1].MinData)
+    axisLimitData.leftMax=Number(dataList[1].MaxData) */
+
+    // 取2个指标中日期相同的数据
+    const real_data = [];
+    let tmpData_date = {};//用来取点对应的日期
+    let data1 =  _.cloneDeep(dataList)[0].DataList || [];
+    let data2 =  _.cloneDeep(dataList)[1].DataList || [];
+    data1.forEach((_item) => {
+        data2.forEach((_item2) => {
+            if(_item.DataTimestamp === _item2.DataTimestamp) {
+                //日期
+                let itemIndex =_item.Value + "_" +_item2.Value
+                if(tmpData_date[itemIndex]) {
+                    tmpData_date[itemIndex].push( moment(_item.DataTimestamp).format('YYYY/MM/DD'))
+                } else {
+                    tmpData_date[itemIndex] = [moment(_item.DataTimestamp).format('YYYY/MM/DD')]
+                }
+            
+                //值
+                real_data.push({
+                    x: _item.Value,
+                    y: _item2.Value
+                })
+            }
+        })
+    })
+    real_data.sort((x,y) => x-y);
+
+    //悬浮窗 拼接日期 原始指标名称
+    let tooltip = {
+        formatter: function() {
+            return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
+            ${dataList[0].EdbName}: <span style="font-weight: 600">	${this.x}</span><br>
+            ${dataList[1].EdbName}: <span style="font-weight: 600">	${this.y}</span>
+            `
+        },
+        // 中文
+        formatterCh: function() {
+            return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
+            ${dataList[0].EdbName}: <span style="font-weight: 600">	${this.x}</span><br>
+            ${dataList[1].EdbName}: <span style="font-weight: 600">	${this.y}</span>
+            `
+        },
+        // 英文
+        formatterEn: function() {
+            let str1 = `${dataList[0].EdbNameEn}`
+            let str2 = `${dataList[1].EdbNameEn}`
+            return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
+            ${str1}: <span style="font-weight: 600">	${this.x}</span><br>
+            ${str2}: <span style="font-weight: 600">	${this.y}</span>
+            `
+        }
+    }
+
+    const { IsOrder,ChartColor } = dataList[0];
+
+    //获取上下限
+    let minLimit = 0,maxLimit = 0
+    if(!useSelfLimit){
+        minLimit = data.ChartInfo.LeftMin||0;
+        maxLimit = data.ChartInfo.LeftMax||0;
+    }else{
+        minLimit = axisLimitState.leftMin||0
+        maxLimit = axisLimitState.leftMax||0
+    }
+    console.log('check limit',minLimit,maxLimit)
+    const textYZh = dataList[1].ConvertUnit||dataList[1].Unit
+    const textYEn = dataList[1].ConvertEnUnit||dataList[1].UnitEn||dataList[1].ConvertUnit||dataList[1].Unit
+    //y轴
+    let yAxis = {
+        title: {
+            text:  `${textYZh}`,
+            textZh:textYZh,
+            textEn:textYZh?textYEn:'',
+            align: 'high',
+            rotation: 0,
+            y: -15,
+            x:0,
+            textAlign: 'left',
+            reserveSpace: false,
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            formatter: function (ctx) {
+            return ctx.value;
+            },
+            align: 'center',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        opposite: false,
+        reversed: IsOrder,
+        min: Number(minLimit),
+        max: Number(maxLimit),
+        tickWidth: 1,
+        tickLength: 5,
+        lineWidth: 1,
+        lineColor: '#bfbfbf',
+        tickColor: '#bfbfbf',
+        offset: 0,
+        visible: true,
+        gridLineWidth: 0,
+        tickPosition: 'inside',
+        endOnTick: false,
+        startOnTick: false,
+        showLastLabel: true,
+        tickPixelInterval: 50,
+        plotBands: setAxisPlotAreas(1),
+        plotLines: setAxisPlotLines(1)
+    }
+
+    //数据列
+    let series = {
+        data: [],
+        type: 'scatter',
+        name: `${ChartInfo.ChartName}${IsOrder ? '(逆序)' : ''}`,
+        nameZh:`${ChartInfo.ChartName}${IsOrder ? '(逆序)' : ''}`,
+        nameEn:ChartInfo.ChartNameEn?`${ChartInfo.ChartNameEn}${IsOrder ? '(reverse)' : ''}`:'',
+        color: ChartColor,
+        visible:true,
+        chartType: 'linear',
+        marker: {
+          radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+        },
+    }
+    real_data.forEach(_ => {
+        series.data.push([_.x,_.y])
+    })
+    const textXZh = dataList[0].ConvertUnit||dataList[0].Unit
+    const textXEn = dataList[0].ConvertEnUnit||dataList[0].UnitEn||dataList[0].ConvertUnit||dataList[0].Unit
+    return {
+        title: {
+            text:''
+        },
+        series: [ series ],
+        yAxis,
+        xAxis: {
+            ...scatterXAxis,
+            title: {
+                text:  `${textXZh}`,
+                textZh:textXZh,
+                textEn:textXZh?textXEn:'',
+                align: 'high',
+                rotation: 0,
+                x: 0,
+                offset: 20,
+                style: {
+                    ...chartTheme&&chartTheme.xAxisOptions.style
+                },
+            },
+            labels: {
+                style: {
+                  ...chartTheme&&chartTheme.xAxisOptions.style
+                }
+            },
+        },
+        tooltip
+    }
+}
+
+
+/* 奇怪柱形图 */
+const barDateList = ref([]);//柱形图的绘图数据
+const barXData = ref([]);//柱形图的x轴
+const barEdbData = ref([]);//柱形图的表格数据 只用于取值
+let axisLimitData={}
+/* 奇怪柱状图 和其他逻辑无公用点 依赖数据为单独的数据
+    x轴为指标名称的柱形图 以日期作为series
+*/
+function setBarChart (e){
+    let seriesData = [];
+    const data = _.cloneDeep(barDateList.value);
+
+    /* 主题样式*/
+    const chartTheme =  e.ChartInfo.ChartThemeStyle ? JSON.parse(e.ChartInfo.ChartThemeStyle) : null;
+
+    //x轴
+    let xAxis = {
+        ...scatterXAxis,
+        categories: barXData.value,
+        tickWidth: 1,
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        }
+    }
+
+    const { leftMin,leftMax } = axisLimitState;
+
+    const textZh = e.ChartInfo?.Unit
+    const textEn = e.ChartInfo?.UnitEn||e.ChartInfo?.Unit
+    // console.log(leftMin,leftMax)
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text:  textZh,
+            textZh: textZh,
+            textEn: textEn,
+            align: 'high',
+            rotation: 0,
+            y: -12,
+            x:0,
+            textAlign: 'left',
+            reserveSpace: false,
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            formatter: function (ctx) {
+            let val = ctx.value;
+            return val;
+            },
+            align: 'center',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        min: Number(leftMin),
+        max: Number(leftMax),
+        opposite: false,
+        tickWidth: 1,
+        plotBands: setAxisPlotAreas(1),
+        plotLines: setAxisPlotLines(1)
+    }
+
+    //数据列
+    data.forEach(item => {
+        let serie_item = {
+            data: item.Value,
+            type: 'column',
+            yAxis: 0,
+            name: item.Name || item.Date,
+            nameZh: item.Name || item.Date,
+            nameEn: item.Date,
+            color: item.Color,
+            chartType: 'linear',              
+            visible:true,
+        };
+        seriesData.push(serie_item)
+    })
+    
+    return {
+        title: {
+            text:''
+        },
+        plotOptions: {
+            column:{
+            stacking: null,
+            },
+        },
+        series: seriesData,
+        yAxis: [ yAxis ],
+        xAxis
+    }
+}
+/* 获取图表详情后赋值柱状图数据 */
+function initBarData(data){
+    const { XEdbIdValue,YDataList,EdbInfoList,ChartInfo } = data;
+
+    let xData = XEdbIdValue.map(_ => EdbInfoList.find(edb => edb.EdbInfoId===_).EdbAliasName)
+    // console.log(xData)
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+    barDateList.value = YDataList;
+    barXData.value = xData;
+    barEdbData.value = EdbInfoList;
+
+    axisLimitState.hasLeftAxis=true
+    axisLimitState.leftMin=Number(ChartInfo.LeftMin)
+    axisLimitState.leftMax=Number(ChartInfo.LeftMax)
+
+    return setBarChart(data);
+}
+
+
+/* 商品价格曲线设置 绘图逻辑同奇怪柱形图*/
+const commodityChartData = ref([]);//商品价格图的绘图数据
+const commodityXData = ref([]);//商品价格图的x轴
+const commodityEdbList = ref([]);//商品价格图的表格数据 只用于取值
+/* 商品价格曲线设置 绘图逻辑同奇怪柱形图*/
+const setCommodityChart = (leftMin,leftMax) => {
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+    /* 主题样式*/
+    const chartTheme =  chartData.value.ChartInfo.ChartThemeStyle ? JSON.parse(chartData.value.ChartInfo.ChartThemeStyle) : null;
+
+    let seriesData = [];
+    const data = _.cloneDeep(commodityChartData.value);
+    console.log(data);
+
+    //x轴
+    let xAxis = {
+        ...scatterXAxis,
+        categories: commodityXData.value.map(_ => _.Name),
+        tickWidth: 1,
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        }
+    }
+
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text: commodityEdbList.value[0].Unit,
+            textZh: commodityEdbList.value[0].Unit,
+            textEn: commodityEdbList.value[0].Unit?(commodityEdbList.value[0].UnitEn||'英文单位'):'',
+            align: 'high',
+            rotation: 0,
+            y: -15,
+            textAlign: 'left',
+            reserveSpace: false,
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        labels: {
+            formatter: function (ctx) {
+            let val = ctx.value;
+            return val;
+            },
+            align: 'center',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        min: Number(leftMin),
+        max: Number(leftMax),
+        opposite: false,
+        tickWidth: 1,
+    }
+
+    //数据列
+    data.forEach(item => {
+        //处理首或/尾全是无效数据的以null填充
+        let filterData = filterInvalidData(item)
+
+        let serie_item = {
+            data: filterData,
+            type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+            dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+            yAxis: 0,
+            name: item.Name,
+            nameZh: item.Name,
+            nameEn: item.NameEn,
+            color: item.Color,
+            chartType: 'linear',
+            lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+            visible: true,
+            marker: {
+                enabled: false
+            }
+        };
+        seriesData.push(serie_item)
+    })
+
+    //tooltip
+    let tooltip = {
+        formatter: function() {
+            const ctx = this;
+            let str = '';
+            ctx.points.forEach(item => {
+                let obj_item = data.find(_ => _.Name === item.series.name);
+                let index = commodityXData.value.findIndex(_ => _.Name === ctx.x);
+                
+                // 合约显示
+                const haveContract=obj_item.XEdbInfoIdList[index]
+                if(haveContract){
+                    // 利润曲线指标名
+                    let edb_name = chartData.value.ChartInfo.Source === 5 
+                        ? (index === 0 ? obj_item.NameList[index] : `${chartData.value.DataResp.ProfitName}(${obj_item.NameList[index]})`)
+                        : commodityEdbList.value.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName;
+                    str+=`<b>${ edb_name }</b>`
+
+                    if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
+                        str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
+                    }else {
+                        str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
+                    }
+
+                }
+            })
+            return str||'无合约'
+        },
+        formatterCh: function() {
+            let str = ''; 
+            this.points.forEach(item => {
+              let obj_item = data.find(_ => _.Name === item.series.name);
+              let index = commodityXData.value.findIndex(_ => _.Name === this.x);
+  
+              str+=`<b>${ commodityEdbList.value.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName }</b>`
+  
+              if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
+                str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
+              }else {
+                str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
+              }
+            })
+            return str
+          },
+          formatterEn: function() {
+            let str = ''; 
+            this.points.forEach(item => {
+              let obj_item = data.find(_ => _.NameEn === item.series.name);
+              let index = commodityXData.value.findIndex(_ => _.NameEn === this.x);
+  
+              str+=`<b>${ commodityEdbList.value.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbNameEn }</b>`
+  
+              if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
+                str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
+              }else {
+                str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
+              }
+            })
+            return str
+          },
+        shared: true
+    }
+    // console.log(seriesData);
+    return {
+        title: {
+            text:''
+        },
+        series: seriesData,
+        yAxis: [ yAxis ],
+        xAxis,
+        tooltip
+    }
+};
+/* 处理无效数据为null */
+function filterInvalidData(item){
+    let validateArr = item.XEdbInfoIdList.filter(_ =>!item.NoDataEdbList.includes(_));
+
+    let first_index = item.XEdbInfoIdList.findIndex(_ => _ === validateArr[0]);
+    let last_index = item.XEdbInfoIdList.findIndex(_ => _ === validateArr[validateArr.length-1]);
+    // console.log('first_index',first_index)
+    // console.log('last_index',last_index)
+
+    let arr = item.Value.map((item,index) => {
+    if(index < first_index || index > last_index) {
+        return null
+    }else {
+        return item
+    }
+    })
+
+    return arr;
+}
+function initCommodityData(data){
+    const { XDataList,YDataList,EdbInfoList,ChartInfo,DataResp } = data;
+
+    commodityEdbList.value = EdbInfoList;
+    commodityChartData.value = ChartInfo.Source===5?DataResp.YDataList:YDataList
+    commodityXData.value = ChartInfo.Source===5?DataResp.XDataList:XDataList
+
+    axisLimitState.hasLeftAxis=true
+    axisLimitState.leftMin=Number(ChartInfo.LeftMin)
+    axisLimitState.leftMax=Number(ChartInfo.LeftMax)
+
+    return setCommodityChart(ChartInfo.LeftMin,ChartInfo.LeftMax);
+}
+
+
+//相关性图表
+function initRelevanceChart(data){
+
+    /* 主题样式*/
+    const chartTheme =  data.ChartInfo.ChartThemeStyle ? JSON.parse(data.ChartInfo.ChartThemeStyle) : null;
+
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+    // 处理X轴
+    let xAxis={
+        categories: data.ChartInfo.Source===3?data.XEdbIdValue:data.DataResp.XDateTimeValue,
+        tickWidth: 1,
+        title: {
+          text: data.ChartInfo.Source===3 ?`期数(${data.CorrelationChartInfo.LeadUnit})` : null,
+          textZh:data.ChartInfo.Source===3 ? `期数(${data.CorrelationChartInfo.LeadUnit})`:null,
+          textEn:data.ChartInfo.Source===3 ? `stage(${relevanceUnitEnMap[data.CorrelationChartInfo.LeadUnit]})`:null,
+          align: 'high',
+          rotation: 0,
+          x: 0,
+          y:10,
+          offset: 20,
+          style: {
+            ...chartTheme&&chartTheme.xAxisOptions.style
+          }
+        },
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        tickInterval: 1,
+        offset:0,
+        tickmarkPlacement:'on'
+    }
+
+    // 处理Y轴
+    let yAxis={
+        ...basicYAxis,
+        title: {
+          text: '相关性系数',
+          textZh: '相关性系数',
+          textEn: 'Correlation coefficient',
+          align: 'high',
+          rotation: 0,
+          y: -15,
+          textAlign: 'left',
+          reserveSpace: false,
+          style:{
+            ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+        },
+        labels: {
+          formatter: function (ctx) {
+            let val = ctx.value;
+            return val;
+          },
+          align: 'center',
+          style:{
+            ...chartTheme&&chartTheme.yAxisOptions.style
+          },
+        },
+        opposite: false,
+        tickWidth: 1,
+    }
+
+    //处理series
+    let seriesData=[]
+    data.YDataList.forEach(item=>{
+        let serie_item = {
+          data: item.Value,
+          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          yAxis: 0,
+          name: data.ChartInfo.ChartName,
+          nameZh: data.ChartInfo.ChartName,
+          nameEn: data.ChartInfo.ChartNameEn,
+          color: item.Color,
+          chartType: 'linear',
+          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+          visible:true,
+          marker: {
+            enabled: false
+          }
+        };
+        seriesData.push(serie_item)
+    })
+    const { LeadValue,LeadUnit } = data.CorrelationChartInfo;
+    const { Source } = data.ChartInfo;
+
+    let tooltip = {
+        formatter: function() {
+            let str = `<p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${ Source===3 ?this.x+'期' : LeadValue+LeadUnit}</p>`
+            return str
+        },
+        formatterCh: function() {
+            let str = `<p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${ Source===3 ?this.x+'期' : LeadValue+LeadUnit}</p>`
+            return str
+        },
+        formatterEn: function() {
+            let str = `<p>Correlation coefficient:${this.y.toFixed(4)}</p><br><p>lead${ Source===3 ? this.x+'stage' : LeadValue+relevanceUnitEnMap[LeadUnit]}</p>`
+            return str
+        }
+    }
+    
+    nextTick(()=>{
+        // if(data.ChartInfo.Source===3){
+        //     const hEl=document.getElementById(RenderDomId.value)
+        //     // console.log(hEl.offsetHeight);
+        //     xAxis.offset=-(hEl.offsetHeight-98)/2
+        // }
+        
+        options.value = {
+            isRelevanceChart:data.ChartInfo.Source===3,
+            title: {
+                text:''
+            },
+            series: seriesData,
+            yAxis: [yAxis] ,
+            xAxis:xAxis,
+            tooltip
+        }
+        ChartIns.update(options.value,true)
+    })
+
+    return {
+        isRelevanceChart:true,
+        title: {
+            text:''
+        },
+        series: seriesData,
+        yAxis: [yAxis] ,
+        xAxis:xAxis,
+        tooltip
+    }
+}
+
+
+/* 截面散点图设置 sectionScatterData */
+function setSectionScatterChart({DataResp,ChartInfo}) {
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+     /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    const { DataList,XName,XNameEn,XUnitName,XUnitNameEn,YName,YNameEn,YUnitName,YUnitNameEn } = DataResp;
+    const leftMin=Number(DataResp.YMinValue)
+    const leftMax=Number(DataResp.YMaxValue)
+    const xMin=Number(DataResp.XMinValue)
+    const xMax=Number(DataResp.XMaxValue)
+
+    axisLimitState.hasLeftAxis=true
+    axisLimitState.hasXAxis=true
+    axisLimitState.leftMin=leftMin
+    axisLimitState.leftMax=leftMax
+    axisLimitState.xMin=xMin
+    axisLimitState.xMax=xMax
+
+    //y轴
+    let yAxis = {
+        ...basicYAxis,
+        title: {
+            text: YName,
+            textZh:YName,// 中文
+            textEn:YNameEn|| '',
+            style:{
+                ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+            align: 'middle',
+        },
+        labels: {
+            style:{
+              ...chartTheme&&chartTheme.yAxisOptions.style
+            },
+        },
+        opposite: false,
+        reversed: false,
+        min: Number(leftMin),
+        max: Number(leftMax),
+        tickWidth: 1,
+        plotBands: setAxisPlotAreas(1),
+        plotLines: setAxisPlotLines(1)
+    }
+
+    //x轴
+    let xAxis = {
+        ...scatterXAxis,
+        title: {
+            text: XName,
+            textZh:XName,// 中文
+            textEn:XNameEn || '',
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            },
+            align: 'middle',
+        },
+        labels: {
+            style:{
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            },
+        },
+        min: Number(xMin),
+        max: Number(xMax),
+        plotBands: setAxisPlotAreas(3),
+        plotLines: setAxisPlotLines(3)
+    }
+
+    //数据列
+    let series = [];
+    DataList.forEach(item => {
+        //数据列
+        let series_item = {
+            data: [],
+            type: 'scatter',
+            name: item.Name,
+            nameZh: item.Name,
+            nameEn: item.NameEn,
+            color: item.Color,
+            lineWidth: 0,
+            chartType: 'linear',
+            zIndex:1,
+            visible: true,
+            marker: {
+                radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+            },
+        }
+        item.EdbInfoList.forEach(_ => {
+            series_item.data.push({
+            x: _.XValue,
+            y: _.YValue,
+            dataLabels: {
+                enabled: _.IsShow,
+                allowOverlap: true,
+                align: 'left',
+                format: _.Name,
+                formatZh: _.Name,
+                formatEn: _.NameEn
+            }
+            })
+        })
+        series.push(series_item);
+
+        //趋势线
+        if(item.ShowTrendLine)  {
+            
+            let trend_data = item.TrendLimitData.map((_,_index) => (
+                _index === item.TrendLimitData.length-1 ? {
+                    x: _.X,
+                    y: _.Y,
+                    dataLabels: {
+                    enabled: item.ShowRSquare || item.ShowFitEquation,
+                    align: 'left',
+                    color: item.Color,
+                    x: 20,
+                    y: 30,
+                    zIndex: 9,
+                    allowOverlap: true,
+                    formatter: function(){
+                        let tag = '';
+                        item.ShowRSquare && item.ShowFitEquation
+                        ? tag =`<span>${item.TrendLine}</span><br><span>R²=${item.RSquare}</span>`
+                        : item.ShowRSquare && !item.ShowFitEquation
+                        ? tag =`<span>R²=${item.RSquare}</span>`
+                        : item.ShowFitEquation && !item.ShowRSquare
+                        ? tag =`<span>${item.TrendLine}</span>`
+                        : ''
+                        return tag
+                    }
+                    }
+                } : {
+                    x: _.X,
+                    y: _.Y,
+                }
+            ))
+
+            let trend_item = {
+                data: trend_data,
+                type: 'spline',
+                linkedTo: ':previous',
+                color: item.Color,
+                lineWidth: 1,
+                chartType: 'linear',
+                enableMouseTracking: false,
+                dashStyle:'Dash',
+                zIndex: 2,
+                visible: true,
+                marker: {
+                    enabled: false
+                }
+            }
+            series.push(trend_item)
+        }
+    })
+
+    let tooltip = {
+        formatter: function() {
+            let series_obj = DataList.find(_ => _.Name === this.series.name);
+            let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
+
+            let str=`<b>${ ponit_obj.Name }</b>`;
+            str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XName}: ${this.x} ${ponit_obj.XDate}<br>`;
+            str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YName}: ${this.y} (${ponit_obj.YDate})`;
+
+            return str
+        },
+        formatterCh: function() {
+            let series_obj = DataList.find(_ => _.Name === this.series.name);
+            let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
+  
+            let str=`<b>${ ponit_obj.Name }</b>`;
+            str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XName}: ${this.x} ${ponit_obj.XDate}<br>`;
+            str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YName}: ${this.y} (${ponit_obj.YDate})`;
+  
+            return str
+            
+          },
+        formatterEn: function() {
+            let series_obj = DataList.find(_ => _.NameEn === this.series.name);
+            let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
+  
+            let str=`<b>${ ponit_obj.NameEn }</b>`;
+            str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XNameEn}: ${this.x} ${ponit_obj.XDate}<br>`;
+            str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YNameEn}: ${this.y} ${ponit_obj.YDate}`;
+  
+            return str
+        }
+    }
+    
+    return {
+        title: {
+            text:''
+        },
+        series,
+        yAxis: [yAxis],
+        xAxis,
+        tooltip
+    }
+}
+
+/* 跨品种分析 */
+function setCrossVarietyChart({DataResp,EdbInfoList,ChartInfo}) {
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+    /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    const { DataList,XName,YName,XNameEn,YNameEn,XMaxValue,XMinValue,YMaxValue,YMinValue } = DataResp;
+
+    const {leftMin,leftMax,xMin,xMax} = axisLimitState;
+
+     //y轴
+     let yAxis = {
+        ...basicYAxis,
+        title: {
+          text: YName,
+          textCh:YName,// 中文
+          textEn:YNameEn||YName,
+          align: 'middle',
+          style: {
+            ...chartTheme&&chartTheme.xAxisOptions.style
+          }
+        },
+        labels: {
+            style: {
+              ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        opposite: false,
+        reversed: false,
+        min: Number(leftMin),
+        max: Number(leftMax),
+        tickWidth: 1,
+      }
+
+      // x轴
+      let xAxis = {
+        ...scatterXAxis,
+        title: {
+            text: XName,
+            textCh:XName,// 中文
+            textEn:XNameEn || XName,
+            align: 'middle',
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        labels: {
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        min: Number(xMin),
+        max: Number(xMax),
+      }
+
+       //数据列
+      let series = [];
+      const tagMap = { //标签对应文字
+        1: '最新',
+        3: 'Fix'
+      }
+      DataList.forEach(item => {
+        //数据列
+        let series_item = {
+          data: [],
+          type: 'scatter',
+          name: item.Name,
+          nameZh: item.Name,
+          nameEn: item.NameEn||item.Name,
+          color: item.Color,
+          lineWidth: 0,
+          chartType: 'linear',
+          zIndex:1
+        }
+        item.CoordinatePointData.forEach(_ => {
+          series_item.data.push({
+            x: _.X,
+            y: _.Y,
+            dataLabels: {
+              enabled: _.ShowTips===1,
+              allowOverlap: true,
+              align: 'left',
+              format: tagMap[_.DateType] || `-${_.DaysAgo}D`,
+            }
+          })
+        })
+        series.push(series_item);
+      })
+
+      let tooltip = {
+        formatter: function() {
+          let series_obj = DataList.find(_ => _.Name === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbName}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbName}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+        },
+        formatterCh: function() {
+          let series_obj = DataList.find(_ => _.Name === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbName}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbName}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+          
+        },
+        formatterEn: function() {
+          let series_obj = DataList.find(_ => _.NameEn === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = EdbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbNameEn}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbNameEn}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+        }
+      }
+
+      return {
+        title: {
+          text:''
+        },
+        series,
+        yAxis: [yAxis],
+        xAxis,
+        tooltip
+      }
+}
+
+/* 雷达图 */
+function setRadarChart({DataResp,EdbInfoList,ChartInfo}) {
+    axisLimitState.leftIndex=-1
+    axisLimitState.rightIndex=-1
+    axisLimitState.rightTwoIndex=-1
+
+    const { YDataList,XEdbIdValue } = DataResp;
+
+    let XDataList = EdbInfoList.filter(_ => XEdbIdValue.includes(_.EdbInfoId));
+    axisLimitState.hasLeftAxis=true
+    axisLimitState.leftMin=Number(ChartInfo.LeftMin)
+    axisLimitState.leftMax=Number(ChartInfo.LeftMax)
+
+    /* 主题样式*/
+    const chartTheme =  ChartInfo.ChartThemeStyle ? JSON.parse(ChartInfo.ChartThemeStyle) : null;
+
+    //x轴
+    let xAxis = {
+      lineWidth: 0,
+      tickLength: 0,
+      tickmarkPlacement: 'on',
+      categories:XDataList.map(_ => _.EdbAliasName||_.EdbName),
+      labels: {
+        allowOverlap: true,
+        autoRotationLimit: 40,
+        style: {
+          ...chartTheme&&chartTheme.xAxisOptions.style
+        }
+      }
+    }
+    //y轴
+    let yAxis = [{
+      gridLineInterpolation: 'polygon',
+      gridLineWidth: 1,
+      lineWidth: 0,
+      endOnTick: false,
+      startOnTick: false,
+      showLastLabel: true,
+      // tickAmount:4,
+      title: {
+        text:  ChartInfo.Unit,
+        textCh: ChartInfo.Unit,
+        textEn: ChartInfo.UnitEn,
+        align: 'high',
+        rotation: 0,
+        y: 5,
+        x:10,
+        textAlign: 'left',
+        reserveSpace: false,
+        style:{
+          ...chartTheme&&chartTheme.yAxisOptions.style
+        },
+      },
+      labels: {
+        allowOverlap: true,
+        style:{
+          ...chartTheme&&chartTheme.yAxisOptions.style
+        }
+      },
+      min: Number(ChartInfo.LeftMin),
+      max: Number(ChartInfo.LeftMax),
+    }]
+
+    //系列
+    let series = [];
+    YDataList.forEach(item => {
+      let serie_item = {
+        name: item.Name || item.Date,
+        nameZh: item.Name || item.Date,
+        nameEn: item.Date,
+        data: item.Value,
+        pointPlacement: 'on',
+        type: (chartTheme&&chartTheme.lineOptions.lineType) || 'line',
+        dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+        yAxis: 0,
+        color: item.Color,
+        lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+        chartType: 'linear'
+      };
+      series.push(serie_item)
+    })
+
+    return {
+      chart: {
+        ...chartDefaultOpts.chart,
+        ...chartTheme?.drawOption,
+        spacing: [2,10,2,10],
+        polar:true,
+      },
+      title: {
+        text:''
+      },
+      pane: {
+        size: '85%'
+      },
+      series,
+      yAxis,
+      xAxis
+    }
+}
+
+/* ----自定义上下限相关--- */
+/* 计算y轴上下限 */
+function calcYAxislimit(tableData=[],ChartInfo){
+    //散点图单独处理
+    if(ChartInfo.ChartType===5){
+        if(tableData[1]){
+            axisLimitState.leftMin = tableData[1].MinData
+            axisLimitState.leftMax = tableData[1].MaxData
+        }
+        return 
+    }
+    //分组
+    const leftData = tableData.filter(i => i.IsAxis === 1).map(i => [Number(i.MinData), Number(i.MaxData)])
+    const rightData = tableData.filter(i => !i.IsAxis).map(i => [Number(i.MinData), Number(i.MaxData)])
+    const rightTwoData = tableData.filter(i => i.IsAxis === 2).map(i => [Number(i.MinData), Number(i.MaxData)])
+    //计算最大最小值
+    if (leftData.length) {
+        const {
+            Max,
+            Min
+        } = calcLimit(leftData.flat())
+        axisLimitState.leftMin = Min
+        axisLimitState.leftMax = Max
+    } 
+    if (rightData.length) {
+        const {
+            Max,
+            Min
+        } = calcLimit(rightData.flat())
+        axisLimitState.rightMin = Min
+        axisLimitState.rightMax = Max
+    }
+    if (rightTwoData.length) {
+        const {
+            Max,
+            Min
+        } = calcLimit(rightTwoData.flat())
+        axisLimitState.rightTwoMin = Min
+        axisLimitState.rightTwoMax = Max
+    }
+}
+function calcLimit(arr) {
+    return {
+        Max: Math.max(...arr),
+        Min: Math.min(...arr)
+    }
+}
+//图表详情-设置图表上下限
+function setLimitData({EdbInfoList,ChartInfo}){
+    const {
+        //左右轴极值字段 
+        LeftMin=0,LeftMax=0,
+        RightMin=0,RightMax=0,
+        Right2Min=0,Right2Max=0,
+        MinMaxSave
+    } = ChartInfo
+    if(MinMaxSave){
+        axisLimitState.leftMin = Number(LeftMin)
+        axisLimitState.leftMax = Number(LeftMax)
+        axisLimitState.rightMin = Number(RightMin)
+        axisLimitState.rightMax = Number(RightMax)
+        axisLimitState.rightTwoMin = Number(Right2Min)
+        axisLimitState.rightTwoMax = Number(Right2Max)
+        //若用户修改过,则检测轴的上下限是否为空,若为空,则需要计算对应轴的上下限
+        checkLimit(EdbInfoList,ChartInfo)
+        console.log('check',axisLimitState.leftMin,axisLimitState.leftMax)
+    }else{
+        calcYAxislimit(EdbInfoList,ChartInfo)
+    }
+}
+function checkLimit(tableData=[],ChartInfo){
+    //散点图单独处理
+    if(ChartInfo.ChartType===5){
+        if(tableData[1]){
+            if(Number(axisLimitState.leftMin)===0&&Number(axisLimitState.leftMax)===0){
+                axisLimitState.leftMin = tableData[1].MinData
+                axisLimitState.leftMax = tableData[1].MaxData
+            }
+        }
+        return 
+    }
+    //若轴的上下限均为0,则不管用户有没有修改过,都重新赋值
+    if(Number(axisLimitState.leftMin)===0&&Number(axisLimitState.leftMax)===0){
+        const leftData = tableData.filter(i=>i.IsAxis===1).map(i=>[Number(i.MinData),Number(i.MaxData)])
+        if(leftData.length){
+            const {Max,Min} = calcLimit(leftData.flat())
+            axisLimitState.leftMin = Min
+            axisLimitState.leftMax = Max
+        }
+    }
+    if(Number(axisLimitState.rightMin)===0&&Number(axisLimitState.rightMax)===0){
+        const rightData = tableData.filter(i => !i.IsAxis).map(i=>[Number(i.MinData),Number(i.MaxData)])
+        if(rightData.length){
+            const {Max,Min} = calcLimit(rightData.flat())
+            axisLimitState.rightMin = Min
+            axisLimitState.rightMax = Max
+        }
+    }
+    if(Number(axisLimitState.rightTwoMin)===0&&Number(axisLimitState.rightTwoMax)===0){
+        const rightTwoData = tableData.filter(i=>i.IsAxis===2).map(i=>[Number(i.MinData),Number(i.MaxData)])
+        if(rightTwoData.length){
+            const {Max,Min} = calcLimit(rightTwoData.flat())
+            axisLimitState.rightTwoMin = Min
+            axisLimitState.rightTwoMax = Max
+        }
+    }
+}
+/*-------------------- */

+ 16 - 0
src/main.js

@@ -0,0 +1,16 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from "./router";
+import '@/styles/vars.css'
+import 'normalize.css'
+import '@/styles/common.scss'
+import 'virtual:svg-icons-register'
+import registerGlobalComponents from '@/components/globalComponents';
+
+const app= createApp(App)
+
+// 注册全局组件
+registerGlobalComponents(app);
+
+app.use(router)
+app.mount('#app')

+ 33 - 0
src/router/index.js

@@ -0,0 +1,33 @@
+import { createRouter, createWebHistory } from "vue-router";
+
+//all routes
+const appAllRoutes = [];
+function importAllRoutes(r) {
+  for (let key in r) {
+    appAllRoutes.push(...r[key].default);
+  }
+}
+importAllRoutes(import.meta.glob("./modules/*.js", { eager: true }));
+
+const routes = [
+  ...appAllRoutes,
+
+  {
+    path: "/:pathMatch(.*)",
+    name: "error",
+    component: () => import("@/views/404.vue"),
+    meta: { title: "404" },
+  },
+];
+
+const router = createRouter({
+  history: createWebHistory(import.meta.env.VITE_APP_BASE_URL),
+  routes,
+});
+
+router.beforeEach(async (to, from, next) => {
+  document.title = to.meta.title;
+  next();
+});
+
+export default router;

+ 10 - 0
src/router/modules/chart.js

@@ -0,0 +1,10 @@
+export default[
+  {
+    path:'/chart/detail',
+    component:()=>import('@/views/chart/Detail.vue'),
+    name:'ChartDetail',
+    meta:{
+      title:'图表详情'
+    },
+  }
+]

+ 10 - 0
src/router/modules/report.js

@@ -0,0 +1,10 @@
+export default[
+  {
+    path:'/report/detail',
+    component:()=>import('@/views/report/Detail.vue'),
+    name:'ReportDetail',
+    meta:{
+      title:'报告详情'
+    },
+  }
+]

+ 14 - 0
src/styles/common.scss

@@ -0,0 +1,14 @@
+/* 全局公共样式 */
+html,body,#app{
+  font-size: var(--font-size);
+  color: var(--text-color);
+  width: 100%;
+  background-color: var(--bg-color);
+}
+
+div{
+  box-sizing: border-box;
+}
+.flex{
+  display: flex;
+}

+ 31 - 0
src/styles/vars.css

@@ -0,0 +1,31 @@
+:root{
+  --primary-color:#053CC9;
+    --primary-color_sub:#DDE6FF;
+
+    --success-color:#4cd964;
+    --warning-color:#FFEFB6;
+    --error-color:#C54322;
+
+    --bg-color:#ffffff;
+    --bg-grey-color:#F8F8FA;
+    --bg-index-page:#F6F9FF;
+
+    --border-color:#DCDFE6;
+
+    --text-color:#333333;
+    --text-color-sub :#666666;
+    --text-color-inverse:#ffffff;
+    --text-color-grey:#999;
+    --text-color-warning:#8F5600;
+
+    --font-size:28px;
+    --font-size-small:24px;
+    --font-size-large:30px;
+    --font-size-huge:34px;
+
+    --page-padding:34px;
+
+    /* 修改td组件颜色 */
+    --td-primary-color-7:#053CC9;
+    --td-primary-color-1:#F5F8FF;
+}

+ 789 - 0
src/utils/crypto.js

@@ -0,0 +1,789 @@
+let key = '';
+
+class CryptoJS {
+	// 3DES加密,CBC/PKCS5Padding
+	static Des3Encrypt (input,keyVal) {
+		key=keyVal
+		let genKey = genkey(key, 0, 24);
+		return base64encode(des(genKey.key, input, 1, 1, key.substr(0, 8), 1));
+	}
+
+	// 3DES解密,CBC/PKCS5Padding
+	static Des3Decrypt (input,keyVal) {
+		key=keyVal
+		let genKey = genkey(key, 0, 24);
+		return des(genKey.key, base64decode(input), 0, 1, key.substr(0, 8), 1);
+	}
+
+	// md5
+	static Md5Encrypt (input) {
+		return md5(String(input));
+	}
+}
+
+function des (key, message, encrypt, mode, iv, padding) {
+	if (encrypt) // 如果是加密的话,首先转换编码
+	{ message = unescape(encodeURIComponent(message)); }
+	// declaring this locally speeds things up a bit
+	let spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
+	let spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
+	let spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
+	let spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
+	let spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
+	let spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
+	let spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
+	let spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
+
+	// create the 16 or 48 subkeys we will need
+	let keys = des_createKeys(key);
+
+	let m = 0, i, j, temp, temp2, right1, right2, left, right, looping;
+	let cbcleft, cbcleft2, cbcright, cbcright2;
+	let endloop, loopinc;
+	var len = message.length;
+	let chunk = 0;
+	// set up the loops for single and triple des
+	let iterations = keys.length === 32 ? 3 : 9; // single or triple des
+	if (iterations === 3) { looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2); } else { looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2); }
+
+	// pad the message depending on the padding parameter
+	if (padding === 2) message += '        '; // pad the message with spaces
+	else if (padding === 1) {
+		if (encrypt) {
+			temp = 8 - (len % 8);
+			message += String.fromCharCode(temp, temp, temp, temp, temp, temp, temp, temp);
+			if (temp === 8) len += 8;
+		}
+	} // PKCS7 padding
+	else if (!padding) message += '\0\0\0\0\0\0\0\0'; // pad the message out with null bytes
+
+	// store the result here
+	let result = '';
+	let tempresult = '';
+
+	if (mode === 1) { // CBC mode
+		cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
+		cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
+		m = 0;
+	}
+
+	// loop through each 64 bit chunk of the message
+	while (m < len) {
+		left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
+		right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
+
+		// for Cipher Block Chaining mode, xor the message with the previous result
+		if (mode === 1) {
+			if (encrypt) {
+				left ^= cbcleft;
+				right ^= cbcright;
+			} else {
+				cbcleft2 = cbcleft;
+				cbcright2 = cbcright;
+				cbcleft = left;
+				cbcright = right;
+			}
+		}
+
+		// first each 64 but chunk of the message must be permuted according to IP
+		temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+		right ^= temp;
+		left ^= (temp << 4);
+		temp = ((left >>> 16) ^ right) & 0x0000ffff;
+		right ^= temp;
+		left ^= (temp << 16);
+		temp = ((right >>> 2) ^ left) & 0x33333333;
+		left ^= temp;
+		right ^= (temp << 2);
+		temp = ((right >>> 8) ^ left) & 0x00ff00ff;
+		left ^= temp;
+		right ^= (temp << 8);
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+
+		left = ((left << 1) | (left >>> 31));
+		right = ((right << 1) | (right >>> 31));
+
+		// do this either 1 or 3 times for each chunk of the message
+		for (j = 0; j < iterations; j += 3) {
+			endloop = looping[j + 1];
+			loopinc = looping[j + 2];
+			// now go through and perform the encryption or decryption
+			for (i = looping[j]; i !== endloop; i += loopinc) { // for efficiency
+				right1 = right ^ keys[i];
+				right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
+				// the result is attained by passing these bytes through the S selection functions
+				temp = left;
+				left = right;
+				right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] |
+					spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] |
+					spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] |
+					spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
+			}
+			temp = left;
+			left = right;
+			right = temp; // unreverse left and right
+		} // for either 1 or 3 iterations
+
+		// move then each one bit to the right
+		left = ((left >>> 1) | (left << 31));
+		right = ((right >>> 1) | (right << 31));
+
+		// now perform IP-1, which is IP in the opposite direction
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+		temp = ((right >>> 8) ^ left) & 0x00ff00ff;
+		left ^= temp;
+		right ^= (temp << 8);
+		temp = ((right >>> 2) ^ left) & 0x33333333;
+		left ^= temp;
+		right ^= (temp << 2);
+		temp = ((left >>> 16) ^ right) & 0x0000ffff;
+		right ^= temp;
+		left ^= (temp << 16);
+		temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+		right ^= temp;
+		left ^= (temp << 4);
+
+		// for Cipher Block Chaining mode, xor the message with the previous result
+		if (mode === 1) {
+			if (encrypt) {
+				cbcleft = left;
+				cbcright = right;
+			} else {
+				left ^= cbcleft2;
+				right ^= cbcright2;
+			}
+		}
+		tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), (right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff));
+
+		chunk += 8;
+		if (chunk === 512) {
+			result += tempresult;
+			tempresult = '';
+			chunk = 0;
+		}
+	} // for every 8 characters, or 64 bits in the message
+
+	// return the result as an array
+	result += tempresult;
+	result = result.replace(/\0*$/g, '');
+
+	if (!encrypt) { // 如果是解密的话,解密结束后对PKCS7 padding进行解码,并转换成utf-8编码
+		if (padding === 1) { // PKCS7 padding解码
+			var len = result.length, paddingChars = 0;
+			len && (paddingChars = result.charCodeAt(len - 1));
+			(paddingChars <= 8) && (result = result.substring(0, len - paddingChars));
+		}
+		// 转换成UTF-8编码
+		result = decodeURIComponent(escape(result));
+	}
+
+	return result;
+} // end of des
+
+// des_createKeys
+// this takes as input a 64 bit key (even though only 56 bits are used)
+// as an array of 2 integers, and returns 16 48 bit keys
+function des_createKeys (key) {
+	// declaring this locally speeds things up a bit
+	let pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204);
+	let pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101);
+	let pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808);
+	let pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000);
+	let pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, 0x41000, 0x1010, 0x41010);
+	let pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, 0x2000000, 0x2000400, 0x2000020, 0x2000420);
+	let pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002);
+	let pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800);
+	let pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, 0x2000002, 0x2040002, 0x2000002, 0x2040002);
+	let pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408);
+	let pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, 0x102000, 0x102020, 0x102000, 0x102020);
+	let pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200);
+	let pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010);
+	let pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105);
+
+	// how many iterations (1 for des, 3 for triple des)
+	let iterations = key.length > 8 ? 3 : 1; // changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
+	// stores the return keys
+	let keys = new Array(32 * iterations);
+	// now define the left shifts which need to be done
+	let shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
+	// other variables
+	let lefttemp, righttemp, m = 0, n = 0, temp;
+
+	for (let j = 0; j < iterations; j++) { // either 1 or 3 iterations
+		let left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
+		let right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
+
+		temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+		right ^= temp;
+		left ^= (temp << 4);
+		temp = ((right >>> -16) ^ left) & 0x0000ffff;
+		left ^= temp;
+		right ^= (temp << -16);
+		temp = ((left >>> 2) ^ right) & 0x33333333;
+		right ^= temp;
+		left ^= (temp << 2);
+		temp = ((right >>> -16) ^ left) & 0x0000ffff;
+		left ^= temp;
+		right ^= (temp << -16);
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+		temp = ((right >>> 8) ^ left) & 0x00ff00ff;
+		left ^= temp;
+		right ^= (temp << 8);
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+
+		// the right side needs to be shifted and to get the last four bits of the left side
+		temp = (left << 8) | ((right >>> 20) & 0x000000f0);
+		// left needs to be put upside down
+		left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
+		right = temp;
+
+		// now go through and perform these shifts on the left and right keys
+		for (let i = 0; i < shifts.length; i++) {
+			// shift the keys either one or two bits to the left
+			if (shifts[i]) {
+				left = (left << 2) | (left >>> 26);
+				right = (right << 2) | (right >>> 26);
+			} else {
+				left = (left << 1) | (left >>> 27);
+				right = (right << 1) | (right >>> 27);
+			}
+			left &= -0xf;
+			right &= -0xf;
+
+			// now apply PC-2, in such a way that E is easier when encrypting or decrypting
+			// this conversion will look like PC-2 except only the last 6 bits of each byte are used
+			// rather than 48 consecutive bits and the order of lines will be according to
+			// how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
+			lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] |
+				pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] |
+				pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] |
+				pc2bytes6[(left >>> 4) & 0xf];
+			righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] |
+				pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] |
+				pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] |
+				pc2bytes13[(right >>> 4) & 0xf];
+			temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
+			keys[n++] = lefttemp ^ temp;
+			keys[n++] = righttemp ^ (temp << 16);
+		}
+	} // for each iterations
+	// return the keys we've created
+	return keys;
+} // end of des_createKeys
+function genkey (key, start, end) {
+	// 8 byte / 64 bit Key (DES) or 192 bit Key
+	return { key: pad(key.slice(start, end)), vector: 1 };
+}
+function pad (key) {
+	for (let i = key.length; i < 24; i++) {
+		key += '0';
+	}
+	return key;
+}
+
+let BASE64_MAPPING = [
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+	'w', 'x', 'y', 'z', '0', '1', '2', '3',
+	'4', '5', '6', '7', '8', '9', '+', '/'
+];
+
+/**
+ *ascii convert to binary
+ */
+let _toBinary = function (ascii) {
+	let binary = new Array();
+	while (ascii > 0) {
+		let b = ascii % 2;
+		ascii = Math.floor(ascii / 2);
+		binary.push(b);
+	}
+	/*
+	 var len = binary.length;
+	 if(6-len > 0){
+	 for(var i = 6-len ; i > 0 ; --i){
+	 binary.push(0);
+	 }
+	 } */
+	binary.reverse();
+	return binary;
+};
+
+/**
+ *binary convert to decimal
+ */
+let _toDecimal = function (binary) {
+	let dec = 0;
+	let p = 0;
+	for (let i = binary.length - 1; i >= 0; --i) {
+		let b = binary[i];
+		if (b === 1) {
+			dec += Math.pow(2, p);
+		}
+		++p;
+	}
+	return dec;
+};
+
+/**
+ *unicode convert to utf-8
+ */
+let _toUTF8Binary = function (c, binaryArray) {
+	let mustLen = (8 - (c + 1)) + ((c - 1) * 6);
+	let fatLen = binaryArray.length;
+	let diff = mustLen - fatLen;
+	while (--diff >= 0) {
+		binaryArray.unshift(0);
+	}
+	let binary = [];
+	let _c = c;
+	while (--_c >= 0) {
+		binary.push(1);
+	}
+	binary.push(0);
+	let i = 0, len = 8 - (c + 1);
+	for (; i < len; ++i) {
+		binary.push(binaryArray[i]);
+	}
+
+	for (let j = 0; j < c - 1; ++j) {
+		binary.push(1);
+		binary.push(0);
+		let sum = 6;
+		while (--sum >= 0) {
+			binary.push(binaryArray[i++]);
+		}
+	}
+	return binary;
+};
+
+let BASE64 = {
+	/**
+	 *BASE64 Encode
+	 */
+	encoder: function (str) {
+		let base64_Index = [];
+		let binaryArray = [];
+		for (var i = 0, len = str.length; i < len; ++i) {
+			let unicode = str.charCodeAt(i);
+			let _tmpBinary = _toBinary(unicode);
+			if (unicode < 0x80) {
+				let _tmpdiff = 8 - _tmpBinary.length;
+				while (--_tmpdiff >= 0) {
+					_tmpBinary.unshift(0);
+				}
+				binaryArray = binaryArray.concat(_tmpBinary);
+			} else if (unicode >= 0x80 && unicode <= 0x7FF) {
+				binaryArray = binaryArray.concat(_toUTF8Binary(2, _tmpBinary));
+			} else if (unicode >= 0x800 && unicode <= 0xFFFF) { // UTF-8 3byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(3, _tmpBinary));
+			} else if (unicode >= 0x10000 && unicode <= 0x1FFFFF) { // UTF-8 4byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(4, _tmpBinary));
+			} else if (unicode >= 0x200000 && unicode <= 0x3FFFFFF) { // UTF-8 5byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(5, _tmpBinary));
+			} else if (unicode >= 4000000 && unicode <= 0x7FFFFFFF) { // UTF-8 6byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(6, _tmpBinary));
+			}
+		}
+
+		let extra_Zero_Count = 0;
+		for (var i = 0, len = binaryArray.length; i < len; i += 6) {
+			let diff = (i + 6) - len;
+			if (diff === 2) {
+				extra_Zero_Count = 2;
+			} else if (diff === 4) {
+				extra_Zero_Count = 4;
+			}
+			// if(extra_Zero_Count > 0){
+			//  len += extra_Zero_Count+1;
+			// }
+			let _tmpExtra_Zero_Count = extra_Zero_Count;
+			while (--_tmpExtra_Zero_Count >= 0) {
+				binaryArray.push(0);
+			}
+			base64_Index.push(_toDecimal(binaryArray.slice(i, i + 6)));
+		}
+
+		let base64 = '';
+		for (var i = 0, len = base64_Index.length; i < len; ++i) {
+			base64 += BASE64_MAPPING[base64_Index[i]];
+		}
+
+		for (var i = 0, len = extra_Zero_Count / 2; i < len; ++i) {
+			base64 += '=';
+		}
+		return base64;
+	},
+	/**
+	 *BASE64  Decode for UTF-8
+	 */
+	decoder: function (_base64Str) {
+		let _len = _base64Str.length;
+		let extra_Zero_Count = 0;
+		/**
+		 *计算在进行BASE64编码的时候,补了几个0
+		 */
+		if (_base64Str.charAt(_len - 1) === '=') {
+			// alert(_base64Str.charAt(_len-1));
+			// alert(_base64Str.charAt(_len-2));
+			if (_base64Str.charAt(_len - 2) === '=') { // 两个等号说明补了4个0
+				extra_Zero_Count = 4;
+				_base64Str = _base64Str.substring(0, _len - 2);
+			} else { // 一个等号说明补了2个0
+				extra_Zero_Count = 2;
+				_base64Str = _base64Str.substring(0, _len - 1);
+			}
+		}
+
+		let binaryArray = [];
+		for (var i = 0, len = _base64Str.length; i < len; ++i) {
+			let c = _base64Str.charAt(i);
+			for (let j = 0, size = BASE64_MAPPING.length; j < size; ++j) {
+				if (c === BASE64_MAPPING[j]) {
+					let _tmp = _toBinary(j);
+					/* 不足6位的补0 */
+					let _tmpLen = _tmp.length;
+					if (6 - _tmpLen > 0) {
+						for (let k = 6 - _tmpLen; k > 0; --k) {
+							_tmp.unshift(0);
+						}
+					}
+					binaryArray = binaryArray.concat(_tmp);
+					break;
+				}
+			}
+		}
+
+		if (extra_Zero_Count > 0) {
+			binaryArray = binaryArray.slice(0, binaryArray.length - extra_Zero_Count);
+		}
+
+		let unicode = [];
+		let unicodeBinary = [];
+		for (var i = 0, len = binaryArray.length; i < len;) {
+			if (binaryArray[i] === 0) {
+				unicode = unicode.concat(_toDecimal(binaryArray.slice(i, i + 8)));
+				i += 8;
+			} else {
+				let sum = 0;
+				while (i < len) {
+					if (binaryArray[i] === 1) {
+						++sum;
+					} else {
+						break;
+					}
+					++i;
+				}
+				unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 1, i + 8 - sum));
+				i += 8 - sum;
+				while (sum > 1) {
+					unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 2, i + 8));
+					i += 8;
+					--sum;
+				}
+				unicode = unicode.concat(_toDecimal(unicodeBinary));
+				unicodeBinary = [];
+			}
+		}
+		// ---------直接转换为结果
+		let strResult = '';
+		for (var i = 0, len = unicode.length; i < len; ++i) {
+			strResult += String.fromCharCode(unicode[i]);
+		}
+		return strResult;
+	}
+};
+
+let rotateLeft = function (lValue, iShiftBits) {
+	return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
+};
+
+let addUnsigned = function (lX, lY) {
+	let lX4, lY4, lX8, lY8, lResult;
+	lX8 = (lX & 0x80000000);
+	lY8 = (lY & 0x80000000);
+	lX4 = (lX & 0x40000000);
+	lY4 = (lY & 0x40000000);
+	lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
+	if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
+	if (lX4 | lY4) {
+		if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
+		else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
+	} else {
+		return (lResult ^ lX8 ^ lY8);
+	}
+};
+
+let F = function (x, y, z) {
+	return (x & y) | ((~x) & z);
+};
+
+let G = function (x, y, z) {
+	return (x & z) | (y & (~z));
+};
+
+let H = function (x, y, z) {
+	return (x ^ y ^ z);
+};
+
+let I = function (x, y, z) {
+	return (y ^ (x | (~z)));
+};
+
+let FF = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let GG = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let HH = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let II = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let convertToWordArray = function (string) {
+	let lWordCount;
+	let lMessageLength = string.length;
+	let lNumberOfWordsTempOne = lMessageLength + 8;
+	let lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;
+	let lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
+	let lWordArray = Array(lNumberOfWords - 1);
+	let lBytePosition = 0;
+	let lByteCount = 0;
+	while (lByteCount < lMessageLength) {
+		lWordCount = (lByteCount - (lByteCount % 4)) / 4;
+		lBytePosition = (lByteCount % 4) * 8;
+		lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
+		lByteCount++;
+	}
+	lWordCount = (lByteCount - (lByteCount % 4)) / 4;
+	lBytePosition = (lByteCount % 4) * 8;
+	lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
+	lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
+	lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
+	return lWordArray;
+};
+
+let wordToHex = function (lValue) {
+	let WordToHexValue = '', WordToHexValueTemp = '', lByte, lCount;
+	for (lCount = 0; lCount <= 3; lCount++) {
+		lByte = (lValue >>> (lCount * 8)) & 255;
+		WordToHexValueTemp = '0' + lByte.toString(16);
+		WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
+	}
+	return WordToHexValue;
+};
+
+let uTF8Encode = function (str) {
+	str = str.replace(/\x0d\x0a/g, '\x0a');
+	let output = '';
+	for (let n = 0; n < str.length; n++) {
+		let c = str.charCodeAt(n);
+		if (c < 128) {
+			output += String.fromCharCode(c);
+		} else if ((c > 127) && (c < 2048)) {
+			output += String.fromCharCode((c >> 6) | 192);
+			output += String.fromCharCode((c & 63) | 128);
+		} else {
+			output += String.fromCharCode((c >> 12) | 224);
+			output += String.fromCharCode(((c >> 6) & 63) | 128);
+			output += String.fromCharCode((c & 63) | 128);
+		}
+	}
+	return output;
+};
+
+var md5 = function (string) {
+	let x = Array();
+	let k, AA, BB, CC, DD, a, b, c, d;
+	let S11 = 7, S12 = 12, S13 = 17, S14 = 22;
+	let S21 = 5, S22 = 9, S23 = 14, S24 = 20;
+	let S31 = 4, S32 = 11, S33 = 16, S34 = 23;
+	let S41 = 6, S42 = 10, S43 = 15, S44 = 21;
+	string = uTF8Encode(string);
+	x = convertToWordArray(string);
+	a = 0x67452301;
+	b = 0xEFCDAB89;
+	c = 0x98BADCFE;
+	d = 0x10325476;
+	for (k = 0; k < x.length; k += 16) {
+		AA = a;
+		BB = b;
+		CC = c;
+		DD = d;
+		a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
+		d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
+		c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
+		b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
+		a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
+		d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
+		c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
+		b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
+		a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
+		d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
+		c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
+		b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
+		a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
+		d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
+		c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
+		b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
+		a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
+		d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
+		c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
+		b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
+		a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
+		d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
+		c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
+		b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
+		a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
+		d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
+		c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
+		b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
+		a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
+		d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
+		c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
+		b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
+		a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
+		d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
+		c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
+		b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
+		a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
+		d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
+		c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
+		b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
+		a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
+		d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
+		c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
+		b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
+		a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
+		d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
+		c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
+		b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
+		a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
+		d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
+		c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
+		b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
+		a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
+		d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
+		c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
+		b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
+		a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
+		d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
+		c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
+		b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
+		a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
+		d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
+		c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
+		b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
+		a = addUnsigned(a, AA);
+		b = addUnsigned(b, BB);
+		c = addUnsigned(c, CC);
+		d = addUnsigned(d, DD);
+	}
+	let tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
+	return tempValue.toLowerCase();
+};
+let base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+let base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
+/**
+ * base64编码
+ * @param {Object} str
+ */
+function base64encode (str) {
+	let out, i, len;
+	let c1, c2, c3;
+	len = str.length;
+	i = 0;
+	out = '';
+	while (i < len) {
+		c1 = str.charCodeAt(i++) & 0xff;
+		if (i === len) {
+			out += base64EncodeChars.charAt(c1 >> 2);
+			out += base64EncodeChars.charAt((c1 & 0x3) << 4);
+			out += '==';
+			break;
+		}
+		c2 = str.charCodeAt(i++);
+		if (i === len) {
+			out += base64EncodeChars.charAt(c1 >> 2);
+			out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+			out += base64EncodeChars.charAt((c2 & 0xF) << 2);
+			out += '=';
+			break;
+		}
+		c3 = str.charCodeAt(i++);
+		out += base64EncodeChars.charAt(c1 >> 2);
+		out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+		out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
+		out += base64EncodeChars.charAt(c3 & 0x3F);
+	}
+	return out;
+}
+/**
+ * base64解码
+ * @param {Object} str
+ */
+function base64decode (str) {
+	let c1, c2, c3, c4;
+	let i, len, out;
+	len = str.length;
+	i = 0;
+	out = '';
+	while (i < len) {
+		/* c1 */
+		do {
+			c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+		}
+		while (i < len && c1 === -1);
+		if (c1 === -1) { break; }
+		/* c2 */
+		do {
+			c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+		}
+		while (i < len && c2 === -1);
+		if (c2 === -1) { break; }
+		out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
+		/* c3 */
+		do {
+			c3 = str.charCodeAt(i++) & 0xff;
+			if (c3 === 61) { return out; }
+			c3 = base64DecodeChars[c3];
+		}
+		while (i < len && c3 === -1);
+		if (c3 === -1) { break; }
+		out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
+		/* c4 */
+		do {
+			c4 = str.charCodeAt(i++) & 0xff;
+			if (c4 === 61) { return out; }
+			c4 = base64DecodeChars[c4];
+		}
+		while (i < len && c4 === -1);
+		if (c4 === -1) { break; }
+		out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
+	}
+	return out;
+}
+
+export default CryptoJS;

+ 25 - 0
src/views/404.vue

@@ -0,0 +1,25 @@
+<script setup>
+
+</script>
+
+<template>
+    <div class="nofound-page">
+        <img src="@/assets/imgs/404.png" alt="">
+        <p>404</p>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.nofound-page{
+    text-align: center;
+    font-size: 32px;
+    color: #666;
+    padding-top: 100px;
+    p{
+        margin: 20px 0;
+    }
+}
+img{
+    width: 300px;
+}
+</style>

+ 73 - 0
src/views/chart/Detail.vue

@@ -0,0 +1,73 @@
+<script setup>
+import {useChartRender} from '@/hooks/chart/render'
+
+const {options,axisLimitState,chartRender,setLimitData,isUseSelfLimit}=useChartRender()
+
+function handleCollect(){
+
+}
+
+const isShowMZSM=ref(false)
+</script>
+<template>
+  <div class="chart-detail-page">
+    <div class="chart-title">图表标题</div>
+    <div class="mz-tips" @click="isShowMZSM = true">免责声明</div>
+    <!-- 图表渲染盒子 -->
+    <div class="chart-render-wrap"></div>
+    <div><span>来源:</span></div>
+
+    <div class="change-btns-box">
+      <div class="btn">上一张</div>
+      <div class="btn">下一张</div>
+    </div>
+    <!-- 收藏 -->
+    <svg-icon @click="handleCollect" class="collect-icon" name="collect" />
+  </div>
+  <!-- 免责声明 -->
+  <disclaimers-wrap v-model:show="isShowMZSM" />
+</template>
+
+<style lang="scss" scoped>
+.chart-detail-page{
+  padding: var(--page-padding);
+  .chart-title{
+    font-size: 36px;
+    line-height: 44px;
+    margin-bottom: 20px;
+  }
+  .mz-tips{
+    text-align: right;
+    color: var(--primary-color);
+    font-size: var(--font-size-small);
+  }
+  .chart-render-wrap{
+    margin-top: 50px;
+    height: 800px;
+  }
+  .change-btns-box{
+    position: fixed;
+    left: var(--page-padding);
+    right: var(--page-padding);
+    bottom: 69px;
+    display: flex;
+    justify-content: space-between;
+    .btn{
+      width: 48%;
+      height: 68px;
+      text-align: center;
+      border-radius: 68px;
+      line-height: 68px;
+      background-color: #F3F5F9;
+    }
+  }
+}
+.collect-icon {
+  position: fixed;
+  z-index: 99;
+  right: 34px;
+  bottom: 130px;
+  width: 100px;
+  height: 100px;
+}
+</style>

+ 222 - 0
src/views/report/Detail.vue

@@ -0,0 +1,222 @@
+<script setup>
+
+
+// 点击收藏
+function handleCollect() {
+
+}
+
+// 显示免责声明
+const isShowMZSM = ref(false)
+
+// 显示返回顶部
+const showToTop = ref(false)
+function handlePageScroll() {
+  const top = document.documentElement.scrollTop || document.body.scrollTop
+  if (top > window.outerHeight) {
+    showToTop.value = true
+  } else {
+    showToTop.value = false
+  }
+}
+function handleBackTop() {
+  document.body.scrollTop = document.documentElement.scrollTop = 0
+}
+
+// 点击报告内容中的图片
+function handlePreviewImgs() {
+  document.addEventListener('DOMContentLoaded', function () {
+    document.querySelector('.rich-content').addEventListener('click', function (event) {
+      let imgArray = [];
+      let curImageSrc = event.target.src;
+      let oParent = event.target.parentNode;
+      if (curImageSrc && !oParent.hasAttribute('href')) {
+        let imgs = document.querySelectorAll('.rich-content img');
+        for (let i = 0; i < imgs.length; i++) {
+          let itemSrc = imgs[i].src;
+          imgArray.push(itemSrc);
+        }
+        wx.previewImage({ current: curImageSrc, urls: imgArray });
+      }
+    });
+  });
+}
+
+onMounted(() => {
+  handlePreviewImgs()
+  window.addEventListener('scroll', handlePageScroll)
+})
+onUnmounted(() => {
+  window.removeEventListener('scroll', handlePageScroll)
+})
+
+</script>
+
+<template>
+  <div class="report-detail-page">
+    <div class="title-box">报告标题</div>
+    <div class="author-box">作者</div>
+    <div class="time-box">
+      <span>2023-02-02 12:12</span>
+      <span class="btn" @click="isShowMZSM = true">免责声明</span>
+    </div>
+    <div class="des-box">
+      <svg-icon name="icon01"></svg-icon>
+      <div>摘要内容部分</div>
+    </div>
+    <div class="report-content-box rich-content"></div>
+    <!-- 右侧悬浮操作栏 -->
+    <div class="right-fix-box">
+      <!-- 收藏 -->
+      <svg-icon
+        @click="handleCollect"
+        class="item collect-icon"
+        name="collect"
+      />
+      <!-- 返回顶部 -->
+      <div class="item back-top-img">
+        <svg-icon
+          name="backtop"
+          v-show="showToTop"
+          @click="handleBackTop"
+          class="back-top-img"
+        />
+      </div>
+    </div>
+  </div>
+  <!-- 无权限  -->
+  <div class="no-auth-wrap" v-if="false">
+    <div class="opcity-box"></div>
+    <div class="content-box">
+      <img class="icon" src="@/assets/imgs/lock-img.png" alt="" />
+      <div class="text">您暂无权限查看,<br />请联系客服人员开通!</div>
+      <t-button theme="primary" block style="width: 300px; margin: 30px auto"
+        >立即联系</t-button
+      >
+    </div>
+  </div>
+  <!-- 免责声明 -->
+  <disclaimers-wrap v-model:show="isShowMZSM" />
+</template>
+
+<style lang="scss" scoped>
+.report-detail-page {
+  padding: var(--page-padding);
+  .title-box {
+    font-size: 36px;
+    line-height: 44px;
+    margin-bottom: 20px;
+  }
+  .time-box {
+    margin-top: 10px;
+    font-size: var(--font-size-small);
+    color: var(--text-color-grey);
+    .btn {
+      float: right;
+      color: var(--primary-color);
+    }
+  }
+  .des-box {
+    background-color: #f8f8f8;
+    padding: 20px;
+    margin: 20px 0;
+    display: flex;
+    gap: 0 10px;
+    color: --text-color-sub;
+    font-size: var(--font-size-small);
+    line-height: 36px;
+  }
+  .report-content-box {
+    line-height: 1.8;
+    font-size: 36px;
+    :deep(img) {
+      width: 100% !important;
+    }
+    :deep(span) {
+      font-size: 36px !important;
+      line-height: 1.8 !important;
+      background-color: rgba(255, 255, 255, 0) !important;
+    }
+    :deep(p) {
+      font-size: 36px !important;
+      line-height: 1.8 !important;
+      background-color: rgba(255, 255, 255, 0) !important;
+    }
+    :deep(ul) {
+      font-size: 36px !important;
+      line-height: 1.8 !important;
+      background-color: rgba(255, 255, 255, 0) !important;
+    }
+    :deep(ol) {
+      font-size: 36px !important;
+      line-height: 1.8 !important;
+      background-color: rgba(255, 255, 255, 0) !important;
+    }
+    :deep(iframe) {
+      width: 100% !important;
+    }
+    :deep(li) {
+      font-size: 36px !important;
+      line-height: 1.8 !important;
+      background-color: rgba(255, 255, 255, 0) !important;
+      list-style: inherit !important;
+      list-style-position: inside !important;
+    }
+    :deep(span.fr-emoticon) {
+      width: 36px !important;
+      height: 36px !important;
+      background-repeat: no-repeat !important;
+      background-size: cover !important;
+      display: inline-block !important;
+      vertical-align: middle !important;
+    }
+  }
+  .right-fix-box {
+    position: fixed;
+    z-index: 99;
+    right: 34px;
+    bottom: 130px;
+    .item {
+      margin-top: 10px;
+    }
+    .back-top-img {
+      width: 100px;
+      height: 100px;
+      display: block;
+    }
+    .collect-icon {
+      width: 100px;
+      height: 100px;
+      display: block;
+    }
+  }
+}
+.no-auth-wrap {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 99;
+  .opcity-box {
+    height: 129px;
+    background: linear-gradient(
+      360deg,
+      #ffffff 0%,
+      rgba(255, 255, 255, 0) 100%
+    );
+  }
+  .content-box {
+    background-color: #fff;
+    padding-bottom: 200px;
+    text-align: center;
+    color: var(--primary-color);
+  }
+
+  .icon {
+    display: block;
+    margin: 0 auto;
+    width: 200px;
+    height: 200px;
+  }
+}
+</style>

+ 79 - 0
vite.config.js

@@ -0,0 +1,79 @@
+import { defineConfig, loadEnv } from "vite";
+import vue from "@vitejs/plugin-vue";
+import path from "path";
+import Icons from "unplugin-icons/vite";
+import IconsResolver from "unplugin-icons/resolver";
+import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
+import AutoImport from 'unplugin-auto-import/vite';
+import Components from 'unplugin-vue-components/vite';
+import { TDesignResolver } from 'unplugin-vue-components/resolvers';
+
+// https://vitejs.dev/config/
+export default defineConfig(({ mode }) => {
+  const ENV = loadEnv(mode, process.cwd());
+
+  return {
+    base: ENV.VITE_APP_BASE_URL, // 若服务器不是将该项目放在根目录的则 需要此设置 和服务器上同名
+    plugins: [
+      vue(),
+      AutoImport({
+        // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
+        imports: ["vue"],
+        resolvers: [TDesignResolver({
+          library: 'mobile-vue'
+        })],
+      }),
+      Components({
+        resolvers: [TDesignResolver({
+          library: 'mobile-vue'
+        })],
+      }),
+
+      createSvgIconsPlugin({
+        // 指定需要缓存的图标文件夹
+        iconDirs: [path.resolve(process.cwd(), "src/assets/svg")],
+        // 指定symbolId格式
+        symbolId: "[name]",
+        /**
+         * 自定义插入位置
+         * @default: body-last
+         */
+        // inject?: 'body-last' | 'body-first'
+
+        /**
+         * custom dom id
+         * @default: __svg__icons__dom__
+         */
+        // customDomId: '__svg__icons__dom__'
+      }),
+    ],
+    css: {
+      // css预处理器
+      preprocessorOptions: {
+        scss: {
+          // 定义全局的scss变量
+          // 给导入的路径最后加上 ;
+          // additionalData: `@import '@/styles/var.scss';`,
+        },
+      },
+    },
+    resolve: {
+      alias: {
+        "@": path.resolve(__dirname, "./src"),
+      },
+    },
+    build: {
+      outDir: ENV.VITE_APP_OUTDIR,
+    },
+    server: {
+      port: 8707,
+      proxy: {
+        "/v1": {
+          target: "http://8.136.199.33:8705/adminapi",
+          changeOrigin: true,
+          rewrite: (path) => path.replace(/^\/v1/, ""),
+        },
+      },
+    },
+  };
+});