From 076844f4c54c75350e8354ad10cd125f98e86458 Mon Sep 17 00:00:00 2001
From: Junjie <540245094@qq.com>
Date: 星期一, 01 七月 2024 15:41:08 +0800
Subject: [PATCH] #

---
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java                   |   12 
 zy-asrs-admin/package-lock.json                                                    | 3466 ++++++++++++++++++++++++++++++
 zy-asrs-admin/src/assets/main.css                                                  |  139 +
 zy-asrs-admin/.gitignore                                                           |   30 
 zy-asrs-admin/vite.config.js                                                       |   18 
 zy-asrs-admin/src/views/HomeView.vue                                               |   14 
 zy-asrs-framework/src/main/resources/templates/vue/Sql.txt                         |    9 
 zy-asrs-framework/src/main/resources/templates/vue/ServiceImpl.txt                 |   12 
 zy-asrs-framework/src/main/resources/templates/vue/Index.txt                       |  181 +
 zy-asrs-admin/package.json                                                         |   24 
 zy-asrs-framework/src/main/resources/templates/vue/Service.txt                     |    8 
 zy-asrs-admin/public/img/logo.png                                                  |    0 
 zy-asrs-admin/public/img/bg1.png                                                   |    0 
 zy-asrs-admin/src/views/system/userLogin/edit.vue                                  |   92 
 zy-asrs-framework/src/main/resources/templates/vue/Mapper.txt                      |   12 
 zy-asrs-framework/src/main/resources/templates/vue/Controller.txt                  |  101 
 zy-asrs-admin/src/locales/en_US.js                                                 |  131 +
 zy-asrs-admin/public/img/weixin_qrcode.jpg                                         |    0 
 zy-asrs-framework/src/main/resources/templates/vue/Xml.txt                         |    5 
 zy-asrs-admin/jsconfig.json                                                        |    8 
 zy-asrs-admin/public/img/login-bg.mp4                                              |    0 
 zy-asrs-framework/src/main/resources/templates/vue/Entity.txt                      |   26 
 zy-asrs-admin/src/main.js                                                          |   15 
 zy-asrs-admin/src/utils/localeUtils.js                                             |   19 
 zy-asrs-framework/src/main/resources/templates/vue/Edit.txt                        |   72 
 zy-asrs-admin/public/favicon.ico                                                   |    0 
 zy-asrs-admin/src/stores/counter.js                                                |   12 
 zy-asrs-admin/src/utils/request.js                                                 |   43 
 zy-asrs-wms/src/main/java/user.sql                                                 |    9 
 zy-asrs-admin/src/views/login/LoginView.vue                                        |  273 ++
 zy-asrs-admin/README.md                                                            |   29 
 zy-asrs-admin/src/locales/map.js                                                   |  177 +
 zy-asrs-admin/src/config.js                                                        |   15 
 zy-asrs-admin/src/assets/logo.svg                                                  |    1 
 zy-asrs-admin/index.html                                                           |   13 
 zy-asrs-admin/src/assets/base.css                                                  |   37 
 zy-asrs-admin/src/views/system/userLogin/index.vue                                 |  211 +
 zy-asrs-admin/.vscode/extensions.json                                              |    3 
 zy-asrs-admin/src/App.vue                                                          |   40 
 zy-asrs-admin/src/views/IndexView.vue                                              |  190 +
 zy-asrs-admin/src/locales/zh_CN.js                                                 |    4 
 zy-asrs-framework/src/main/java/com/zy/asrs/framework/generators/VueGenerator.java |  955 ++++++++
 zy-asrs-admin/src/views/system/menu/index.vue                                      |  134 +
 zy-asrs-admin/src/router/index.js                                                  |   42 
 zy-asrs-admin/src/views/system/menu/edit.vue                                       |  105 
 45 files changed, 6,681 insertions(+), 6 deletions(-)

diff --git a/zy-asrs-admin/.gitignore b/zy-asrs-admin/.gitignore
new file mode 100644
index 0000000..8ee54e8
--- /dev/null
+++ b/zy-asrs-admin/.gitignore
@@ -0,0 +1,30 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/zy-asrs-admin/.vscode/extensions.json b/zy-asrs-admin/.vscode/extensions.json
new file mode 100644
index 0000000..a7cea0b
--- /dev/null
+++ b/zy-asrs-admin/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar"]
+}
diff --git a/zy-asrs-admin/README.md b/zy-asrs-admin/README.md
new file mode 100644
index 0000000..7c515d1
--- /dev/null
+++ b/zy-asrs-admin/README.md
@@ -0,0 +1,29 @@
+# zy-asrs-admin
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+npm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+npm run dev
+```
+
+### Compile and Minify for Production
+
+```sh
+npm run build
+```
diff --git a/zy-asrs-admin/index.html b/zy-asrs-admin/index.html
new file mode 100644
index 0000000..99f583a
--- /dev/null
+++ b/zy-asrs-admin/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8">
+    <link rel="icon" href="/favicon.ico">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Vite App</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>
diff --git a/zy-asrs-admin/jsconfig.json b/zy-asrs-admin/jsconfig.json
new file mode 100644
index 0000000..5a1f2d2
--- /dev/null
+++ b/zy-asrs-admin/jsconfig.json
@@ -0,0 +1,8 @@
+{
+  "compilerOptions": {
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}
diff --git a/zy-asrs-admin/package-lock.json b/zy-asrs-admin/package-lock.json
new file mode 100644
index 0000000..61d399e
--- /dev/null
+++ b/zy-asrs-admin/package-lock.json
@@ -0,0 +1,3466 @@
+{
+  "name": "zy-asrs-admin",
+  "version": "0.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "zy-asrs-admin",
+      "version": "0.0.0",
+      "dependencies": {
+        "@ant-design/icons-vue": "^7.0.1",
+        "@vitejs/plugin-vue-jsx": "^4.0.0",
+        "ant-design-vue": "^4.2.3",
+        "axios": "^1.7.2",
+        "pinia": "^2.1.7",
+        "vue": "^3.4.29",
+        "vue-router": "^4.3.3"
+      },
+      "devDependencies": {
+        "@vitejs/plugin-vue": "^5.0.5",
+        "vite": "^5.3.1"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@ant-design/colors": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
+      "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.4.0"
+      }
+    },
+    "node_modules/@ant-design/icons-svg": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz",
+      "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA=="
+    },
+    "node_modules/@ant-design/icons-vue": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz",
+      "integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==",
+      "dependencies": {
+        "@ant-design/colors": "^6.0.0",
+        "@ant-design/icons-svg": "^4.2.1"
+      },
+      "peerDependencies": {
+        "vue": ">=3.0.3"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+      "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+      "dependencies": {
+        "@babel/highlight": "^7.24.7",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz",
+      "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
+      "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.24.7",
+        "@babel/generator": "^7.24.7",
+        "@babel/helper-compilation-targets": "^7.24.7",
+        "@babel/helper-module-transforms": "^7.24.7",
+        "@babel/helpers": "^7.24.7",
+        "@babel/parser": "^7.24.7",
+        "@babel/template": "^7.24.7",
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz",
+      "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==",
+      "dependencies": {
+        "@babel/types": "^7.24.7",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^2.5.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
+      "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
+      "dependencies": {
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz",
+      "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==",
+      "dependencies": {
+        "@babel/compat-data": "^7.24.7",
+        "@babel/helper-validator-option": "^7.24.7",
+        "browserslist": "^4.22.2",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz",
+      "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.24.7",
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-function-name": "^7.24.7",
+        "@babel/helper-member-expression-to-functions": "^7.24.7",
+        "@babel/helper-optimise-call-expression": "^7.24.7",
+        "@babel/helper-replace-supers": "^7.24.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+        "@babel/helper-split-export-declaration": "^7.24.7",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-environment-visitor": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
+      "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
+      "dependencies": {
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-function-name": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
+      "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
+      "dependencies": {
+        "@babel/template": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-hoist-variables": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
+      "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
+      "dependencies": {
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-member-expression-to-functions": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz",
+      "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==",
+      "dependencies": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+      "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+      "dependencies": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz",
+      "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==",
+      "dependencies": {
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-module-imports": "^7.24.7",
+        "@babel/helper-simple-access": "^7.24.7",
+        "@babel/helper-split-export-declaration": "^7.24.7",
+        "@babel/helper-validator-identifier": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-optimise-call-expression": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
+      "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
+      "dependencies": {
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz",
+      "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-replace-supers": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz",
+      "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==",
+      "dependencies": {
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-member-expression-to-functions": "^7.24.7",
+        "@babel/helper-optimise-call-expression": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-simple-access": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+      "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+      "dependencies": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
+      "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
+      "dependencies": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-split-export-declaration": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
+      "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
+      "dependencies": {
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
+      "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+      "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz",
+      "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz",
+      "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==",
+      "dependencies": {
+        "@babel/template": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+      "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.24.7",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
+      "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-jsx": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
+      "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-typescript": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz",
+      "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-typescript": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz",
+      "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.24.7",
+        "@babel/helper-create-class-features-plugin": "^7.24.7",
+        "@babel/helper-plugin-utils": "^7.24.7",
+        "@babel/plugin-syntax-typescript": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
+      "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
+      "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
+      "dependencies": {
+        "@babel/code-frame": "^7.24.7",
+        "@babel/parser": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz",
+      "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==",
+      "dependencies": {
+        "@babel/code-frame": "^7.24.7",
+        "@babel/generator": "^7.24.7",
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-function-name": "^7.24.7",
+        "@babel/helper-hoist-variables": "^7.24.7",
+        "@babel/helper-split-export-declaration": "^7.24.7",
+        "@babel/parser": "^7.24.7",
+        "@babel/types": "^7.24.7",
+        "debug": "^4.3.1",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
+      "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.24.7",
+        "@babel/helper-validator-identifier": "^7.24.7",
+        "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@ctrl/tinycolor": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+      "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@emotion/hash": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
+      "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
+    },
+    "node_modules/@emotion/unitless": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+      "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+      "cpu": [
+        "loong64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+      "cpu": [
+        "mips64el"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+      "cpu": [
+        "s390x"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+      "dependencies": {
+        "@jridgewell/set-array": "^1.2.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
+      "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
+      "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
+      "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
+      "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
+      "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
+      "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
+      "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
+      "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
+      "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
+      "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
+      "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+      "cpu": [
+        "s390x"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
+      "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
+      "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
+      "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
+      "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
+      "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@simonwep/pickr": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz",
+      "integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==",
+      "dependencies": {
+        "core-js": "^3.15.1",
+        "nanopop": "^2.1.0"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+    },
+    "node_modules/@vitejs/plugin-vue": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz",
+      "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==",
+      "dev": true,
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^5.0.0",
+        "vue": "^3.2.25"
+      }
+    },
+    "node_modules/@vitejs/plugin-vue-jsx": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-4.0.0.tgz",
+      "integrity": "sha512-A+6wL2AdQhDsLsDnY+2v4rRDI1HLJGIMc97a8FURO9tqKsH5QvjWrzsa5DH3NlZsM742W2wODl2fF+bfcTWtXw==",
+      "dependencies": {
+        "@babel/core": "^7.24.6",
+        "@babel/plugin-transform-typescript": "^7.24.6",
+        "@vue/babel-plugin-jsx": "^1.2.2"
+      },
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^5.0.0",
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/@vue/babel-helper-vue-transform-on": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.2.tgz",
+      "integrity": "sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw=="
+    },
+    "node_modules/@vue/babel-plugin-jsx": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.2.tgz",
+      "integrity": "sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==",
+      "dependencies": {
+        "@babel/helper-module-imports": "~7.22.15",
+        "@babel/helper-plugin-utils": "^7.22.5",
+        "@babel/plugin-syntax-jsx": "^7.23.3",
+        "@babel/template": "^7.23.9",
+        "@babel/traverse": "^7.23.9",
+        "@babel/types": "^7.23.9",
+        "@vue/babel-helper-vue-transform-on": "1.2.2",
+        "@vue/babel-plugin-resolve-type": "1.2.2",
+        "camelcase": "^6.3.0",
+        "html-tags": "^3.3.1",
+        "svg-tags": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      },
+      "peerDependenciesMeta": {
+        "@babel/core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/babel-plugin-jsx/node_modules/@babel/helper-module-imports": {
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+      "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+      "dependencies": {
+        "@babel/types": "^7.22.15"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.2.tgz",
+      "integrity": "sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==",
+      "dependencies": {
+        "@babel/code-frame": "^7.23.5",
+        "@babel/helper-module-imports": "~7.22.15",
+        "@babel/helper-plugin-utils": "^7.22.5",
+        "@babel/parser": "^7.23.9",
+        "@vue/compiler-sfc": "^3.4.15"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@babel/helper-module-imports": {
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+      "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+      "dependencies": {
+        "@babel/types": "^7.22.15"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.30.tgz",
+      "integrity": "sha512-ZL8y4Xxdh8O6PSwfdZ1IpQ24PjTAieOz3jXb/MDTfDtANcKBMxg1KLm6OX2jofsaQGYfIVzd3BAG22i56/cF1w==",
+      "dependencies": {
+        "@babel/parser": "^7.24.7",
+        "@vue/shared": "3.4.30",
+        "entities": "^4.5.0",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.30.tgz",
+      "integrity": "sha512-+16Sd8lYr5j/owCbr9dowcNfrHd+pz+w2/b5Lt26Oz/kB90C9yNbxQ3bYOvt7rI2bxk0nqda39hVcwDFw85c2Q==",
+      "dependencies": {
+        "@vue/compiler-core": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.30.tgz",
+      "integrity": "sha512-8vElKklHn/UY8+FgUFlQrYAPbtiSB2zcgeRKW7HkpSRn/JjMRmZvuOtwDx036D1aqKNSTtXkWRfqx53Qb+HmMg==",
+      "dependencies": {
+        "@babel/parser": "^7.24.7",
+        "@vue/compiler-core": "3.4.30",
+        "@vue/compiler-dom": "3.4.30",
+        "@vue/compiler-ssr": "3.4.30",
+        "@vue/shared": "3.4.30",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.10",
+        "postcss": "^8.4.38",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.30.tgz",
+      "integrity": "sha512-ZJ56YZGXJDd6jky4mmM0rNaNP6kIbQu9LTKZDhcpddGe/3QIalB1WHHmZ6iZfFNyj5mSypTa4+qDJa5VIuxMSg==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "node_modules/@vue/devtools-api": {
+      "version": "6.6.3",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.3.tgz",
+      "integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw=="
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.30.tgz",
+      "integrity": "sha512-bVJurnCe3LS0JII8PPoAA63Zd2MBzcKrEzwdQl92eHCcxtIbxD2fhNwJpa+KkM3Y/A4T5FUnmdhgKwOf6BfbcA==",
+      "dependencies": {
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.30.tgz",
+      "integrity": "sha512-qaFEbnNpGz+tlnkaualomogzN8vBLkgzK55uuWjYXbYn039eOBZrWxyXWq/7qh9Bz2FPifZqGjVDl/FXiq9L2g==",
+      "dependencies": {
+        "@vue/reactivity": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.30.tgz",
+      "integrity": "sha512-tV6B4YiZRj5QsaJgw2THCy5C1H+2UeywO9tqgWEc21tn85qHEERndHN/CxlyXvSBFrpmlexCIdnqPuR9RM9thw==",
+      "dependencies": {
+        "@vue/reactivity": "3.4.30",
+        "@vue/runtime-core": "3.4.30",
+        "@vue/shared": "3.4.30",
+        "csstype": "^3.1.3"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.30.tgz",
+      "integrity": "sha512-TBD3eqR1DeDc0cMrXS/vEs/PWzq1uXxnvjoqQuDGFIEHFIwuDTX/KWAQKIBjyMWLFHEeTDGYVsYci85z2UbTDg==",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.4.30",
+        "@vue/shared": "3.4.30"
+      },
+      "peerDependencies": {
+        "vue": "3.4.30"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.30.tgz",
+      "integrity": "sha512-CLg+f8RQCHQnKvuHY9adMsMaQOcqclh6Z5V9TaoMgy0ut0tz848joZ7/CYFFyF/yZ5i2yaw7Fn498C+CNZVHIg=="
+    },
+    "node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ant-design-vue": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.3.tgz",
+      "integrity": "sha512-kqGyWvZtFlSInFP93Ow6wS8LzEsxxUgpI+ZY5jQQkuX8WAcqdwXCA7IcHMpECW6JB89DZMo2Bw85jUg2SjlgQA==",
+      "dependencies": {
+        "@ant-design/colors": "^6.0.0",
+        "@ant-design/icons-vue": "^7.0.0",
+        "@babel/runtime": "^7.10.5",
+        "@ctrl/tinycolor": "^3.5.0",
+        "@emotion/hash": "^0.9.0",
+        "@emotion/unitless": "^0.8.0",
+        "@simonwep/pickr": "~1.8.0",
+        "array-tree-filter": "^2.1.0",
+        "async-validator": "^4.0.0",
+        "csstype": "^3.1.1",
+        "dayjs": "^1.10.5",
+        "dom-align": "^1.12.1",
+        "dom-scroll-into-view": "^2.0.0",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.15",
+        "resize-observer-polyfill": "^1.5.1",
+        "scroll-into-view-if-needed": "^2.2.25",
+        "shallow-equal": "^1.0.0",
+        "stylis": "^4.1.3",
+        "throttle-debounce": "^5.0.0",
+        "vue-types": "^3.0.0",
+        "warning": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=12.22.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/ant-design-vue"
+      },
+      "peerDependencies": {
+        "vue": ">=3.2.0"
+      }
+    },
+    "node_modules/array-tree-filter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
+      "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw=="
+    },
+    "node_modules/async-validator": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/axios": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.23.1",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
+      "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "caniuse-lite": "^1.0.30001629",
+        "electron-to-chromium": "^1.4.796",
+        "node-releases": "^2.0.14",
+        "update-browserslist-db": "^1.0.16"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/camelcase": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001638",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz",
+      "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ]
+    },
+    "node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/compute-scroll-into-view": {
+      "version": "1.0.20",
+      "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
+      "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
+    },
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
+    },
+    "node_modules/core-js": {
+      "version": "3.37.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz",
+      "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==",
+      "hasInstallScript": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+    },
+    "node_modules/dayjs": {
+      "version": "1.11.11",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz",
+      "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg=="
+    },
+    "node_modules/debug": {
+      "version": "4.3.5",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+      "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/dom-align": {
+      "version": "1.12.4",
+      "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz",
+      "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw=="
+    },
+    "node_modules/dom-scroll-into-view": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
+      "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w=="
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.4.812",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz",
+      "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg=="
+    },
+    "node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.21.5",
+        "@esbuild/android-arm": "0.21.5",
+        "@esbuild/android-arm64": "0.21.5",
+        "@esbuild/android-x64": "0.21.5",
+        "@esbuild/darwin-arm64": "0.21.5",
+        "@esbuild/darwin-x64": "0.21.5",
+        "@esbuild/freebsd-arm64": "0.21.5",
+        "@esbuild/freebsd-x64": "0.21.5",
+        "@esbuild/linux-arm": "0.21.5",
+        "@esbuild/linux-arm64": "0.21.5",
+        "@esbuild/linux-ia32": "0.21.5",
+        "@esbuild/linux-loong64": "0.21.5",
+        "@esbuild/linux-mips64el": "0.21.5",
+        "@esbuild/linux-ppc64": "0.21.5",
+        "@esbuild/linux-riscv64": "0.21.5",
+        "@esbuild/linux-s390x": "0.21.5",
+        "@esbuild/linux-x64": "0.21.5",
+        "@esbuild/netbsd-x64": "0.21.5",
+        "@esbuild/openbsd-x64": "0.21.5",
+        "@esbuild/sunos-x64": "0.21.5",
+        "@esbuild/win32-arm64": "0.21.5",
+        "@esbuild/win32-ia32": "0.21.5",
+        "@esbuild/win32-x64": "0.21.5"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/html-tags": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
+      "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
+      "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "node_modules/jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.30.10",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
+      "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.4.15"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/nanopop": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz",
+      "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw=="
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+      "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+      "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
+    },
+    "node_modules/pinia": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
+      "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.5.0",
+        "vue-demi": ">=0.14.5"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.4.0",
+        "typescript": ">=4.4.4",
+        "vue": "^2.6.14 || ^3.3.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pinia/node_modules/vue-demi": {
+      "version": "0.14.8",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
+      "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.4.38",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
+    "node_modules/resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
+    "node_modules/rollup": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
+      "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+      "dependencies": {
+        "@types/estree": "1.0.5"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "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.2"
+      }
+    },
+    "node_modules/scroll-into-view-if-needed": {
+      "version": "2.2.31",
+      "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
+      "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
+      "dependencies": {
+        "compute-scroll-into-view": "^1.0.20"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/shallow-equal": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
+      "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/stylis": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
+      "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg=="
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/svg-tags": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+      "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA=="
+    },
+    "node_modules/throttle-debounce": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
+      "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
+      "engines": {
+        "node": ">=12.22"
+      }
+    },
+    "node_modules/to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
+      "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.1.2",
+        "picocolors": "^1.0.1"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/vite": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz",
+      "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==",
+      "dependencies": {
+        "esbuild": "^0.21.3",
+        "postcss": "^8.4.38",
+        "rollup": "^4.13.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "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
+        }
+      }
+    },
+    "node_modules/vue": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.30.tgz",
+      "integrity": "sha512-NcxtKCwkdf1zPsr7Y8+QlDBCGqxvjLXF2EX+yi76rV5rrz90Y6gK1cq0olIhdWGgrlhs9ElHuhi9t3+W5sG5Xw==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.4.30",
+        "@vue/compiler-sfc": "3.4.30",
+        "@vue/runtime-dom": "3.4.30",
+        "@vue/server-renderer": "3.4.30",
+        "@vue/shared": "3.4.30"
+      },
+      "peerDependencies": {
+        "typescript": "*"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-router": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.0.tgz",
+      "integrity": "sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.5.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/vue-types": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz",
+      "integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==",
+      "dependencies": {
+        "is-plain-object": "3.0.1"
+      },
+      "engines": {
+        "node": ">=10.15.0"
+      },
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/warning": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+      "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+      "dependencies": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+    }
+  },
+  "dependencies": {
+    "@ampproject/remapping": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+      "requires": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "@ant-design/colors": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
+      "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
+      "requires": {
+        "@ctrl/tinycolor": "^3.4.0"
+      }
+    },
+    "@ant-design/icons-svg": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz",
+      "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA=="
+    },
+    "@ant-design/icons-vue": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz",
+      "integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==",
+      "requires": {
+        "@ant-design/colors": "^6.0.0",
+        "@ant-design/icons-svg": "^4.2.1"
+      }
+    },
+    "@babel/code-frame": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+      "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+      "requires": {
+        "@babel/highlight": "^7.24.7",
+        "picocolors": "^1.0.0"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz",
+      "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw=="
+    },
+    "@babel/core": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
+      "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
+      "requires": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.24.7",
+        "@babel/generator": "^7.24.7",
+        "@babel/helper-compilation-targets": "^7.24.7",
+        "@babel/helper-module-transforms": "^7.24.7",
+        "@babel/helpers": "^7.24.7",
+        "@babel/parser": "^7.24.7",
+        "@babel/template": "^7.24.7",
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      }
+    },
+    "@babel/generator": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz",
+      "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==",
+      "requires": {
+        "@babel/types": "^7.24.7",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^2.5.1"
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
+      "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
+      "requires": {
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz",
+      "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==",
+      "requires": {
+        "@babel/compat-data": "^7.24.7",
+        "@babel/helper-validator-option": "^7.24.7",
+        "browserslist": "^4.22.2",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      }
+    },
+    "@babel/helper-create-class-features-plugin": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz",
+      "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==",
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.24.7",
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-function-name": "^7.24.7",
+        "@babel/helper-member-expression-to-functions": "^7.24.7",
+        "@babel/helper-optimise-call-expression": "^7.24.7",
+        "@babel/helper-replace-supers": "^7.24.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+        "@babel/helper-split-export-declaration": "^7.24.7",
+        "semver": "^6.3.1"
+      }
+    },
+    "@babel/helper-environment-visitor": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
+      "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
+      "requires": {
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
+      "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
+      "requires": {
+        "@babel/template": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
+      "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
+      "requires": {
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz",
+      "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==",
+      "requires": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+      "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+      "requires": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz",
+      "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==",
+      "requires": {
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-module-imports": "^7.24.7",
+        "@babel/helper-simple-access": "^7.24.7",
+        "@babel/helper-split-export-declaration": "^7.24.7",
+        "@babel/helper-validator-identifier": "^7.24.7"
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
+      "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
+      "requires": {
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz",
+      "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg=="
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz",
+      "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==",
+      "requires": {
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-member-expression-to-functions": "^7.24.7",
+        "@babel/helper-optimise-call-expression": "^7.24.7"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+      "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+      "requires": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
+      "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
+      "requires": {
+        "@babel/traverse": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
+      "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
+      "requires": {
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/helper-string-parser": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
+      "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg=="
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+      "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w=="
+    },
+    "@babel/helper-validator-option": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz",
+      "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw=="
+    },
+    "@babel/helpers": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz",
+      "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==",
+      "requires": {
+        "@babel/template": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+      "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.24.7",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
+      "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw=="
+    },
+    "@babel/plugin-syntax-jsx": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
+      "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.24.7"
+      }
+    },
+    "@babel/plugin-syntax-typescript": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz",
+      "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==",
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.24.7"
+      }
+    },
+    "@babel/plugin-transform-typescript": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz",
+      "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==",
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.24.7",
+        "@babel/helper-create-class-features-plugin": "^7.24.7",
+        "@babel/helper-plugin-utils": "^7.24.7",
+        "@babel/plugin-syntax-typescript": "^7.24.7"
+      }
+    },
+    "@babel/runtime": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
+      "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
+      "requires": {
+        "regenerator-runtime": "^0.14.0"
+      }
+    },
+    "@babel/template": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
+      "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
+      "requires": {
+        "@babel/code-frame": "^7.24.7",
+        "@babel/parser": "^7.24.7",
+        "@babel/types": "^7.24.7"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz",
+      "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==",
+      "requires": {
+        "@babel/code-frame": "^7.24.7",
+        "@babel/generator": "^7.24.7",
+        "@babel/helper-environment-visitor": "^7.24.7",
+        "@babel/helper-function-name": "^7.24.7",
+        "@babel/helper-hoist-variables": "^7.24.7",
+        "@babel/helper-split-export-declaration": "^7.24.7",
+        "@babel/parser": "^7.24.7",
+        "@babel/types": "^7.24.7",
+        "debug": "^4.3.1",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/types": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
+      "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
+      "requires": {
+        "@babel/helper-string-parser": "^7.24.7",
+        "@babel/helper-validator-identifier": "^7.24.7",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@ctrl/tinycolor": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+      "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA=="
+    },
+    "@emotion/hash": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
+      "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
+    },
+    "@emotion/unitless": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+      "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
+    },
+    "@esbuild/aix-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+      "optional": true
+    },
+    "@esbuild/android-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+      "optional": true
+    },
+    "@esbuild/android-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+      "optional": true
+    },
+    "@esbuild/android-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+      "optional": true
+    },
+    "@esbuild/darwin-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+      "optional": true
+    },
+    "@esbuild/darwin-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+      "optional": true
+    },
+    "@esbuild/freebsd-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+      "optional": true
+    },
+    "@esbuild/freebsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+      "optional": true
+    },
+    "@esbuild/linux-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+      "optional": true
+    },
+    "@esbuild/linux-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+      "optional": true
+    },
+    "@esbuild/linux-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+      "optional": true
+    },
+    "@esbuild/linux-loong64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+      "optional": true
+    },
+    "@esbuild/linux-mips64el": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+      "optional": true
+    },
+    "@esbuild/linux-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+      "optional": true
+    },
+    "@esbuild/linux-riscv64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+      "optional": true
+    },
+    "@esbuild/linux-s390x": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+      "optional": true
+    },
+    "@esbuild/linux-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+      "optional": true
+    },
+    "@esbuild/netbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+      "optional": true
+    },
+    "@esbuild/openbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+      "optional": true
+    },
+    "@esbuild/sunos-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+      "optional": true
+    },
+    "@esbuild/win32-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+      "optional": true
+    },
+    "@esbuild/win32-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+      "optional": true
+    },
+    "@esbuild/win32-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+      "optional": true
+    },
+    "@jridgewell/gen-mapping": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+      "requires": {
+        "@jridgewell/set-array": "^1.2.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="
+    },
+    "@jridgewell/set-array": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="
+    },
+    "@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+    },
+    "@jridgewell/trace-mapping": {
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+      "requires": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "@rollup/rollup-android-arm-eabi": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
+      "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+      "optional": true
+    },
+    "@rollup/rollup-android-arm64": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
+      "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+      "optional": true
+    },
+    "@rollup/rollup-darwin-arm64": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
+      "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+      "optional": true
+    },
+    "@rollup/rollup-darwin-x64": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
+      "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
+      "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
+      "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
+      "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-arm64-musl": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
+      "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
+      "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
+      "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
+      "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-x64-gnu": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
+      "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+      "optional": true
+    },
+    "@rollup/rollup-linux-x64-musl": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
+      "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+      "optional": true
+    },
+    "@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
+      "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+      "optional": true
+    },
+    "@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
+      "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+      "optional": true
+    },
+    "@rollup/rollup-win32-x64-msvc": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
+      "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+      "optional": true
+    },
+    "@simonwep/pickr": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz",
+      "integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==",
+      "requires": {
+        "core-js": "^3.15.1",
+        "nanopop": "^2.1.0"
+      }
+    },
+    "@types/estree": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+    },
+    "@vitejs/plugin-vue": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz",
+      "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==",
+      "dev": true,
+      "requires": {}
+    },
+    "@vitejs/plugin-vue-jsx": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-4.0.0.tgz",
+      "integrity": "sha512-A+6wL2AdQhDsLsDnY+2v4rRDI1HLJGIMc97a8FURO9tqKsH5QvjWrzsa5DH3NlZsM742W2wODl2fF+bfcTWtXw==",
+      "requires": {
+        "@babel/core": "^7.24.6",
+        "@babel/plugin-transform-typescript": "^7.24.6",
+        "@vue/babel-plugin-jsx": "^1.2.2"
+      }
+    },
+    "@vue/babel-helper-vue-transform-on": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.2.tgz",
+      "integrity": "sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw=="
+    },
+    "@vue/babel-plugin-jsx": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.2.tgz",
+      "integrity": "sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==",
+      "requires": {
+        "@babel/helper-module-imports": "~7.22.15",
+        "@babel/helper-plugin-utils": "^7.22.5",
+        "@babel/plugin-syntax-jsx": "^7.23.3",
+        "@babel/template": "^7.23.9",
+        "@babel/traverse": "^7.23.9",
+        "@babel/types": "^7.23.9",
+        "@vue/babel-helper-vue-transform-on": "1.2.2",
+        "@vue/babel-plugin-resolve-type": "1.2.2",
+        "camelcase": "^6.3.0",
+        "html-tags": "^3.3.1",
+        "svg-tags": "^1.0.0"
+      },
+      "dependencies": {
+        "@babel/helper-module-imports": {
+          "version": "7.22.15",
+          "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+          "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+          "requires": {
+            "@babel/types": "^7.22.15"
+          }
+        }
+      }
+    },
+    "@vue/babel-plugin-resolve-type": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.2.tgz",
+      "integrity": "sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==",
+      "requires": {
+        "@babel/code-frame": "^7.23.5",
+        "@babel/helper-module-imports": "~7.22.15",
+        "@babel/helper-plugin-utils": "^7.22.5",
+        "@babel/parser": "^7.23.9",
+        "@vue/compiler-sfc": "^3.4.15"
+      },
+      "dependencies": {
+        "@babel/helper-module-imports": {
+          "version": "7.22.15",
+          "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+          "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+          "requires": {
+            "@babel/types": "^7.22.15"
+          }
+        }
+      }
+    },
+    "@vue/compiler-core": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.30.tgz",
+      "integrity": "sha512-ZL8y4Xxdh8O6PSwfdZ1IpQ24PjTAieOz3jXb/MDTfDtANcKBMxg1KLm6OX2jofsaQGYfIVzd3BAG22i56/cF1w==",
+      "requires": {
+        "@babel/parser": "^7.24.7",
+        "@vue/shared": "3.4.30",
+        "entities": "^4.5.0",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "@vue/compiler-dom": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.30.tgz",
+      "integrity": "sha512-+16Sd8lYr5j/owCbr9dowcNfrHd+pz+w2/b5Lt26Oz/kB90C9yNbxQ3bYOvt7rI2bxk0nqda39hVcwDFw85c2Q==",
+      "requires": {
+        "@vue/compiler-core": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "@vue/compiler-sfc": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.30.tgz",
+      "integrity": "sha512-8vElKklHn/UY8+FgUFlQrYAPbtiSB2zcgeRKW7HkpSRn/JjMRmZvuOtwDx036D1aqKNSTtXkWRfqx53Qb+HmMg==",
+      "requires": {
+        "@babel/parser": "^7.24.7",
+        "@vue/compiler-core": "3.4.30",
+        "@vue/compiler-dom": "3.4.30",
+        "@vue/compiler-ssr": "3.4.30",
+        "@vue/shared": "3.4.30",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.10",
+        "postcss": "^8.4.38",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "@vue/compiler-ssr": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.30.tgz",
+      "integrity": "sha512-ZJ56YZGXJDd6jky4mmM0rNaNP6kIbQu9LTKZDhcpddGe/3QIalB1WHHmZ6iZfFNyj5mSypTa4+qDJa5VIuxMSg==",
+      "requires": {
+        "@vue/compiler-dom": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "@vue/devtools-api": {
+      "version": "6.6.3",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.3.tgz",
+      "integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw=="
+    },
+    "@vue/reactivity": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.30.tgz",
+      "integrity": "sha512-bVJurnCe3LS0JII8PPoAA63Zd2MBzcKrEzwdQl92eHCcxtIbxD2fhNwJpa+KkM3Y/A4T5FUnmdhgKwOf6BfbcA==",
+      "requires": {
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "@vue/runtime-core": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.30.tgz",
+      "integrity": "sha512-qaFEbnNpGz+tlnkaualomogzN8vBLkgzK55uuWjYXbYn039eOBZrWxyXWq/7qh9Bz2FPifZqGjVDl/FXiq9L2g==",
+      "requires": {
+        "@vue/reactivity": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "@vue/runtime-dom": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.30.tgz",
+      "integrity": "sha512-tV6B4YiZRj5QsaJgw2THCy5C1H+2UeywO9tqgWEc21tn85qHEERndHN/CxlyXvSBFrpmlexCIdnqPuR9RM9thw==",
+      "requires": {
+        "@vue/reactivity": "3.4.30",
+        "@vue/runtime-core": "3.4.30",
+        "@vue/shared": "3.4.30",
+        "csstype": "^3.1.3"
+      }
+    },
+    "@vue/server-renderer": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.30.tgz",
+      "integrity": "sha512-TBD3eqR1DeDc0cMrXS/vEs/PWzq1uXxnvjoqQuDGFIEHFIwuDTX/KWAQKIBjyMWLFHEeTDGYVsYci85z2UbTDg==",
+      "requires": {
+        "@vue/compiler-ssr": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "@vue/shared": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.30.tgz",
+      "integrity": "sha512-CLg+f8RQCHQnKvuHY9adMsMaQOcqclh6Z5V9TaoMgy0ut0tz848joZ7/CYFFyF/yZ5i2yaw7Fn498C+CNZVHIg=="
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "ant-design-vue": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.3.tgz",
+      "integrity": "sha512-kqGyWvZtFlSInFP93Ow6wS8LzEsxxUgpI+ZY5jQQkuX8WAcqdwXCA7IcHMpECW6JB89DZMo2Bw85jUg2SjlgQA==",
+      "requires": {
+        "@ant-design/colors": "^6.0.0",
+        "@ant-design/icons-vue": "^7.0.0",
+        "@babel/runtime": "^7.10.5",
+        "@ctrl/tinycolor": "^3.5.0",
+        "@emotion/hash": "^0.9.0",
+        "@emotion/unitless": "^0.8.0",
+        "@simonwep/pickr": "~1.8.0",
+        "array-tree-filter": "^2.1.0",
+        "async-validator": "^4.0.0",
+        "csstype": "^3.1.1",
+        "dayjs": "^1.10.5",
+        "dom-align": "^1.12.1",
+        "dom-scroll-into-view": "^2.0.0",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.15",
+        "resize-observer-polyfill": "^1.5.1",
+        "scroll-into-view-if-needed": "^2.2.25",
+        "shallow-equal": "^1.0.0",
+        "stylis": "^4.1.3",
+        "throttle-debounce": "^5.0.0",
+        "vue-types": "^3.0.0",
+        "warning": "^4.0.0"
+      }
+    },
+    "array-tree-filter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
+      "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw=="
+    },
+    "async-validator": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "axios": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+      "requires": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "browserslist": {
+      "version": "4.23.1",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
+      "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
+      "requires": {
+        "caniuse-lite": "^1.0.30001629",
+        "electron-to-chromium": "^1.4.796",
+        "node-releases": "^2.0.14",
+        "update-browserslist-db": "^1.0.16"
+      }
+    },
+    "camelcase": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
+    },
+    "caniuse-lite": {
+      "version": "1.0.30001638",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz",
+      "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ=="
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "compute-scroll-into-view": {
+      "version": "1.0.20",
+      "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
+      "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
+    },
+    "convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
+    },
+    "core-js": {
+      "version": "3.37.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz",
+      "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw=="
+    },
+    "csstype": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+    },
+    "dayjs": {
+      "version": "1.11.11",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz",
+      "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg=="
+    },
+    "debug": {
+      "version": "4.3.5",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+      "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+    },
+    "dom-align": {
+      "version": "1.12.4",
+      "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz",
+      "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw=="
+    },
+    "dom-scroll-into-view": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
+      "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w=="
+    },
+    "electron-to-chromium": {
+      "version": "1.4.812",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz",
+      "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg=="
+    },
+    "entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
+    },
+    "esbuild": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+      "requires": {
+        "@esbuild/aix-ppc64": "0.21.5",
+        "@esbuild/android-arm": "0.21.5",
+        "@esbuild/android-arm64": "0.21.5",
+        "@esbuild/android-x64": "0.21.5",
+        "@esbuild/darwin-arm64": "0.21.5",
+        "@esbuild/darwin-x64": "0.21.5",
+        "@esbuild/freebsd-arm64": "0.21.5",
+        "@esbuild/freebsd-x64": "0.21.5",
+        "@esbuild/linux-arm": "0.21.5",
+        "@esbuild/linux-arm64": "0.21.5",
+        "@esbuild/linux-ia32": "0.21.5",
+        "@esbuild/linux-loong64": "0.21.5",
+        "@esbuild/linux-mips64el": "0.21.5",
+        "@esbuild/linux-ppc64": "0.21.5",
+        "@esbuild/linux-riscv64": "0.21.5",
+        "@esbuild/linux-s390x": "0.21.5",
+        "@esbuild/linux-x64": "0.21.5",
+        "@esbuild/netbsd-x64": "0.21.5",
+        "@esbuild/openbsd-x64": "0.21.5",
+        "@esbuild/sunos-x64": "0.21.5",
+        "@esbuild/win32-arm64": "0.21.5",
+        "@esbuild/win32-ia32": "0.21.5",
+        "@esbuild/win32-x64": "0.21.5"
+      }
+    },
+    "escalade": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA=="
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+    },
+    "estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+    },
+    "follow-redirects": {
+      "version": "1.15.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
+    },
+    "form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "optional": true
+    },
+    "gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
+    },
+    "globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+    },
+    "html-tags": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
+      "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ=="
+    },
+    "is-plain-object": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
+      "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g=="
+    },
+    "js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+    },
+    "json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
+    },
+    "lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "magic-string": {
+      "version": "0.30.10",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
+      "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+      "requires": {
+        "@jridgewell/sourcemap-codec": "^1.4.15"
+      }
+    },
+    "mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+    },
+    "mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "requires": {
+        "mime-db": "1.52.0"
+      }
+    },
+    "ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "nanoid": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
+    },
+    "nanopop": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz",
+      "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw=="
+    },
+    "node-releases": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+      "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
+    },
+    "picocolors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+      "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
+    },
+    "pinia": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
+      "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
+      "requires": {
+        "@vue/devtools-api": "^6.5.0",
+        "vue-demi": ">=0.14.5"
+      },
+      "dependencies": {
+        "vue-demi": {
+          "version": "0.14.8",
+          "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
+          "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
+          "requires": {}
+        }
+      }
+    },
+    "postcss": {
+      "version": "8.4.38",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+      "requires": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
+    "regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
+    "resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
+    "rollup": {
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
+      "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+      "requires": {
+        "@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",
+        "@types/estree": "1.0.5",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "scroll-into-view-if-needed": {
+      "version": "2.2.31",
+      "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
+      "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
+      "requires": {
+        "compute-scroll-into-view": "^1.0.20"
+      }
+    },
+    "semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
+    },
+    "shallow-equal": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
+      "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
+    },
+    "source-map-js": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="
+    },
+    "stylis": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
+      "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg=="
+    },
+    "supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "requires": {
+        "has-flag": "^3.0.0"
+      }
+    },
+    "svg-tags": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+      "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA=="
+    },
+    "throttle-debounce": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
+      "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A=="
+    },
+    "to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
+    },
+    "update-browserslist-db": {
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
+      "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+      "requires": {
+        "escalade": "^3.1.2",
+        "picocolors": "^1.0.1"
+      }
+    },
+    "vite": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz",
+      "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==",
+      "requires": {
+        "esbuild": "^0.21.3",
+        "fsevents": "~2.3.3",
+        "postcss": "^8.4.38",
+        "rollup": "^4.13.0"
+      }
+    },
+    "vue": {
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.30.tgz",
+      "integrity": "sha512-NcxtKCwkdf1zPsr7Y8+QlDBCGqxvjLXF2EX+yi76rV5rrz90Y6gK1cq0olIhdWGgrlhs9ElHuhi9t3+W5sG5Xw==",
+      "requires": {
+        "@vue/compiler-dom": "3.4.30",
+        "@vue/compiler-sfc": "3.4.30",
+        "@vue/runtime-dom": "3.4.30",
+        "@vue/server-renderer": "3.4.30",
+        "@vue/shared": "3.4.30"
+      }
+    },
+    "vue-router": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.0.tgz",
+      "integrity": "sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==",
+      "requires": {
+        "@vue/devtools-api": "^6.5.1"
+      }
+    },
+    "vue-types": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz",
+      "integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==",
+      "requires": {
+        "is-plain-object": "3.0.1"
+      }
+    },
+    "warning": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+      "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+      "requires": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+    }
+  }
+}
diff --git a/zy-asrs-admin/package.json b/zy-asrs-admin/package.json
new file mode 100644
index 0000000..b3f7ed8
--- /dev/null
+++ b/zy-asrs-admin/package.json
@@ -0,0 +1,24 @@
+{
+  "name": "zy-asrs-admin",
+  "version": "0.0.0",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@ant-design/icons-vue": "^7.0.1",
+    "@vitejs/plugin-vue-jsx": "^4.0.0",
+    "ant-design-vue": "^4.2.3",
+    "axios": "^1.7.2",
+    "pinia": "^2.1.7",
+    "vue": "^3.4.29",
+    "vue-router": "^4.3.3"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^5.0.5",
+    "vite": "^5.3.1"
+  }
+}
diff --git a/zy-asrs-admin/public/favicon.ico b/zy-asrs-admin/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
--- /dev/null
+++ b/zy-asrs-admin/public/favicon.ico
Binary files differ
diff --git a/zy-asrs-admin/public/img/bg1.png b/zy-asrs-admin/public/img/bg1.png
new file mode 100644
index 0000000..b371c63
--- /dev/null
+++ b/zy-asrs-admin/public/img/bg1.png
Binary files differ
diff --git a/zy-asrs-admin/public/img/login-bg.mp4 b/zy-asrs-admin/public/img/login-bg.mp4
new file mode 100644
index 0000000..dc982dc
--- /dev/null
+++ b/zy-asrs-admin/public/img/login-bg.mp4
Binary files differ
diff --git a/zy-asrs-admin/public/img/logo.png b/zy-asrs-admin/public/img/logo.png
new file mode 100644
index 0000000..21a19b9
--- /dev/null
+++ b/zy-asrs-admin/public/img/logo.png
Binary files differ
diff --git a/zy-asrs-admin/public/img/weixin_qrcode.jpg b/zy-asrs-admin/public/img/weixin_qrcode.jpg
new file mode 100644
index 0000000..50fedd5
--- /dev/null
+++ b/zy-asrs-admin/public/img/weixin_qrcode.jpg
Binary files differ
diff --git a/zy-asrs-admin/src/App.vue b/zy-asrs-admin/src/App.vue
new file mode 100644
index 0000000..8cdf986
--- /dev/null
+++ b/zy-asrs-admin/src/App.vue
@@ -0,0 +1,40 @@
+<script setup>
+import { getCurrentInstance, provide } from "vue";
+import IndexView from './views/IndexView.vue'
+import LoginView from './views/login/LoginView.vue'
+import { globalState } from './config.js'
+import zhCN from 'ant-design-vue/es/locale/zh_CN';
+import enUS from 'ant-design-vue/es/locale/en_US';
+import dayjs from 'dayjs';
+import 'dayjs/locale/zh-cn';
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+dayjs.locale('zh-cn');
+provide('globalState', globalState);
+
+const localeType = {
+  zhCN,
+  enUS,
+};
+
+if (globalState.token == '' || globalState.token == null) {
+  let token = localStorage.getItem('token')
+  let user = JSON.parse(localStorage.getItem('user'))
+  globalState.token = token;
+  globalState.user = user;
+}
+</script>
+
+<template>
+  <a-config-provider :locale="localeType[globalState.locale]">
+    <div v-if="globalState.token == '' || globalState.token == null">
+      <LoginView />
+      {{ context.$config }}
+    </div>
+    <div v-else>
+      <IndexView />
+      {{ context.$config }}
+    </div>
+  </a-config-provider>
+</template>
+
+<style scoped></style>
diff --git a/zy-asrs-admin/src/assets/base.css b/zy-asrs-admin/src/assets/base.css
new file mode 100644
index 0000000..ff2601b
--- /dev/null
+++ b/zy-asrs-admin/src/assets/base.css
@@ -0,0 +1,37 @@
+/* color palette from <https://github.com/vuejs/theme> */
+:root {
+  --vt-c-white: #ffffff;
+  --vt-c-white-soft: #f8f8f8;
+  --vt-c-white-mute: #f2f2f2;
+
+  --vt-c-black: #181818;
+  --vt-c-black-soft: #222222;
+  --vt-c-black-mute: #282828;
+
+  --vt-c-indigo: #2c3e50;
+
+  --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
+  --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
+  --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
+  --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
+
+  --vt-c-text-light-1: var(--vt-c-indigo);
+  --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
+  --vt-c-text-dark-1: var(--vt-c-white);
+  --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
+}
+
+/* semantic color variables for this project */
+:root {
+  --color-background: var(--vt-c-white);
+  --color-background-soft: var(--vt-c-white-soft);
+  --color-background-mute: var(--vt-c-white-mute);
+
+  --color-border: var(--vt-c-divider-light-2);
+  --color-border-hover: var(--vt-c-divider-light-1);
+
+  --color-heading: var(--vt-c-text-light-1);
+  --color-text: var(--vt-c-text-light-1);
+
+  --section-gap: 160px;
+}
diff --git a/zy-asrs-admin/src/assets/logo.svg b/zy-asrs-admin/src/assets/logo.svg
new file mode 100644
index 0000000..7565660
--- /dev/null
+++ b/zy-asrs-admin/src/assets/logo.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
diff --git a/zy-asrs-admin/src/assets/main.css b/zy-asrs-admin/src/assets/main.css
new file mode 100644
index 0000000..e45447d
--- /dev/null
+++ b/zy-asrs-admin/src/assets/main.css
@@ -0,0 +1,139 @@
+@import './base.css';
+
+.main {
+  height: 100vh;
+  overflow: scroll;
+}
+
+.trigger {
+  font-size: 18px;
+  line-height: 64px;
+  padding: 0 24px;
+  cursor: pointer;
+  transition: color 0.3s;
+  color: #000000;
+}
+
+.trigger:hover {
+  color: #1890ff;
+}
+
+.active {
+  color: #1890ff !important;
+}
+
+.active:hover {
+  color: #000000 !important;
+}
+
+.logo {
+  height: 50px;
+  /* background: rgba(255, 255, 255, 0.3); */
+  background: url('/public/img/logo.png') no-repeat;
+  background-size: 100%;
+  margin: 16px;
+}
+
+.site-layout .site-layout-background {
+  background: #fff;
+}
+
+.header-top {
+  display: flex;
+  justify-content: space-between;
+}
+
+.header-top-left {
+  flex: 1;
+}
+
+.header-top-right {
+  margin-right: 20px;
+  color: #000000;
+  cursor: pointer;
+  user-select: none;
+  flex: 4;
+  display: flex;
+  justify-content: flex-end;
+  font-size: 16px;
+}
+
+.header-top-right>div {
+  margin-right: 15px;
+}
+
+.header-user {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #000000;
+  cursor: pointer;
+  user-select: none;
+}
+
+.tabs-fixed {
+  position: relative;
+  top: -64px;
+  left: -24px;
+  display: flex;
+}
+
+.tabs-item {
+  height: 30px;
+  background: #fff;
+  display: flex;
+  justify-content: space-evenly;
+  align-items: center;
+  padding: 20px 0px;
+  cursor: pointer;
+  margin-right: 5px;
+  user-select: none;
+}
+
+.tabs-item>div:nth-child(1) {
+  margin-right: 10px;
+  margin-left: 10px;
+}
+
+.tabs-item>div:nth-child(1):hover {
+  color: #1890ff;
+}
+
+.tabs-item>div:nth-child(2) {
+  margin-right: 10px;
+  margin-left: 10px;
+}
+
+.tabs-item>div:nth-child(3) {
+  margin-right: 10px;
+  margin-left: 10px;
+}
+
+.tabs-item>div:nth-child(3):hover {
+  color: #1890ff;
+}
+
+.tabs-item-active>div:nth-child(2) {
+  color: rgb(24, 144, 255);
+}
+
+.tabs-item-reload-none {
+  display: none;
+}
+
+.table-header {
+  margin-bottom: 20px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.table-header-right>button {
+  margin-right: 10px;
+}
+
+.content-view {
+  margin: 45px 16px;
+  padding: 24px;
+  background: #fff;
+  min-height: 280px;
+}
\ No newline at end of file
diff --git a/zy-asrs-admin/src/config.js b/zy-asrs-admin/src/config.js
new file mode 100644
index 0000000..4fa3870
--- /dev/null
+++ b/zy-asrs-admin/src/config.js
@@ -0,0 +1,15 @@
+import { reactive, inject } from 'vue';
+
+export const globalState = reactive({
+    url: 'http://127.0.0.1:8081/wms',
+    token: '',
+    user: null,
+    locale: 'zhCN'
+});
+
+export const logout = () => {
+    globalState.token = null;
+    globalState.user = null;
+    localStorage.removeItem('token')
+    localStorage.removeItem('user')
+}
\ No newline at end of file
diff --git a/zy-asrs-admin/src/locales/en_US.js b/zy-asrs-admin/src/locales/en_US.js
new file mode 100644
index 0000000..84de0af
--- /dev/null
+++ b/zy-asrs-admin/src/locales/en_US.js
@@ -0,0 +1,131 @@
+import map from './map.js';
+
+export default {
+    ...map,
+    'message.hello': 'Hello, World!',
+    'message.language': 'Language',
+    'commont.enter':'Please enter',
+    'commont.select':'Please select',
+    'common.submit':'Submit',
+    'common.confirm':'Confirm',
+    'common.cancel':'Cancel',
+    'common.reset':'Reset',
+    'common.username':'Username',
+    'common.nickname':'Nickname',
+    'common.sex':'Sex',
+    'common.male':'Male',
+    'common.female':'Female',
+    'common.undefined':'Undefined',
+    'common.phone':'Phone',
+    'common.home':'Home',
+    'common.email':'Email',
+    'common.select.cancel':'Cancel Selection',
+    'common.realname':'Real Name',
+    'common.idcard':'ID Number',
+    'common.introduction':'Introduction',
+    'common.execute':'Execute',
+    'common.success':'Success',
+    'common.fail':'Fail',
+    'common.account.logout': 'Logout',
+    'common.search.placeholder': 'Please enter search content',
+    'common.loading.api.message': 'Calling Server...',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    'page.table.no': 'No',
+    'page.add': 'Add New',
+    'page.adding':'In process of adding',
+    'page.add.success':'Add Successful',
+    'page.add.fail':'Add failed, please try again!',
+    'page.updating':'Updating now',
+    'page.update.success':'Update Successful',
+    'page.update.fail':'Update failed, please try again!',
+    'page.deleting':'In process of deletion',
+    'page.delete.success':'Deletion Successful',
+    'page.delete.fail':'Deletion failed, please try again!',
+    'page.exporting':'Exporting...',
+    'page.export.success':'Exported successfully',
+    'page.export.fail':'Export failed, please try again.',
+    'page.edit':'Edit',
+    'page.delete':'Delete',
+    'page.delete.confirm':'Are you sure that you want to delete this item?',
+    'page.export':'Export',
+    'page.selected':' has been selected',
+    'page.delete.batch':'Batch Delete',
+    'page.assigning':'Assigning',
+    'page.assign.success':'Assignment Successful',
+    'page.assign.fail':'Assignment failed, please try again!',
+    'page.assign.permission':'Assign',
+    'page.permission.menu':'Menu',
+    'page.role.assign.ec':'Expand/Collapse',
+    'page.role.assign.sd':'Select All/Deselect All',
+    'page.resetting':'Resetting',
+    'page.reset.success':'Reset Successful',
+    'page.reset.fail':'Reset failed, please try again!"',
+    'page.reset.pwd':'Reset Pwd',
+    'page.assign.role':'Assign Role',
+    'page.input':'Please Input',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    'personal.base.setting':'Basic Settings',
+    'personal.security.setting':'Security Settings',
+    'personal.base.button.name':'Update Basic Information',
+    'personal.security.button.name':'Update Password',
+    'personal.security.cur.pwd':'Current Password',
+    'personal.security.new.pwd':'New Password',
+    'personal.security.new.pwd.confirm':'Confirm Password',
+    'personal.security.new.pwd.rule.length':'The new password must be 4 to 16 characters',
+    'personal.security.new.pwd.rule.check':'The passwords entered twice do not matc',
+    '':'',
+    '':'',
+    '':'',
+    'login.success':'Login successful!',
+    'login.fail':'Login fail!',
+    'login.logout':'Login out!',
+    'login.failure':'Login failed, please try again!',
+    'login.retoken':'Renewal Token!',
+    'login.accountLogin.tab':'Account Login',
+    'login.phoneLogin.tab':'Phone Login',
+    'login.host':'Host:',
+    'login.rule.host':'Please select host',
+    'login.username':'Username:',
+    'login.rule.username':'Please enter your username',
+    'login.password':'Password:',
+    'login.rule.password':'Please enter your password',
+    'login.accountLogin.errorMessage':'Incorrect username/password',
+    'login.rememberMe':'Remember me',
+    'login.phoneNumber.placeholder':'Phone Number',
+    'login.phoneNumber.required':'Please input your phone number!',
+    'login.phoneNumber.invalid':'Phone number is invalid!',
+    'login.captcha.placeholder':'Verification Code',
+    'login.getCaptchaSecondText':'sec(s)',
+    'login.phoneLogin.getVerificationCode':'Get Code',
+    'login.captcha.required':'Please input verification code!',
+    'login.phoneLogin.none':'Mobile phone login is not enabled',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    'system.dept':'Department',
+    'system.role':'Role',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+    '':'',
+};
\ No newline at end of file
diff --git a/zy-asrs-admin/src/locales/map.js b/zy-asrs-admin/src/locales/map.js
new file mode 100644
index 0000000..e905fe3
--- /dev/null
+++ b/zy-asrs-admin/src/locales/map.js
@@ -0,0 +1,177 @@
+export default {
+    'map.edit': 'Edit Model',
+    'map.edit.close': 'Exit Edit',
+    'map.device.add': 'Add New Device',
+    'map.device.oper': 'Device Settings',
+    'map.model.observer': 'Observer Pattern',
+    'map.model.editor': 'Editor Pattern',
+    'map.save': 'Save Map',
+    'map.load': 'Load Map',
+    'map.clear': 'Clear Map',
+    'map.x': 'x',
+    'map.y': 'y',
+    'map.load.success': 'Welcome To WCS.',
+    '': '',
+    '': '',
+    'map.loc.no': 'Location Number',
+    'map.task.no': 'Task Number',
+    'map.device.status': 'Device Status',
+    'map.origin.site': 'Origin Site',
+    'map.origin.loc': 'Origin Location',
+    'map.dest.site': 'Destination Site',
+    'map.dest.loc': 'Destination Location',
+    'map.error': 'Error',
+    'map.pakmk': 'PakMk',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.pallet.barcode': 'Pallet Barcode',
+    'map.is.enable': 'Enable or Not',
+    'map.enable': 'Enable',
+    'map.diable': 'Disable',
+    'map.handle': 'Handle',
+    'map.command': 'Command',
+    'map.loc.sts': 'Location Status',
+    'map.loc.operation': 'Location Operation',
+    'map.loc.lock': 'Lock',
+    'map.loc.unlock': 'Unlock',
+    'map.loc.reset': 'Reset Location',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.lift.no': 'Lift Number',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.shuttle.no': 'Shuttle Number',
+    'map.shuttle.current.code': 'Current Code',
+    'map.shuttle.batter.power': 'Batter Power',
+    'map.shuttle.batter.voltage': 'Batter Voltage',
+    'map.shuttle.batter.temp': 'Batter Temperature',
+    'map.shuttle.has.lift': 'Has Lift',
+    'map.shuttle.has.pallet': 'Has Pallet',
+    'map.shuttle.has.charge': 'Charging',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.conveyor.no': 'Conveyor Number',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.sensor.type.shuttle': 'Shuttle',
+    'map.sensor.type.lift': 'Lift',
+    'map.sensor.type.shelf': 'Shelf',
+    'map.sensor.type.agv': 'Agv',
+    'map.sensor.type.point': 'Point',
+    'map.sensor.type.conveyor': 'Conveyor',
+    '': '',
+    '': '',
+    '': '',
+    'map.drawer.json': 'JSON',
+    'map.drawer.shelf.view.title': 'Shelf Information',
+    'map.drawer.lift.view.title': 'Lift Information',
+    'map.drawer.shuttle.view.title': 'Shuttle Information',
+    'map.drawer.conveyor.view.title': 'Conveyor Information',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.settings.more': 'More',
+    'map.settings.delete': 'Delete',
+    'map.settings.type': 'Type',
+    'map.settings.uuid': 'Uuid',
+    'map.settings.component': 'Component',
+    'map.settings.name': 'Name',
+    'map.settings.position': 'Position',
+    'map.settings.scale': 'Scale',
+    'map.settings.scale.x': 'ScaleX',
+    'map.settings.scale.y': 'ScaleY',
+    'map.settings.rotation': 'Rotation',
+    'map.settings.copy': 'Copy',
+    'map.settings.left': 'Left',
+    'map.settings.right': 'Right',
+    'map.settings.top': 'Top',
+    'map.settings.bottom': 'Bottom',
+    'map.settings.map.param': 'Map Parameters',
+    'map.settings.config.param': 'Config Parameters',
+    'map.settings.batch.select.shelf': 'Select Shelfs',
+    'map.settings.batch.set.params': 'Set Parameters',
+    'map.settings.batch.result': 'Result',
+    'map.settings.batch.result.title': 'Batch settings successful!',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.settings.no': 'No.',
+    'map.settings.shelf.no': 'Shelf No',
+    'map.settings.shelf.location': 'Location',
+    'map.settings.shelf.row': 'Row',
+    'map.settings.shelf.bay': 'Bay',
+    'map.settings.shelf.type': 'Type',
+    'map.settings.shelf.space': 'Space',
+    'map.settings.shelf.top': 'Top',
+    'map.settings.shelf.right': 'Right',
+    'map.settings.shelf.bottom': 'Bottom',
+    'map.settings.shelf.left': 'Left',
+    'map.settings.shelf.value': 'Map Value',
+    'map.settings.shelf.store': 'Store',
+    'map.settings.shelf.track': 'Track',
+    'map.settings.shelf.lift': 'Lift',
+    'map.settings.shelf.charge': 'Charge',
+    'map.settings.shelf.diable': 'Diable',
+    'map.settings.shelf.reference': 'Reference',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    'map.settings.point.vertical': 'Vertical',
+    'map.settings.point.horizontal': 'Horizontal',
+    '': '',
+    '': '',
+    'map.settings.conveyor.plc.no': 'Plc No',
+    '': '',
+    '': '',
+    '': '',
+    'map.settings.lift.no': 'Lift No',
+    '': '',
+    '': '',
+    '': '',
+    'map.settings.sub.copy.reverse': 'Reverse',
+    'map.settings.sub.copy.rule': 'Copy Rule',
+    'map.settings.sub.copy.dire': 'Direction',
+    'map.settings.sub.copy.count': 'Count',
+    'map.settings.sub.copy.gap': 'Gap',
+    'map.settings.sub.copy.id': 'ID',
+    'map.settings.sub.copy.auto-increment': 'Auto Increment',
+    'map.settings.sub.copy.increment-value': 'Increment Value',
+    'map.settings.sub.copy.increment.mode': 'Increment Mode',
+    'map.settings.sub.copy.ascend': 'Ascending',
+    'map.settings.sub.copy.descend': 'Descending',
+    '': '',
+    '': '',
+    '': '',
+    'map.settings.sub.copy.warn.config.shelf': 'Please set the shelf parameters first!',
+    'map.settings.sub.copy.warn.config.point': 'Please set the point parameters first!',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+    '': '',
+}
\ No newline at end of file
diff --git a/zy-asrs-admin/src/locales/zh_CN.js b/zy-asrs-admin/src/locales/zh_CN.js
new file mode 100644
index 0000000..a535a18
--- /dev/null
+++ b/zy-asrs-admin/src/locales/zh_CN.js
@@ -0,0 +1,4 @@
+export default {
+    'message.hello': '浣犲ソ',
+    'message.language': '璇█',
+};
\ No newline at end of file
diff --git a/zy-asrs-admin/src/main.js b/zy-asrs-admin/src/main.js
new file mode 100644
index 0000000..06214a2
--- /dev/null
+++ b/zy-asrs-admin/src/main.js
@@ -0,0 +1,15 @@
+import './assets/main.css'
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+import router from './router'
+import Antd from 'ant-design-vue';
+import 'ant-design-vue/dist/reset.css';
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+app.use(Antd)
+
+app.mount('#app')
diff --git a/zy-asrs-admin/src/router/index.js b/zy-asrs-admin/src/router/index.js
new file mode 100644
index 0000000..11e6fb7
--- /dev/null
+++ b/zy-asrs-admin/src/router/index.js
@@ -0,0 +1,42 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+import MenuView from '../views/system/menu/index.vue'
+import LoginView from '../views/login/LoginView.vue'
+import UserLoginView from '../views/system/userLogin/index.vue'
+
+const router = createRouter({
+  history: createWebHistory(import.meta.env.BASE_URL),
+  routes: [
+    {
+      path: '/',
+      name: '涓婚〉',
+      component: HomeView,
+      meta: {
+        keepAlive: true // 璁剧疆keepAlive锛岃姝よ矾鐢遍〉闈㈣缂撳瓨
+      },
+    },
+    {
+      path: '/login',
+      name: '鐧诲綍',
+      component: LoginView,
+    },
+    {
+      path: '/system/menu',
+      name: '鑿滃崟绠$悊',
+      component: MenuView,
+      meta: {
+        keepAlive: true // 璁剧疆keepAlive锛岃姝よ矾鐢遍〉闈㈣缂撳瓨
+      },
+    },
+    {
+      path: '/system/userLogin',
+      name: '鐧诲綍鏃ュ織',
+      component: UserLoginView,
+      meta: {
+        keepAlive: true // 璁剧疆keepAlive锛岃姝よ矾鐢遍〉闈㈣缂撳瓨
+      },
+    },
+  ]
+})
+
+export default router
diff --git a/zy-asrs-admin/src/stores/counter.js b/zy-asrs-admin/src/stores/counter.js
new file mode 100644
index 0000000..b6757ba
--- /dev/null
+++ b/zy-asrs-admin/src/stores/counter.js
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+  const count = ref(0)
+  const doubleCount = computed(() => count.value * 2)
+  function increment() {
+    count.value++
+  }
+
+  return { count, doubleCount, increment }
+})
diff --git a/zy-asrs-admin/src/utils/localeUtils.js b/zy-asrs-admin/src/utils/localeUtils.js
new file mode 100644
index 0000000..c503c68
--- /dev/null
+++ b/zy-asrs-admin/src/utils/localeUtils.js
@@ -0,0 +1,19 @@
+import { globalState } from '../config.js'
+import enUS from '../locales/en_US.js';
+import zhCN from '../locales/zh_CN.js';
+
+export const formatMessage = (id, defaultMessage) => {
+    const localesType = {
+        enUS,
+        zhCN,
+    }
+
+    const message = localesType[globalState.locale]
+    if(message == null) {
+        return defaultMessage;
+    }
+    if(message[id] == null || message[id] == undefined) {
+        return defaultMessage;
+    }
+    return message[id];
+}
\ No newline at end of file
diff --git a/zy-asrs-admin/src/utils/request.js b/zy-asrs-admin/src/utils/request.js
new file mode 100644
index 0000000..eb7803e
--- /dev/null
+++ b/zy-asrs-admin/src/utils/request.js
@@ -0,0 +1,43 @@
+import axios from "axios";
+import { globalState } from '../config.js'
+
+const instance = axios.create({
+    baseURL: globalState.url,
+    timeout: 30000,
+})
+
+export const get = (url, params) => {
+    return instance({
+        url: url,
+        method: 'get',
+        params: params,
+        headers: {
+            Authorization: globalState.token
+        }
+    })
+}
+
+export const post = (url, data) => {
+    return instance({
+        url: url,
+        method: 'post',
+        data: data,
+        headers: {
+            Authorization: globalState.token
+        }
+    })
+}
+
+export const postBlob = (url, data) => {
+    return instance({
+        url: url,
+        method: 'post',
+        data: data,
+        headers: {
+            Authorization: globalState.token
+        },
+        responseType: 'blob'
+    })
+}
+
+export default instance;
\ No newline at end of file
diff --git a/zy-asrs-admin/src/views/HomeView.vue b/zy-asrs-admin/src/views/HomeView.vue
new file mode 100644
index 0000000..6ece80c
--- /dev/null
+++ b/zy-asrs-admin/src/views/HomeView.vue
@@ -0,0 +1,14 @@
+<script setup>
+import { getCurrentInstance, ref } from 'vue';
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+</script>
+
+<script>
+export default {
+  name: '涓婚〉'
+}
+</script>
+
+<template>
+  Hello World
+</template>
diff --git a/zy-asrs-admin/src/views/IndexView.vue b/zy-asrs-admin/src/views/IndexView.vue
new file mode 100644
index 0000000..1f9f9f7
--- /dev/null
+++ b/zy-asrs-admin/src/views/IndexView.vue
@@ -0,0 +1,190 @@
+<script setup>
+import { nextTick, ref, inject, computed } from 'vue';
+import { useRouter } from "vue-router";
+import { get, post } from '@/utils/request.js'
+import { logout } from '@/config.js';
+import * as Icons from "@ant-design/icons-vue";
+import {
+  MenuUnfoldOutlined,
+  MenuFoldOutlined,
+  HomeOutlined,
+  CloseOutlined,
+  RedoOutlined,
+  UserOutlined,
+  TranslationOutlined,
+} from "@ant-design/icons-vue";
+import { formatMessage } from '@/utils/localeUtils.js';
+
+const globalState = inject('globalState');
+const selectedKeys = ref([]);
+const collapsed = ref(false);
+const router = useRouter();
+let routerCache = ref([]);
+let routerCacheMap = ref(new Map());
+let currentCache = ref(null);
+let isRouterAlive = ref(true);
+const menuCache = ref([]);
+
+const components = {
+  ...Icons,
+};
+
+getMenu()
+
+function getMenu() {
+  post('/api/menu/tree', {}).then((result) => {
+    console.log(result.data.data);
+    menuCache.value = result.data.data;
+  })
+}
+
+function menuSelect(item) {
+  router.push({
+    path: item.key
+  })
+
+  let name = item.item.name;
+  currentCache.value = name;
+  console.log(routerCache.value);
+
+  if (name != undefined && routerCache.value.indexOf(name) == -1) {
+    routerCache.value.push(item.item.name)
+    routerCacheMap.value.set(name, item.key)
+  }
+}
+
+function closeTabs(name) {
+  let tmp = []
+  routerCache.value.forEach((item) => {
+    if (item != name) {
+      tmp.push(item);
+    }
+  })
+
+  if (tmp == 0) {
+    router.push({
+      path: '/'
+    })
+    routerCache.value.push('home')
+    routerCacheMap.value.set('home', '/')
+    selectedKeys.value = ['/']
+  } else {
+    switchTabs(tmp[0]);
+  }
+  routerCache.value = tmp;
+}
+
+function reloadTabs() {
+  isRouterAlive.value = false;
+  nextTick(() => {
+    isRouterAlive.value = true;
+  })
+}
+
+function switchTabs(name) {
+  router.push({
+    path: routerCacheMap.value.get(name)
+  })
+
+  currentCache.value = name;
+  selectedKeys.value = [routerCacheMap.value.get(name)]
+
+  console.log(routerCacheMap, name, routerCacheMap.value.get(name));
+
+}
+
+const switchLocale = (locale) => {
+  globalState.locale = locale;
+}
+
+</script>
+
+<template>
+  <a-layout class="main">
+    <a-layout-sider v-model:collapsed="collapsed" :trigger="null" collapsible>
+      <div class="logo" />
+      <a-menu v-for="(item, index) in menuCache" :key="index" v-model:selectedKeys="selectedKeys" @select="menuSelect"
+        theme="dark" mode="inline">
+        <div>
+          <a-menu-item key="/" name="涓婚〉">
+            <HomeOutlined /> {{ formatMessage('common.home','涓婚〉') }}
+          </a-menu-item>
+        </div>
+
+        <a-sub-menu v-if="item.type == 0">
+          <template #title>
+            <span>
+              <component :is="components[ref(item.icon).value]" />
+              {{ item.name }}
+            </span>
+          </template>
+          <div v-for="(child, idx) in item.children">
+            <a-menu-item v-if="child.status == 1" :key="child.route" :name="child.name">
+              {{ child.name }}
+            </a-menu-item>
+          </div>
+        </a-sub-menu>
+      </a-menu>
+
+    </a-layout-sider>
+    <a-layout>
+      <a-layout-header style="background: #fff; padding: 0">
+        <div class="header-top">
+          <div class="header-top-left">
+            <MenuUnfoldOutlined v-if="collapsed" class="trigger" @click="() => (collapsed = !collapsed)" />
+            <MenuFoldOutlined v-else class="trigger" @click="() => (collapsed = !collapsed)" />
+          </div>
+          <div class="header-top-right">
+            <div class="trigger">
+              <a-dropdown>
+                <TranslationOutlined />
+                <template #overlay>
+                  <a-menu>
+                    <a-menu-item @click="switchLocale('enUS')"
+                      :class="globalState.locale == 'enUS' ? 'active' : ''">English</a-menu-item>
+                    <a-menu-item @click="switchLocale('zhCN')"
+                      :class="globalState.locale == 'zhCN' ? 'active' : ''">绠�浣撲腑鏂�</a-menu-item>
+                  </a-menu>
+                </template>
+              </a-dropdown>
+            </div>
+            <div>
+              <a-dropdown>
+                <a class="header-user" @click.prevent>
+                  <UserOutlined />
+                  <span>{{ globalState.user.username }}</span>
+                </a>
+                <template #overlay>
+                  <a-menu @click="logout">
+                    <a-menu-item key="logout">{{ formatMessage('common.account.logout','閫�鍑�') }}</a-menu-item>
+                  </a-menu>
+                </template>
+              </a-dropdown>
+            </div>
+          </div>
+        </div>
+      </a-layout-header>
+      <a-layout-content class="content-view">
+        <div class="tabs-fixed">
+          <div v-for="(item, index) in routerCache" :key="index" @click="switchTabs(item)" class="tabs-item"
+            :class="currentCache == item ? 'tabs-item-active' : ''">
+            <div :class="currentCache == item ? '' : 'tabs-item-reload-none'" @click="reloadTabs" @click.stop>
+              <RedoOutlined />
+            </div>
+            <div>{{ item }}</div>
+            <div @click="closeTabs(item)" @click.stop>
+              <CloseOutlined />
+            </div>
+          </div>
+        </div>
+        <router-view v-slot="{ Component, route }" v-if="isRouterAlive">
+          <keep-alive :include="routerCache">
+            <component :is="Component" />
+          </keep-alive>
+        </router-view>
+      </a-layout-content>
+    </a-layout>
+  </a-layout>
+</template>
+
+<style scoped></style>
diff --git a/zy-asrs-admin/src/views/login/LoginView.vue b/zy-asrs-admin/src/views/login/LoginView.vue
new file mode 100644
index 0000000..f981e72
--- /dev/null
+++ b/zy-asrs-admin/src/views/login/LoginView.vue
@@ -0,0 +1,273 @@
+<script setup>
+import { getCurrentInstance, inject, ref } from 'vue';
+import { message } from 'ant-design-vue';
+import { get, post } from '../../utils/request.js'
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+const globalState = inject('globalState');
+
+let copyrightLargeShow = ref(false);
+let username = ref("");
+let password = ref("");
+
+function loginConfirm() {
+    if (username.value == "" || password.value == "") {
+        message.info('璇疯緭鍏ヨ处鍙峰瘑鐮�!');
+        return;
+    }
+
+    post('/api/login', {
+        username: username.value,
+        password: password.value
+    }).then((result) => {
+        if (result.data.code == 200) {
+            let data = result.data.data;
+            globalState.token = data.accessToken;
+            globalState.user = data.user;
+            localStorage.setItem('token', data.accessToken)
+            localStorage.setItem('user', JSON.stringify(data.user))
+            message.success('鐧诲綍鎴愬姛')
+        } else {
+            message.error(result.data.msg)
+        }
+    })
+
+}
+
+</script>
+
+<script>
+export default {
+    name: 'login'
+}
+</script>
+
+<template>
+    <div class="container" @keyup.enter="loginConfirm">
+        <div class="left-box">
+            <div class="login-video">
+                <video src="/public/img/login-bg.mp4" height="100%" loop autoplay muted="false"
+                    controlslist="nodownload" disablepictureinpicture></video>
+                <!-- <img src="/public/img/bg1.png" height="100%"> -->
+            </div>
+        </div>
+
+        <div class="right-box">
+            <div class="login-box">
+                <div class="form-main">
+                    <p style="text-align: center;"><img class="loginLogoUrl" src="/public/img/logo.png" alt=""
+                            style="width: 80%">
+                    </p>
+                    <p style="margin-top: -10px;"><span class="login100-form-title p-t-20 p-b-45"
+                            style="color: #868686;font-size: 24px">WMS</span></p>
+                    <div class="inputContainer">
+                        <svg viewBox="0 0 16 16" fill="#2e2e2e" height="16" width="16"
+                            xmlns="http://www.w3.org/2000/svg" class="inputIcon">
+                            <path
+                                d="M13.106 7.222c0-2.967-2.249-5.032-5.482-5.032-3.35 0-5.646 2.318-5.646 5.702 0 3.493 2.235 5.708 5.762 5.708.862 0 1.689-.123 2.304-.335v-.862c-.43.199-1.354.328-2.29.328-2.926 0-4.813-1.88-4.813-4.798 0-2.844 1.921-4.881 4.594-4.881 2.735 0 4.608 1.688 4.608 4.156 0 1.682-.554 2.769-1.416 2.769-.492 0-.772-.28-.772-.76V5.206H8.923v.834h-.11c-.266-.595-.881-.964-1.6-.964-1.4 0-2.378 1.162-2.378 2.823 0 1.737.957 2.906 2.379 2.906.8 0 1.415-.39 1.709-1.087h.11c.081.67.703 1.148 1.503 1.148 1.572 0 2.57-1.415 2.57-3.643zm-7.177.704c0-1.197.54-1.907 1.456-1.907.93 0 1.524.738 1.524 1.907S8.308 9.84 7.371 9.84c-.895 0-1.442-.725-1.442-1.914z">
+                            </path>
+                        </svg>
+                        <input placeholder="璇疯緭鍏ョ敤鎴峰悕" v-model="username" class="inputField" type="text">
+                    </div>
+
+                    <div class="inputContainer">
+                        <svg viewBox="0 0 16 16" fill="#2e2e2e" height="16" width="16"
+                            xmlns="http://www.w3.org/2000/svg" class="inputIcon">
+                            <path
+                                d="M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z">
+                            </path>
+                        </svg>
+                        <input placeholder="璇疯緭鍏ュ瘑鐮�" v-model="password" class="inputField" type="password">
+                    </div>
+
+                    <input @click="loginConfirm" type="button" class="login-button" value="鐧诲綍">
+
+                    <div style="display: none;margin-top: 5px;width: 100%;" id="updateLicense">
+                        <form enctype="multipart/form-data" style="display: none;">
+                            <input id="license" type="file" name="file">
+                        </form>
+                        <input type="button" id="submitLicense" class="login-button" style="margin: 0;" value="鏇存柊璁稿彲璇�">
+                    </div>
+                </div>
+            </div>
+
+            <div class="login-copyright">
+                <div class="copyright-text">Copyright 漏2023 娴欐睙涓壃绔嬪簱鎶�鏈湁闄愬叕鍙哥増鏉冩墍鏈�</div>
+                <div id="copyright-img1" class="copyright-img" @mouseover="copyrightLargeShow = true"
+                    @mouseout="copyrightLargeShow = false">
+                    <img class="copyright-img-url" src="/public/img/weixin_qrcode.jpg" />
+                    <div v-if="copyrightLargeShow" class="copyright-img-large"><img class="copyright-img-url"
+                            src="/public/img/weixin_qrcode.jpg" /></div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style>
+* {
+    padding: 0;
+    margin: 0;
+}
+
+.container {
+    display: flex;
+    height: 100vh;
+    width: 100%;
+}
+
+.left-box {
+    height: 100%;
+    width: 70%;
+}
+
+.login-video {
+    height: 100%;
+    overflow: hidden;
+}
+
+.form-main {
+    width: 300px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    background-color: rgba(255, 255, 255, 0.6);
+    padding: 50px 30px 50px 30px;
+    border-radius: 20px;
+    box-shadow: 0px 0px 40px rgba(0, 0, 0, 0.062);
+}
+
+.heading {
+    font-size: 2.5em;
+    color: #2e2e2e;
+    font-weight: 700;
+    margin: 15px 0 0px 0;
+}
+
+.inputContainer {
+    width: 100%;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.inputIcon {
+    position: absolute;
+    left: 10px;
+}
+
+.inputField {
+    width: 100%;
+    height: 40px;
+    background-color: transparent;
+    border: none;
+    border-bottom: 2px solid rgb(173, 173, 173);
+    border-radius: 30px;
+    margin: 10px 0;
+    color: black;
+    font-size: .8em;
+    font-weight: 500;
+    box-sizing: border-box;
+    padding-left: 30px;
+}
+
+.inputField:focus {
+    outline: none;
+    border-bottom: 2px solid rgb(199, 114, 255);
+}
+
+.inputField::placeholder {
+    color: rgb(80, 80, 80);
+    font-size: 1em;
+    font-weight: 500;
+}
+
+.login-box {
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.login-button {
+    position: relative;
+    width: 100%;
+    border: 2px solid #8000ff;
+    background-color: #8000ff;
+    height: 40px;
+    color: white;
+    font-size: .8em;
+    font-weight: 500;
+    letter-spacing: 1px;
+    border-radius: 30px;
+    margin: 10px;
+    cursor: pointer;
+    overflow: hidden;
+}
+
+.login-button::after {
+    content: "";
+    position: absolute;
+    background-color: rgba(255, 255, 255, 0.253);
+    height: 100%;
+    width: 150px;
+    top: 0;
+    left: -200px;
+    border-bottom-right-radius: 100px;
+    border-top-left-radius: 100px;
+    filter: blur(10px);
+    transition-duration: .5s;
+}
+
+.login-button:hover::after {
+    transform: translateX(600px);
+    transition-duration: .5s;
+}
+
+.right-box {
+    height: 100%;
+    width: 30%;
+    background: #f6f6f6;
+    position: relative;
+}
+
+.login-copyright {
+    position: absolute;
+    bottom: 20px;
+    right: 20px;
+    font-size: 14px;
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.copyright-text {
+    margin-right: 20px;
+}
+
+.copyright-img {
+    width: 40px;
+    height: 40px;
+    position: relative;
+}
+
+.copyright-img>img {
+    width: 100%;
+    height: 100%;
+}
+
+.copyright-img-large {
+    width: 140px;
+    height: 140px;
+    position: absolute;
+    top: -140px;
+    left: -50px;
+}
+
+.copyright-img-large>img {
+    width: 100%;
+    height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/zy-asrs-admin/src/views/system/menu/edit.vue b/zy-asrs-admin/src/views/system/menu/edit.vue
new file mode 100644
index 0000000..32e143f
--- /dev/null
+++ b/zy-asrs-admin/src/views/system/menu/edit.vue
@@ -0,0 +1,105 @@
+<script setup>
+import { getCurrentInstance, ref, computed, reactive, watch } from 'vue';
+import { get, post } from '@/utils/request.js'
+import * as Icons from "@ant-design/icons-vue";
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+const components = {
+    ...Icons,
+};
+
+const open = ref(false);
+const initFormData = {
+    name: null
+}
+let formData = ref(initFormData);
+const treeData = ref(null);
+
+const emit = defineEmits(['tableReload'])
+
+const handleOk = (e) => {
+    open.value = false;
+    console.log(formData.value);
+    post('/api/menu/update', formData.value).then((result) => {
+        console.log(result);
+        emit('tableReload', 'reload')
+    })
+};
+
+const onFinish = values => {
+    console.log('Success:', values);
+};
+const onFinishFailed = errorInfo => {
+    console.log('Failed:', errorInfo);
+};
+
+defineExpose({
+    open,
+    formData,
+    initFormData,
+    treeData,
+})
+
+</script>
+
+<script>
+export default {
+    name: '鑿滃崟绠$悊'
+}
+</script>
+
+<template>
+    <div>
+        <a-modal v-model:open="open" :title="formData == null ? '娣诲姞' : '缂栬緫'" @ok="handleOk" style="width: 600px;">
+            <a-form :model="formData" name="menu" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }"
+                style="display: flex;justify-content: space-between;flex-wrap: wrap;" autocomplete="off"
+                @finish="onFinish" @finishFailed="onFinishFailed">
+                <a-form-item label="涓婄骇鑿滃崟" name="parentId" style="width: 250px;"
+                    :rules="[{ required: true, message: '涓婄骇鑿滃崟涓嶈兘涓虹┖!' }]">
+                    <a-tree-select v-model:value="formData.parentId" show-search style="width: 100%"
+                        :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="Please select"
+                        allow-clea tree-data-simple-mode :tree-data="treeData" tree-node-filter-prop="name"
+                        :field-names="{
+                            children: 'children',
+                            label: 'name',
+                            value: 'id',
+                        }">
+                        <template #title="{ value: id, name }">
+                            {{ name }}
+                        </template>
+                    </a-tree-select>
+                </a-form-item>
+                <a-form-item label="鑿滃崟鍚嶇О" name="name" style="width: 250px;"
+                    :rules="[{ required: true, message: '鑿滃崟鍚嶇О涓嶈兘涓虹┖!' }]">
+                    <a-input v-model:value="formData.name" />
+                </a-form-item>
+                <a-form-item label="璺敱鍦板潃" name="route" style="width: 250px;">
+                    <a-input v-model:value="formData.route" />
+                </a-form-item>
+                <a-form-item label="椤甸潰缁勪欢" name="component" style="width: 250px;">
+                    <a-input v-model:value="formData.component" />
+                </a-form-item>
+                <a-form-item label="绫诲瀷" name="type" style="width: 250px;"
+                    :rules="[{ required: true, message: '绫诲瀷涓嶈兘涓虹┖!' }]">
+                    <a-select ref="select" v-model:value="formData.type" :options="[
+                        { label: '鑿滃崟', value: 0 },
+                        { label: '鎸夐挳', value: 1 },
+                    ]"></a-select>
+                </a-form-item>
+                <a-form-item label="鑿滃崟鍥炬爣" name="icon" style="width: 250px;">
+                    <a-input v-model:value="formData.icon" />
+                </a-form-item>
+                <a-form-item label="鎺掑簭" name="sort" style="width: 250px;">
+                    <a-input v-model:value="formData.sort" />
+                </a-form-item>
+                <a-form-item label="鐘舵��" name="status" style="width: 250px;">
+                    <a-select ref="select" v-model:value="formData.status" :options="[
+                        { label: '绂佺敤', value: 0 },
+                        { label: '姝e父', value: 1 },
+                    ]"></a-select>
+                </a-form-item>
+            </a-form>
+        </a-modal>
+    </div>
+</template>
+
+<style></style>
\ No newline at end of file
diff --git a/zy-asrs-admin/src/views/system/menu/index.vue b/zy-asrs-admin/src/views/system/menu/index.vue
new file mode 100644
index 0000000..97d4ad3
--- /dev/null
+++ b/zy-asrs-admin/src/views/system/menu/index.vue
@@ -0,0 +1,134 @@
+<script setup>
+import { getCurrentInstance, ref, computed, reactive, onMounted } from 'vue';
+import { get, post } from '@/utils/request.js'
+import * as Icons from "@ant-design/icons-vue";
+import EditView from './edit.vue'
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+const components = {
+  ...Icons,
+};
+
+const searchInput = ref("")
+const editChild = ref(null)
+
+let tableData = ref([]);
+getPage();
+
+const typeMap = {
+  0: {
+    color: 'success',
+    text: '鑿滃崟',
+  },
+  1: {
+    color: 'default',
+    text: '鎸夐挳',
+  },
+};
+
+const state = reactive({
+  selectedRowKeys: [],
+  loading: false,
+});
+const hasSelected = computed(() => state.selectedRowKeys.length > 0);
+const start = () => {
+  state.loading = true;
+  // ajax request after empty completing
+  setTimeout(() => {
+    state.loading = false;
+    state.selectedRowKeys = [];
+  }, 1000);
+};
+const onSelectChange = selectedRowKeys => {
+  // console.log('selectedRowKeys changed: ', selectedRowKeys);
+  state.selectedRowKeys = selectedRowKeys;
+};
+
+function getPage() {
+  post('/api/menu/tree', {}).then((result) => {
+    if (result.data.code == 200) {
+      let data = result.data.data;
+      tableData.value = data;
+      console.log(data);
+      editChild.value.treeData = [{
+        id: 0,
+        name: '鏍圭洰褰�',
+        children: data
+      }];
+    } else {
+
+    }
+  })
+}
+
+const handleEdit = (item) => {
+  editChild.value.open = true;
+  editChild.value.formData = item == null ? editChild.value.initFormData : item;
+}
+
+const handleExport = async (intl) => {
+  post('/api/menu/export', {}).then(result => {
+    const blob = new Blob([result.data], { type: 'application/vnd.ms-excel' });
+    window.location.href = window.URL.createObjectURL(blob);
+    return true;
+  })
+};
+
+const onSearch = () => {
+  console.log('search');
+}
+
+function handleTableReload(value) {
+  getPage()
+}
+
+</script>
+
+<script>
+export default {
+  name: '鑿滃崟绠$悊'
+}
+</script>
+
+<template>
+  <div>
+    <EditView ref="editChild" @tableReload="handleTableReload" />
+    <div class="table-header">
+      <a-input-search v-model:value="searchInput" placeholder="璇疯緭鍏�" style="width: 200px;" @search="onSearch" />
+      <div class="table-header-right">
+        <a-button @click="handleEdit(null)" type="primary">娣诲姞</a-button>
+        <a-button @click="handleExport">瀵煎嚭</a-button>
+      </div>
+    </div>
+    <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+      :data-source="tableData" :defaultExpandAllRows="false" key="menu" rowKey="id">
+      <a-table-column title="鑿滃崟鍚嶇О" key="name" data-index="name" />
+      <a-table-column title="璺敱鍦板潃" key="route" data-index="route" />
+      <a-table-column title="绫诲瀷" key="type" data-index="type$">
+        <template #default="{ record }">
+          <span>
+            <a-tag :color="typeMap[record.type].color">{{ record.type$ }}</a-tag>
+          </span>
+        </template>
+      </a-table-column>
+      <a-table-column title="鏉冮檺鏍囪瘑" key="authority" data-index="authority" />
+      <a-table-column title="鑿滃崟鍥炬爣" key="icon" data-index="icon">
+        <template #default="{ record }">
+          <component :is="components[ref(record.icon).value]" />
+        </template>
+      </a-table-column>
+      <a-table-column title="鎺掑簭" key="sort" data-index="sort" />
+      <a-table-column title="鐘舵��" key="status$" data-index="status$" />
+      <a-table-column title="淇敼鏃堕棿" key="updateTime$" data-index="updateTime$" />
+      <a-table-column title="鎿嶄綔" key="oper" data-index="oper">
+        <template #default="{ record }">
+          <div style="display: flex;justify-content: space-evenly;">
+            <a-button type="link" primary @click="handleEdit(record)">缂栬緫</a-button>
+            <a-button type="link" danger>鍒犻櫎</a-button>
+          </div>
+        </template>
+      </a-table-column>
+    </a-table>
+  </div>
+</template>
+
+<style></style>
\ No newline at end of file
diff --git a/zy-asrs-admin/src/views/system/userLogin/edit.vue b/zy-asrs-admin/src/views/system/userLogin/edit.vue
new file mode 100644
index 0000000..235a3c9
--- /dev/null
+++ b/zy-asrs-admin/src/views/system/userLogin/edit.vue
@@ -0,0 +1,92 @@
+<script setup>
+import { ref, nextTick } from 'vue';
+import { get, post } from '@/utils/request.js'
+import { formatMessage } from '@/utils/localeUtils.js';
+
+const submitButton = ref(null);
+const isSave = ref(true);
+const open = ref(false);
+const initFormData = {
+    name: null
+}
+let formData = ref(initFormData);
+const treeData = ref(null);
+
+const emit = defineEmits(['tableReload'])
+
+const handleOk = (e) => {
+    nextTick(() => {
+        setTimeout(() => {
+            submitButton.value.$el.click();
+        }, 100);
+    });
+};
+
+const onFinish = values => {
+    // console.log('Success:', values);
+    open.value = false;
+    post(isSave.value ? '/api/userLogin/save' : '/api/userLogin/update', formData.value).then((result) => {
+        console.log(result);
+        emit('tableReload', 'reload')
+    })
+};
+const onFinishFailed = errorInfo => {
+    console.log('Failed:', errorInfo);
+};
+
+defineExpose({
+    open,
+    formData,
+    initFormData,
+    treeData,
+    isSave,
+})
+
+</script>
+
+<script>
+export default {
+    name: '鑿滃崟绠$悊'
+}
+</script>
+
+<template>
+    <div>
+        <a-modal v-model:open="open"
+            :title="isSave ? formatMessage('page.add', '娣诲姞') : formatMessage('page.edit', '缂栬緫')" @ok="handleOk"
+            style="width: 600px;">
+            <a-form :model="formData" name="formTable" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }"
+                style="display: flex;justify-content: space-between;flex-wrap: wrap;" autocomplete="off"
+                @finish="onFinish" @finishFailed="onFinishFailed">
+                <a-form-item label="鐢ㄦ埛" name="userId" style="width: 250px;"
+                    :rules="[{ required: true, message: '鐢ㄦ埛涓嶈兘涓虹┖!' }]">
+                    <a-input v-model:value="formData.userId" />
+                </a-form-item>
+                <a-form-item label="瀵嗛挜" name="token" style="width: 250px;">
+                    <a-input v-model:value="formData.token" />
+                </a-form-item>
+                <a-form-item label="鐧诲綍ip" name="ip" style="width: 250px;">
+                    <a-input v-model:value="formData.ip" />
+                </a-form-item>
+                <a-form-item label="绫诲瀷" name="type" style="width: 250px;"
+                    :rules="[{ required: true, message: '绫诲瀷涓嶈兘涓虹┖!' }]">
+                    <a-select ref="select" v-model:value="formData.type" :options="[
+                        { label: '鐧诲綍鎴愬姛', value: 0 },
+                        { label: '鐧诲綍澶辫触', value: 1 },
+                        { label: '閫�鍑虹櫥褰�', value: 2 },
+                        { label: '缁token', value: 3 },
+                    ]"></a-select>
+                </a-form-item>
+                <a-form-item label="澶囨敞" name="memo" style="width: 250px;">
+                    <a-input v-model:value="formData.memo" />
+                </a-form-item>
+                <a-form-item>
+                    <a-button type="primary" html-type="submit" ref="submitButton"
+                        style="visibility: hidden;">Submit</a-button>
+                </a-form-item>
+            </a-form>
+        </a-modal>
+    </div>
+</template>
+
+<style></style>
\ No newline at end of file
diff --git a/zy-asrs-admin/src/views/system/userLogin/index.vue b/zy-asrs-admin/src/views/system/userLogin/index.vue
new file mode 100644
index 0000000..e151820
--- /dev/null
+++ b/zy-asrs-admin/src/views/system/userLogin/index.vue
@@ -0,0 +1,211 @@
+<script setup>
+import { getCurrentInstance, ref, computed, reactive } from 'vue';
+import { useRouter } from "vue-router";
+import { get, post, postBlob } from '@/utils/request.js'
+import { message, Modal } from 'ant-design-vue';
+import { logout } from '@/config.js';
+import EditView from './edit.vue'
+import { formatMessage } from '@/utils/localeUtils.js';
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+
+const router = useRouter();
+const TABLE_KEY = 'table-userLogin';
+let currentPage = 1;
+let pageSize = 10;
+const searchInput = ref("")
+const editChild = ref(null)
+
+let tableData = ref([]);
+getPage();
+
+const columns = [
+  {
+    title: 'ID',
+    name: 'id',
+    dataIndex: 'id',
+    key: 'id',
+  },
+  {
+    title: '鐢ㄦ埛',
+    name: 'userId$',
+    dataIndex: 'userId$',
+    key: 'userId$',
+  },
+  {
+    title: '瀵嗛挜',
+    name: 'token',
+    dataIndex: 'token',
+    key: 'token',
+    ellipsis: true,
+  },
+  {
+    title: '鐧诲綍ip',
+    name: 'ip',
+    dataIndex: 'ip',
+    key: 'ip',
+  },
+  {
+    title: '绫诲瀷',
+    name: 'type',
+    dataIndex: 'type',
+    key: 'type',
+    customRender: (column) => {
+      let typeMap = {
+        0: {
+          text: formatMessage('login.success', '鐧诲綍鎴愬姛'),
+        },
+        1: {
+          text: formatMessage('login.fail', '鐧诲綍澶辫触'),
+        },
+        2: {
+          text: formatMessage('login.logout', '閫�鍑虹櫥褰�'),
+        },
+        3: {
+          text: formatMessage('login.retoken', '缁token'),
+        },
+      };
+      return typeMap[column.value].text;
+    }
+  },
+  {
+    title: '娣诲姞鏃堕棿',
+    name: 'createTime$',
+    dataIndex: 'createTime$',
+    key: 'createTime$',
+  },
+  {
+    title: '澶囨敞',
+    name: 'memo',
+    dataIndex: 'memo',
+    key: 'memo',
+  },
+  {
+    title: '鎿嶄綔',
+    name: 'oper',
+    dataIndex: 'oper',
+    key: 'oper',
+  },
+];
+
+const state = reactive({
+  selectedRowKeys: [],
+  loading: false,
+});
+const hasSelected = computed(() => state.selectedRowKeys.length > 0);
+const start = () => {
+  state.loading = true;
+  // ajax request after empty completing
+  setTimeout(() => {
+    state.loading = false;
+    state.selectedRowKeys = [];
+  }, 1000);
+};
+const onSelectChange = selectedRowKeys => {
+  // console.log('selectedRowKeys changed: ', selectedRowKeys);
+  state.selectedRowKeys = selectedRowKeys;
+};
+
+function getPage() {
+  post('/api/userLogin/page', {
+    current: currentPage,
+    pageSize: pageSize,
+    condition: searchInput.value
+  }).then((resp) => {
+    let result = resp.data;
+    if (result.code == 200) {
+      let data = result.data;
+      tableData.value = data;
+    } else if (result.code === 401) {
+      message.error(result.msg);
+      logout()
+    } else {
+      message.error(result.msg);
+    }
+  })
+}
+
+const handleEdit = (item) => {
+  editChild.value.open = true;
+  editChild.value.formData = item == null ? editChild.value.initFormData : JSON.parse(JSON.stringify(item));
+  editChild.value.isSave = item == null;
+}
+
+const handleDel = (rows) => {
+  Modal.confirm({
+    title: formatMessage('page.delete', '鍒犻櫎'),
+    content: formatMessage('page.delete.confirm', '纭畾鍒犻櫎璇ラ」鍚楋紵'),
+    maskClosable: true,
+    onOk: async () => {
+      post('/api/userLogin/remove/' + rows.map((row) => row.id).join(','), {}).then(resp => {
+        let result = resp.data;
+        if (result.code === 200) {
+          message.success(result.msg);
+        } else {
+          message.error(result.msg);
+        }
+        getPage()
+      })
+    },
+  });
+}
+
+const handleExport = async (intl) => {
+  postBlob('/api/userLogin/export', {}).then(result => {
+    const blob = new Blob([result.data], { type: 'application/vnd.ms-excel' });
+    window.location.href = window.URL.createObjectURL(blob);
+    return true;
+  })
+};
+
+const onSearch = () => {
+  // console.log('search');
+  getPage()
+}
+
+const onPageChange = (page, size) => {
+  currentPage = page;
+  pageSize = size;
+  getPage();
+}
+
+function handleTableReload(value) {
+  getPage()
+}
+
+</script>
+
+<script>
+export default {
+  name: '鐧诲綍鏃ュ織'
+}
+</script>
+
+<template>
+  <div>
+    <EditView ref="editChild" @tableReload="handleTableReload" />
+    <div class="table-header">
+      <a-input-search v-model:value="searchInput" :placeholder="formatMessage('page.input', '璇疯緭鍏�')"
+        style="width: 200px;" @search="onSearch" />
+      <div class="table-header-right">
+        <a-button @click="handleEdit(null)" type="primary">{{ formatMessage('page.add', '娣诲姞') }}</a-button>
+        <a-button @click="handleExport">{{ formatMessage('page.export', '瀵煎嚭') }}</a-button>
+      </div>
+    </div>
+    <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+      :data-source="tableData.records" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id"
+      :pagination="{ total: tableData.total, onChange: onPageChange }"
+      :scroll="{ y: 768, scrollToFirstRowOnChange: true }" :columns="columns">
+      <template #bodyCell="{ column, text, record }">
+        <template v-if="column.dataIndex === 'oper'">
+          <div style="display: flex;justify-content: space-evenly;">
+            <a-button type="link" primary @click="handleEdit(record)">{{ formatMessage('page.edit', '缂栬緫') }}</a-button>
+            <a-button type="link" danger @click="handleDel([record])">{{ formatMessage('page.delete', '鍒犻櫎')
+              }}</a-button>
+          </div>
+        </template>
+      </template>
+    </a-table>
+  </div>
+</template>
+
+<style></style>
\ No newline at end of file
diff --git a/zy-asrs-admin/vite.config.js b/zy-asrs-admin/vite.config.js
new file mode 100644
index 0000000..59bd7cf
--- /dev/null
+++ b/zy-asrs-admin/vite.config.js
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import VueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [
+    VueJsx(),
+    vue(),
+  ],
+  resolve: {
+    alias: {
+      '@': fileURLToPath(new URL('./src', import.meta.url))
+    }
+  }
+})
diff --git a/zy-asrs-framework/src/main/java/com/zy/asrs/framework/generators/VueGenerator.java b/zy-asrs-framework/src/main/java/com/zy/asrs/framework/generators/VueGenerator.java
new file mode 100644
index 0000000..23373e9
--- /dev/null
+++ b/zy-asrs-framework/src/main/java/com/zy/asrs/framework/generators/VueGenerator.java
@@ -0,0 +1,955 @@
+package com.zy.asrs.framework.generators;
+
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.generators.constant.SqlOsType;
+import com.zy.asrs.framework.generators.domain.Column;
+import com.zy.asrs.framework.generators.utils.GeneratorUtils;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.*;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by vincent on 2019-06-18
+ */
+public class VueGenerator {
+
+    private static final String BASE_DIR = "src/main/";
+    private static final String JAVA_DIR = BASE_DIR + "java/";
+    private static final String XML_DIR = BASE_DIR + "resources/mapper/";
+    private static final String HTML_DIR = BASE_DIR + "webapp/";
+    private static final String[] ALL_TEMPLATES = new String[]{
+            "Controller",
+            "Service",
+            "ServiceImpl",
+            "Mapper",
+            "Entity",
+            "Xml",
+            "Index",
+            "Edit",
+            "Sql"};
+    private static final ArrayList<String> SYSTEM_MODEL = new ArrayList<String>(){{
+            add("User");
+            add("Host");
+    }};
+
+
+    public String url;
+    public String username;
+    public String password;
+    public String table;
+    public String tableName;
+    public String packagePath;
+    public boolean controller = true;
+    public boolean service = true;
+    public boolean mapper = true;
+    public boolean entity = true;
+    public boolean xml = true;
+    public boolean vue = true;
+    public boolean sql = true;
+    public SqlOsType sqlOsType;
+    public String backendPrefixPath;
+    public String frontendPrefixPath;
+
+    private List<Column> columns = new ArrayList<>();
+    private String fullEntityName;
+    private String simpleEntityName;
+    private String entityImport;
+    private String entityContent;
+    private String xmlContent;
+    private String htmlContent;
+    private String htmlDialogContent;
+    private String jsTableContent;
+    private String jsForeignKeyContent;
+    private String jsDateContent;
+    private String jsPrimaryKeyDoms;
+    private String primaryKeyColumn;
+    private String majorColumn;
+    private String systemPackagePath;
+    private String systemPackage;
+    private String itemName;
+    private String tableColumns;
+    private String formEditColumns;
+
+    public void build() throws Exception {
+        init();
+        for (String template : ALL_TEMPLATES){
+            boolean pass = false;
+            String lowerCase = template.toLowerCase();
+            String templatePath = lowerCase.contains("impl")?lowerCase.substring(0,lowerCase.length()-4)+"/"+lowerCase.substring(lowerCase.length()-4):lowerCase;
+            String directory="";
+            String fileName="";
+            switch (template){
+                case "Controller":
+                    pass = controller;
+                    directory = backendPrefixPath + JAVA_DIR + packagePath.replace(".", "/")+"/"+templatePath+"/";
+                    fileName = fullEntityName+template+".java";
+                    break;
+                case "Service":
+                    pass = service;
+                    directory = backendPrefixPath + JAVA_DIR + packagePath.replace(".", "/")+"/"+templatePath+"/";
+                    fileName = fullEntityName+template+".java";
+                    break;
+                case "ServiceImpl":
+                    pass = service;
+                    directory = backendPrefixPath + JAVA_DIR + packagePath.replace(".", "/")+"/"+templatePath+"/";
+                    fileName = fullEntityName+template+".java";
+                    break;
+                case "Mapper":
+                    pass = mapper;
+                    directory = backendPrefixPath + JAVA_DIR + packagePath.replace(".", "/")+"/"+templatePath+"/";
+                    fileName = fullEntityName+template+".java";
+                    break;
+                case "Entity":
+                    pass = entity;
+                    directory = backendPrefixPath + JAVA_DIR + packagePath.replace(".", "/")+"/"+templatePath+"/";
+                    fileName = fullEntityName+".java";
+                    break;
+                case "Xml":
+                    pass = xml;
+                    directory = backendPrefixPath + XML_DIR + itemName + "/";
+                    fileName = fullEntityName+"Mapper.xml";
+                    break;
+                case "Sql":
+                    pass = sql;
+                    directory = backendPrefixPath + JAVA_DIR;
+                    fileName = simpleEntityName+".sql";
+                    break;
+                case "Index":
+                    pass = vue;
+                    directory = frontendPrefixPath + "/src/views/" + simpleEntityName + "/";
+                    fileName = "index.vue";
+                    break;
+                case "Edit":
+                    pass = vue;
+                    directory = frontendPrefixPath + "/src/views/" +  simpleEntityName + "/";
+                    fileName = "edit.vue";
+                    break;
+                default:
+                    break;
+            }
+            if (!pass){ continue; }
+            String content = readFile(template);
+            writeFile(content, directory, fileName, template);
+        }
+    }
+
+    private void init() throws Exception {
+        gainDbInfo();
+        fullEntityName = GeneratorUtils.getNameSpace(table);
+        simpleEntityName = fullEntityName.substring(0, 1).toLowerCase()+fullEntityName.substring(1);
+        entityContent = createEntityMsg();
+        htmlContent = createHtmlMsg();
+        htmlDialogContent = createHtmlDialogMsg();
+        jsTableContent = createJsTableMsg();
+        jsForeignKeyContent = createJsFkContent();
+        jsDateContent = createJsDateContent();
+        jsPrimaryKeyDoms = createJsPrimaryKeyMsg();
+        primaryKeyColumn = createPrimaryMsg();
+        majorColumn = createMajorMsg();
+        String[] packagePathSplit = packagePath.split("\\.");
+        systemPackagePath = packagePath.replaceAll(packagePathSplit[packagePathSplit.length-1], "system");
+        String[] split = systemPackagePath.split("\\.");
+        systemPackage = "";
+        for (int i = 1;i <= split.length; i++) {
+            if (i != split.length) {
+                if (i == split.length - 1) {
+                    systemPackage = systemPackage + split[i-1];
+                } else {
+                    systemPackage = systemPackage + split[i-1] + ".";
+                }
+            }
+        }
+        itemName = packagePathSplit[packagePathSplit.length - 1];
+        tableColumns = createTableColumns();
+        formEditColumns = createFormEditColumns();
+    }
+
+    private String readFile(String template){
+        StringBuilder txtContentBuilder=new StringBuilder();
+        ClassPathResource classPath=new ClassPathResource("templates/vue/"+template + ".txt");
+
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(classPath.getInputStream()))) {
+            String lineContent;
+            while ((lineContent = reader.readLine()) != null) {
+                txtContentBuilder.append(lineContent).append("\n");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return txtContentBuilder.toString();
+    }
+
+    private void writeFile(String content, String directory, String fileName, String template) throws IOException {
+        File codeDirectory=new File(directory);
+        if(!codeDirectory.exists()){
+            codeDirectory.mkdirs();
+        }
+
+        File writerFile=new File(directory+fileName);
+        if(!writerFile.exists()){
+            content=content.
+                    replaceAll("@\\{TABLENAME}", table)
+                    .replaceAll("@\\{TABLEDESC}", tableName)
+                    .replaceAll("@\\{ENTITYIMPORT}", entityImport)
+                    .replaceAll("@\\{ENTITYCONTENT}", entityContent)
+                    .replaceAll("@\\{ENTITYNAME}", fullEntityName)
+                    .replaceAll("@\\{SIMPLEENTITYNAME}", simpleEntityName)
+                    .replaceAll("@\\{UENTITYNAME}", simpleEntityName)
+                    .replaceAll("@\\{COMPANYNAME}",packagePath)
+                    .replaceAll("@\\{ITEMNAME}",itemName)
+//                    .replaceAll("@\\{XMLCONTENT}", xmlContent)
+                    .replaceAll("@\\{HTMLCONTENT}", htmlContent)
+                    .replaceAll("@\\{HTMLDIALOGCONTENT}", htmlDialogContent)
+                    .replaceAll("@\\{JSTABLECONTENT}", jsTableContent)
+                    .replaceAll("@\\{JSFOREIGNKEYCONTENT}", jsForeignKeyContent)
+                    .replaceAll("@\\{JSDATECONTENT}", jsDateContent)
+                    .replaceAll("@\\{JSPRIMARYKEYDOMS}", jsPrimaryKeyDoms)
+                    .replaceAll("@\\{MAJORCOLUMN}", GeneratorUtils.humpToLine(majorColumn))
+                    .replaceAll("@\\{MAJORCOLUMN0}", GeneratorUtils.firstCharConvert(majorColumn, false))
+                    .replaceAll("@\\{MAJORCOLUMN_UP}", GeneratorUtils.firstCharConvert(majorColumn, false))
+                    .replaceAll("@\\{PRIMARYKEYCOLUMN}", GeneratorUtils.firstCharConvert(primaryKeyColumn, false))
+                    .replaceAll("@\\{PRIMARYKEYCOLUMN0}", GeneratorUtils.firstCharConvert(primaryKeyColumn, true))
+                    .replaceAll("@\\{UPCASEMARJORCOLUMN}", GeneratorUtils.firstCharConvert(primaryKeyColumn, false))
+                    .replaceAll("@\\{SYSTEMPACKAGE}",systemPackage)
+                    .replaceAll("@\\{TABLECOLUMNS}", tableColumns)
+                    .replaceAll("@\\{FORMEDITCOLUMNS}", formEditColumns)
+            ;
+            writerFile.createNewFile();
+            BufferedWriter writer=new BufferedWriter(new FileWriter(writerFile));
+            writer.write(content);
+            writer.flush();
+            writer.close();
+            System.out.println(fullEntityName+template+" 婧愭枃浠跺垱寤烘垚鍔燂紒");
+        }else{
+            System.out.println(fullEntityName+template+" 婧愭枃浠跺凡缁忓瓨鍦ㄥ垱寤哄け璐ワ紒");
+        }
+    }
+
+    private void gainDbInfo() throws Exception {
+        Connection conn;
+        if (null == this.sqlOsType) {
+            throw new RuntimeException("璇烽�夋嫨sqlOsType锛�");
+        }
+        if (null == this.table) {
+            throw new RuntimeException("璇疯緭鍏able锛�");
+        }
+        if (null == this.tableName) {
+            throw new RuntimeException("璇疯緭鍏ableName锛�");
+        }
+        switch (this.sqlOsType) {
+            case MYSQL:
+                Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
+                conn = DriverManager.getConnection("jdbc:mysql://"+url, username, password);
+                this.columns = getMysqlColumns(conn, table, true, sqlOsType);
+                break;
+            case SQL_SERVER:
+                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
+                conn = DriverManager.getConnection("jdbc:sqlserver://"+url, username, password);
+                this.columns = getSqlServerColumns(conn, table, true, sqlOsType);
+                break;
+            default:
+                throw new RuntimeException("璇锋寚瀹氭暟鎹簱绫诲瀷锛�");
+        }
+
+    }
+
+    // mysql
+    public static List<Column> getMysqlColumns(Connection conn, String table, boolean init, SqlOsType sqlOsType) throws Exception {
+        List<Column> result = new ArrayList<>();
+        PreparedStatement ps = conn.prepareStatement("select * from " + table);
+        ResultSetMetaData meta = ps.executeQuery().getMetaData();
+        // 鍗曡〃瀛楁鏁伴噺
+        int count = meta.getColumnCount();
+        ResultSet resultSet = ps.executeQuery("show full columns from " + table);
+        for (int i = 1; i < count + 1; i++) {
+            String columnName = meta.getColumnName(i);
+            if (resultSet.next() && columnName.equals(resultSet.getString("Field"))){
+                result.add(new Column(
+                        conn,
+                        meta.getColumnName(i),
+                        GeneratorUtils.getType(meta.getColumnType(i)),
+                        resultSet.getString("Comment"),
+                        resultSet.getString("Key").equals("PRI"),
+                        resultSet.getString("Key").equals("PRI"),
+                        resultSet.getString("Null").equals("NO"),
+                        GeneratorUtils.getColumnLength(resultSet.getString("Type")),
+                        init,
+                        sqlOsType
+                ));
+            }
+            result.forEach(column -> System.out.println(column.toString()));
+        }
+        return result;
+    }
+
+    // sqlserver
+    public static List<Column> getSqlServerColumns(Connection conn, String table, boolean init, SqlOsType sqlOsType) throws Exception {
+        List<Column> result = new ArrayList<>();
+        PreparedStatement ps = conn.prepareStatement("select * from " + table);
+        ResultSetMetaData meta = ps.executeQuery().getMetaData();
+        // 鍗曡〃瀛楁鏁伴噺
+        int count = meta.getColumnCount();
+        StringBuilder sql = new StringBuilder("SELECT \n" +
+                "       'Field'= a.name,\n" +
+                "       'Comment'= isnull(g.[value],''),\n" +
+                "       'Key'= case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then 'PRI' else '' end,\n" +
+                "       'Main'= case when exists(SELECT 1 FROM sysobjects where xtype='PK' and parent_obj=a.id and name in (SELECT name FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid))) then 'PRI' else '' end,"+
+                "       'Type'= b.name,\n" +
+                "       'Length'= COLUMNPROPERTY(a.id,a.name,'PRECISION'),\n" +
+                "       'Decimals'= isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0),\n" +
+                "       'Null'= case when a.isnullable=1 then 'Yes' else 'No' end,\n" +
+                "       'Default' = isnull(e.text,'')\n" +
+                "FROM  syscolumns a\n" +
+                "LEFT JOIN  systypes b on a.xusertype=b.xusertype\n" +
+                "INNER JOIN sysobjects d on  a.id=d.id  and d.xtype='U' and  d.name<>'dtproperties'\n" +
+                "LEFT JOIN  syscomments e on  a.cdefault=e.id\n" +
+                "LEFT JOIN  sys.extended_properties g on  a.id=G.major_id and a.colid=g.minor_id  \n" +
+                "LEFT JOIN  sys.extended_properties f on  d.id=f.major_id and f.minor_id=0 where d.name = '")
+                .append(table).append("' ORDER BY a.colorder ASC");
+        ResultSet resultSet = conn.prepareStatement(sql.toString()).executeQuery();
+        for (int i = 1; i < count + 1; i++) {
+            String columnName = meta.getColumnName(i);
+            if (resultSet.next() && columnName.equals(resultSet.getString("Field"))){
+                result.add(new Column(
+                        conn,
+                        meta.getColumnName(i),
+                        GeneratorUtils.getType(meta.getColumnType(i)),
+                        resultSet.getString("Comment"),
+                        resultSet.getString("Key").equals("PRI"),
+                        resultSet.getString("Main").equals("PRI"),
+                        resultSet.getString("Null").equals("No"),
+                        GeneratorUtils.getColumnLength(resultSet.getString("Type")),
+                        init,
+                        sqlOsType
+                ));
+            }
+        }
+        result.forEach(column -> System.out.println(column.toString()));
+        return result;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    /**********************************************************************************************/
+    /************************************* Entity鍔ㄦ�佸瓧娈� *******************************************/
+    /**********************************************************************************************/
+
+    private String createEntityMsg(){
+        if (Cools.isEmpty(systemPackagePath)) {
+            String[] packagePathSplit = packagePath.split("\\.");
+            systemPackagePath = packagePath.replaceAll(packagePathSplit[packagePathSplit.length-1], "system");
+        }
+        if (columns.isEmpty()){
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        StringBuilder entityIm = new StringBuilder();
+        boolean setTableField = true;
+        boolean setTableId = true;
+        boolean setDateTimeFormat = true;
+        for (Column column : columns){
+            if (column.getType().equals("Date")){
+                entityIm.append("import java.text.SimpleDateFormat;\n")
+                        .append("import java.util.Date;\n");
+            }
+
+            // 娉ㄩ噴
+            if (!Cools.isEmpty(column.getComment())){
+                sb.append("    /**\n")
+                        .append("     * ")
+                        .append(column.getWholeComment())
+                        .append("\n")
+                        .append("     */")
+                        .append("\n");
+            }
+
+            // swagger
+            sb.append("    @ApiModelProperty(value= \"")
+                    .append(column.getWholeComment())
+                    .append("\")\n");
+
+
+            // 涓婚敭淇グ
+            if (column.isMainKey()){
+                if (column.isOnly()){
+                    sb.append("    ")
+                            .append("@TableId(value = \"")
+                            .append(column.getName())
+                            .append("\", type = IdType.AUTO)")
+                            .append("\n");
+                } else {
+                    sb.append("    ")
+                            .append("@TableId(value = \"")
+                            .append(column.getName())
+                            .append("\", type = IdType.INPUT)")
+                            .append("\n");
+                }
+
+            }
+
+            if (column.getName().equals("deleted")) {
+                entityIm.append("import com.baomidou.mybatisplus.annotation.TableLogic;\n");
+                sb.append("    ")
+                        .append("@TableLogic\n");
+            }
+
+            if ("Date".equals(column.getType())){
+                if (setDateTimeFormat){
+                    entityIm.append("import org.springframework.format.annotation.DateTimeFormat;").append("\n");
+                    setDateTimeFormat = false;
+                }
+                sb.append("    ")
+                        .append("@DateTimeFormat(pattern=\"yyyy-MM-dd HH:mm:ss\")")
+                        .append("\n");
+            }
+
+            sb.append("    ")
+                    .append("private ")
+                    .append(column.getType())
+                    .append(" ")
+                    .append(column.getHumpName())
+                    .append(";")
+                    .append("\n")
+                    .append("\n");
+        }
+
+        // default constructor
+        sb.append("    public ").append(fullEntityName).append("() {}\n\n");
+        // full constructor
+        sb.append("    public ").append(fullEntityName).append("(");
+        for (Column column : columns){
+            if (column.isOnly()){ continue;}
+            sb.append(column.getType()).append(" ").append(column.getHumpName()).append(",");
+        }
+        sb.deleteCharAt(sb.length()-1);
+        sb.append(") {\n");
+        for (Column column : columns){
+            if (column.isPrimaryKey()){ continue;}
+            sb.append("        this.").append(column.getHumpName()).append(" = ").append(column.getHumpName()).append(";\n");
+        }
+        sb.append("    }\n\n");
+        // constructor tips
+        sb.append("//    ").append(fullEntityName).append(" ").append(simpleEntityName).append(" = new ").append(fullEntityName).append("(\n");
+        for (int i = 0; i<columns.size(); i++) {
+            if (columns.get(i).isOnly()){ continue;}
+            sb.append("//            null");
+            if (i < columns.size()-1){
+                sb.append(",");
+            }
+            sb.append("    // ").append(columns.get(i).getComment()).append(columns.get(i).isNotNull()?"[闈炵┖]":"");
+            if (i < columns.size()-1){
+                sb.append("\n");
+            }
+        }
+        sb.append("\n//    );\n\n");
+
+        // get set
+        for (Column column : columns){
+            // 鏃堕棿瀛楁澧炲姞$鏍煎紡鍖�
+            if ("Date".equals(column.getType())){
+                sb.append("    public String get")
+                        .append(column.getHumpName().substring(0, 1).toUpperCase()).append(column.getHumpName().substring(1))
+                        .append("\\$")
+                        .append("(){\n")
+                        .append("        if (Cools.isEmpty(this.").append(column.getHumpName()).append(")){\n")
+                        .append("            return \"\";\n")
+                        .append("        }\n")
+                        .append("        return new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").format(this.")
+                        .append(column.getHumpName())
+                        .append(");\n")
+                        .append("    }\n\n");
+                // 鏋氫妇瀛楁澧炲姞$鏍煎紡鍖�
+            } else if (!Cools.isEmpty(column.getEnums())){
+                sb.append("    public String get")
+                        .append(column.getHumpName().substring(0, 1).toUpperCase()).append(column.getHumpName().substring(1))
+                        .append("\\$")
+                        .append("(){\n")
+                        .append("        if (null == this.").append(column.getHumpName()).append("){ return null; }\n")
+                        .append("        switch (this.").append(column.getHumpName()).append("){\n");
+                for (Map<String, Object> map : column.getEnums()){
+                    for (Map.Entry<String, Object> entry : map.entrySet()){
+                        sb.append("            case ").append(entry.getKey()).append(":\n")
+                                .append("                return \"").append(entry.getValue()).append("\";\n");
+                    }
+                }
+                sb.append("            default:\n")
+                        .append("                return String.valueOf(this.").append(column.getHumpName()).append(");\n")
+                        .append("        }\n")
+                        .append("    }\n\n");
+            }
+
+            // 澶栭敭淇グ
+            if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                sb.append("    public String get").append(column.getHumpName().substring(0, 1).toUpperCase()).append(column.getHumpName().substring(1)).append("\\$").append("(){\n")
+                        .append("        ").append(column.getForeignKey()).append("Service service = SpringUtils.getBean(").append(column.getForeignKey()).append("Service.class);\n")
+                        .append("        ").append(column.getForeignKey()).append(" ").append(GeneratorUtils.firstCharConvert(column.getForeignKey()))
+                        .append(" = service.getById(this.").append(column.getHumpName()).append(");\n")
+                        .append("        if (!Cools.isEmpty(").append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append(")){\n")
+                        .append("            return String.valueOf(").append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append(".get").append(column.getForeignKeyMajor()).append("());\n")
+                        .append("        }\n")
+                        .append("        return null;\n")
+                        .append("    }\n\n");
+            }
+
+        }
+        entityImport = entityIm.toString();
+        return sb.toString();
+    }
+
+    /**********************************************************************************************/
+    /*********************************** Controller鍔ㄦ�佸瓧娈� *****************************************/
+    /**********************************************************************************************/
+
+    private String createPrimaryMsg(){
+        String defaultMajor = "id";
+        boolean havePrimary = false;
+        for (Column column: columns){
+            if (column.isPrimaryKey()){
+                defaultMajor = column.getHumpName();
+                havePrimary = true;
+            }
+        }
+        if (!havePrimary) {
+            for (Column column: columns){
+                if (column.isMainKey()){
+                    defaultMajor = column.getHumpName();
+                }
+            }
+        }
+        return defaultMajor;
+    }
+
+    private String createMajorMsg(){
+        String defaultMajor = "id";
+        for (Column column: columns){
+            if (column.isPrimaryKey()){
+                defaultMajor = column.getHumpName();
+            }
+            if (column.isMajor()){
+                return column.getHumpName();
+            }
+        }
+        return defaultMajor;
+    }
+
+    /**********************************************************************************************/
+    /************************************** Html鍔ㄦ�佸瓧娈� *******************************************/
+    /**********************************************************************************************/
+
+    private String createHtmlMsg(){
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns){
+            if (column.isPrimaryKey()){ continue;}
+            if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                sb.append("    <div class=\"layui-inline\">\n")
+                        .append("        <div class=\"layui-input-inline cool-auto-complete\">\n")
+                        .append("            <input id=\"").append(column.getHumpName()).append("\"")
+                        .append(" class=\"layui-input\" name=\"").append(column.getName()).append("\" type=\"text\" placeholder=\"璇疯緭鍏" autocomplete=\"off\" style=\"display: none\">\n")
+                        .append("            <input id=\"").append(column.getHumpName()).append("\\$")
+                        .append("\" class=\"layui-input cool-auto-complete-div\" onclick=\"autoShow(this.id)\" type=\"text\" placeholder=\"").append(GeneratorUtils.supportHtmlName(column.getComment())).append("\" onfocus=this.blur()>\n")
+                        .append("            <div class=\"cool-auto-complete-window\">\n")
+                        .append("                <input class=\"cool-auto-complete-window-input\" data-key=\"").append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append("Query").append("By").append(column.getHumpName()).append("\" onkeyup=\"autoLoad(this.getAttribute('data-key'))\">\n")
+                        .append("                <select class=\"cool-auto-complete-window-select\" data-key=\"").append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append("Query").append("By").append(column.getHumpName()).append("Select\" onchange=\"confirmed(this.getAttribute('data-key'))\" multiple=\"multiple\">\n")
+                        .append("                </select>\n")
+                        .append("            </div>\n")
+                        .append("        </div>\n")
+                        .append("    </div>\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    private String createHtmlDialogMsg() {
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns){
+            if (column.isPrimaryKey()) {
+                continue;
+            }
+            sb.append("                <div class=\"layui-form-item\">\n");
+            sb.append("                    <label class=\"layui-form-label");
+            if (column.isNotNull()){
+                sb.append(" layui-form-required");
+            }
+            sb.append("\">").append(column.getComment()).append(": </label>\n");
+            sb.append("                    <div class=\"layui-input-block");
+            // 鍏宠仈澶栭敭
+            if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                sb.append(" cool-auto-complete");
+            }
+            sb.append("\">\n");
+            // 杈撳叆妗嗙被鍨�
+            if (Cools.isEmpty(column.getEnums())){
+                sb.append("                        <input class=\"layui-input\" name=\"").append(column.getHumpName());
+                if ("Date".equals(column.getType())){
+                    sb.append("\" id=\"").append(column.getHumpName()).append("\\$");
+                }
+                sb.append("\" placeholder=\"璇疯緭鍏�").append(column.getComment()).append("\"");
+                if (column.isNotNull()){
+                    sb.append(" lay-vertype=\"tips\" lay-verify=\"required\"");
+                }
+                // 鍏宠仈澶栭敭
+                if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                    sb.append(" style=\"display: none\"");
+                }
+                sb.append(">\n");
+
+                // 鍏宠仈澶栭敭
+                if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                    sb.append("                        <input id=\"").append(column.getHumpName()).append("\\$").append("\" name=\"").append(column.getHumpName()).append("\\$")
+                            .append("\" class=\"layui-input cool-auto-complete-div\" onclick=\"autoShow(this.id)\" type=\"text\" placeholder=\"璇疯緭鍏�").append(column.getComment()).append("\" onfocus=this.blur()>\n");
+                    sb.append("                        <div class=\"cool-auto-complete-window\">\n")
+                            .append("                            <input class=\"cool-auto-complete-window-input\" data-key=\"")
+                            .append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append("Query").append("By").append(column.getHumpName()).append("\" onkeyup=\"autoLoad(this.getAttribute('data-key'))\">\n")
+                            .append("                            <select class=\"cool-auto-complete-window-select\" data-key=\"").append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append("Query").append("By").append(column.getHumpName()).append("Select\" onchange=\"confirmed(this.getAttribute('data-key'))\" multiple=\"multiple\">\n")
+                            .append("                            </select>\n")
+                            .append("                        </div>\n");
+                }
+            // 鏋氫妇绫诲瀷
+            } else {
+                sb.append("                        <select name=\"").append(column.getHumpName()).append("\"");
+                if (column.isNotNull()){
+                    sb.append(" lay-vertype=\"tips\" lay-verify=\"required\"");
+                }
+                sb.append(">\n");
+                sb.append("                            <option value=\"\">").append("璇烽�夋嫨").append(column.getComment()).append("</option>\n");
+                for (Map<String, Object> map : column.getEnums()){
+                    for (Map.Entry<String, Object> entry : map.entrySet()){
+                        sb.append("                            <option value=\"")
+                                .append(entry.getKey())
+                                .append("\">")
+                                .append(entry.getValue())
+                                .append("</option>\n");
+                    }
+                }
+                sb.append("                        </select>\n");
+            }
+
+            sb.append("                    </div>\n");
+            sb.append("                </div>\n");
+        }
+        return sb.toString();
+    }
+
+    private String createJsTableMsg(){
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns){
+//            if (column.isPrimaryKey()){ continue;}
+            sb.append("            ,{field: '");
+            if ("Date".equals(column.getType()) || !Cools.isEmpty(column.getEnums())){
+                // 鏃堕棿銆佹灇涓�  鏍煎紡鍖�
+                sb.append(column.getHumpName()).append("\\$");
+            } else {
+                // 涓婚敭淇グ
+                if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                    sb.append(column.getHumpName()).append("\\$");
+                } else {
+                    sb.append(column.getHumpName());
+                }
+            }
+            sb.append("', align: 'center',title: '").append(column.getComment()).append("'");
+            // 澶嶉�夋
+            if (column.isCheckBox()){
+                sb.append(", templet:function(row){\n")
+                        .append("                    var html = \"<input value='")
+                        .append(column.getHumpName()).append("' type='checkbox' lay-skin='primary' lay-filter='tableCheckbox' table-index='\"+row.LAY_TABLE_INDEX+\"'\";\n")
+                        .append("                    if(row.").append(column.getHumpName()).append(" === 'Y'){html += \" checked \";}\n")
+                        .append("                    html += \">\";\n")
+                        .append("                    return html;\n")
+                        .append("                }");
+            }
+            sb.append("}\n");
+        }
+        return sb.toString();
+    }
+
+    private String createJsFkContent(){
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns){
+            // 濡傛灉鏈夊叧鑱斿鍋�
+            if (!Cools.isEmpty(column.getForeignKeyMajor())){
+                sb.append("    window.load").append(column.getForeignKey()).append("Sel = function () {").append("\n")
+                        .append("        return xmSelect.render({").append("\n")
+                        .append("            el: '#").append(GeneratorUtils.firstCharConvert(column.getForeignKey(), true)).append("XmlSel',").append("\n")
+                        .append("            autoRow: true,").append("\n")
+                        .append("            filterable: true,").append("\n")
+                        .append("            remoteSearch: true,").append("\n")
+                        .append("            radio: true,").append("\n")
+                        .append("            remoteMethod: function (val, cb, show) {").append("\n")
+                        .append("                \\$.ajax({").append("\n")
+                        .append("                    url: baseUrl + \"/").append(GeneratorUtils.firstCharConvert(column.getForeignKey(), true)).append("/all/get/kv\",").append("\n")
+                        .append("                    headers: {'token': localStorage.getItem('token')},").append("\n")
+                        .append("                    data: {").append("\n")
+                        .append("                        condition: val").append("\n")
+                        .append("                    },").append("\n")
+                        .append("                    method: 'POST',").append("\n")
+                        .append("                    success: function (res) {").append("\n")
+                        .append("                        if (res.code === 200) {").append("\n")
+                        .append("                            cb(res.data)").append("\n")
+                        .append("                        } else {").append("\n")
+                        .append("                            cb([]);").append("\n")
+                        .append("                            layer.msg(res.msg, {icon: 2});").append("\n")
+                        .append("                        }").append("\n")
+                        .append("                    }").append("\n")
+                        .append("                });").append("\n")
+                        .append("            }").append("\n")
+                        .append("        });").append("\n")
+                        .append("    }").append("\n")
+                        .append("\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    private String createJsDateContent(){
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                continue;
+            }
+            if ("Date".equals(column.getType())){
+                sb.append("            layDate.render({\n")
+                        .append("                elem: '#").append(column.getHumpName()).append("\\\\\\\\\\$',\n")
+                        .append("                type: 'datetime',\n")
+                        .append("                value: data!==undefined?data['").append(column.getHumpName()).append("\\$'").append("]:null\n")
+                        .append("            });\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    private String createJsPrimaryKeyMsg(){
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                sb.append("#").append(column.getHumpName()).append(",");
+            }
+        }
+        if (sb.length() > 1){
+            if (sb.substring(sb.length() - 1).equals(",")) {
+                sb.deleteCharAt(sb.length()-1);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**********************************************************************************************/
+    /************************************** Index鍔ㄦ�佸瓧娈� *******************************************/
+    /**********************************************************************************************/
+
+    private String createTableColumns() {
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns) {
+            if (column.isPrimaryKey()
+                    || column.getHumpName().equals("deleted")
+                    || column.getHumpName().equals("hostId")
+            ) {
+                continue;
+            }
+            sb.append("        {\n")
+                    .append("            title: '").append(column.getComment()).append("',\n")
+                    .append("            dataIndex: '");
+            if ("Date".equals(column.getType()) || !Cools.isEmpty(column.getEnums()) || !Cools.isEmpty(column.getForeignKeyMajor())){
+                // 鏃堕棿銆佹灇涓�  鏍煎紡鍖�  涓婚敭淇グ
+                sb.append(column.getHumpName()).append("\\$");
+            } else {
+                sb.append(column.getHumpName());
+            }
+            sb.append("',\n")
+                    .append("            width: 140,\n");
+            if (!Cools.isEmpty(column.getEnums())) {
+                sb.append("                customRender: (column) => {\n");
+                sb.append("                  let typeMap = {");
+                for (Map<String, Object> map : column.getEnums()) {
+                    for (Map.Entry<String, Object> entry : map.entrySet()){
+                        sb.append("                    ").append(entry.getKey()).append(": ");
+                        sb.append("                    { text: '").append(entry.getValue()).append("'").append(" },\n");
+                    }
+                }
+                sb.append("                }\n");
+                sb.append("                }\n");
+            }
+            sb.append("        },\n");
+        }
+        return sb.toString();
+    }
+
+    private String getAntProFilterType(Column column){
+        String filter = "TextFilter";
+        switch (column.getType()) {
+            case "Boolean":
+                filter = "TextFilter";
+                break;
+            case "Short":
+                filter = "TextFilter";
+                break;
+            case "Integer":
+                filter = "TextFilter";
+                break;
+            case "Long":
+                filter = "TextFilter";
+                break;
+            case "Double":
+                filter = "TextFilter";
+                break;
+            case "String":
+                filter = "TextFilter";
+                break;
+            case "Date":
+                filter = "DatetimeRangeFilter";
+                break;
+            default:
+                break;
+        }
+        if (!Cools.isEmpty(column.getEnums())) {
+            filter = "SelectFilter";
+        }
+        if (!Cools.isEmpty(column.getForeignKey())) {
+            filter = "LinkFilter";
+        }
+        return filter;
+    }
+
+    /**********************************************************************************************/
+    /************************************** Edit鍔ㄦ�佸瓧娈� ********************************************/
+    /**********************************************************************************************/
+
+    private String createFormEditColumns() {
+        StringBuilder sb = new StringBuilder();
+        int times = 0;
+        boolean has = false;boolean init = false;
+        for (Column column : columns) {
+            if (column.isPrimaryKey()
+                    || column.getHumpName().equals("deleted")
+                    || column.getHumpName().equals("hostId")
+            ) {
+                continue;
+            }
+            if (times%2 == 0) {
+                sb.append("                    <ProForm.Group>\n");
+                has = true;init=true;
+            }
+
+            String itemType = "ProFormText";
+            String precision = "";
+            switch (column.getType()) {
+                case "Boolean":
+                    itemType = "ProFormText";
+                    break;
+                case "Short":
+                    itemType = "ProFormDigit";
+                    precision = "0";
+                    break;
+                case "Integer":
+                    itemType = "ProFormDigit";
+                    precision = "0";
+                    break;
+                case "Long":
+                    itemType = "ProFormDigit";
+                    precision = "0";
+                    break;
+                case "Double":
+                    itemType = "ProFormDigit";
+                    precision = "2";
+                    break;
+                case "String":
+                    itemType = "ProFormText";
+                    break;
+                case "Date":
+                    itemType = "ProFormDateTimePicker";
+                    break;
+                default:
+                    break;
+            }
+            if (!Cools.isEmpty(column.getEnums())) {
+                itemType = "ProFormSelect";
+            }
+            if (!Cools.isEmpty(column.getForeignKey())) {
+                itemType = "ProFormSelect";
+            }
+
+            sb.append("                        <").append(itemType).append("\n")
+                    .append("                            name=\"").append(column.getHumpName()).append("\"\n")
+                    .append("                            label=\"").append(column.getComment()).append("\"\n")
+                    .append("                            colProps={{ md: 12, xl: 12 }}\n");
+            // 鏁板瓧灏忔暟鐐�
+            if (!Cools.isEmpty(precision) && Cools.isEmpty(column.getEnums())) {
+                sb.append("                            fieldProps={{ precision: ").append(precision).append(" }}\n");
+            }
+
+            // 闈炵┖
+            if (column.isNotNull()) {
+                sb.append("                            rules={[{ required: true }]}\n");
+            }
+
+            // 鏋氫妇
+            if (!Cools.isEmpty(column.getEnums())) {
+                sb.append("                            options={[\n");
+                for (Map<String, Object> map : column.getEnums()) {
+                    for (Map.Entry<String, Object> entry : map.entrySet()){
+                        sb.append("                                { label: '").append(entry.getValue()).append("', value: ").append(entry.getKey()).append(" },\n");
+                    }
+                }
+                sb.append("                            ]}\n");
+            }
+
+            // 鏃堕棿
+            if ("Date".equals(column.getType())) {
+                sb.append("                            transform={(value) => moment(value).toISOString()}\n");
+            }
+
+            // 鍏宠仈琛�
+            if (!Cools.isEmpty(column.getForeignKey())) {
+                sb.append("                            showSearch\n")
+                        .append("                            debounceTime={300}\n")
+                        .append("                            request={async ({ keyWords }) => {\n")
+                        .append("                                const resp = await Http.doPostForm('api/").append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append("/query', { condition: keyWords });\n")
+                        .append("                                return resp.data;\n")
+                        .append("                            }}\n");
+            }
+
+            sb.append("                        />\n");
+
+            if (times%2 != 0) {
+                sb.append("                    </ProForm.Group>\n");
+                has = false;
+            }
+            times++;
+        }
+        if (init && has) {
+            sb.append("                    </ProForm.Group>\n");
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Controller.txt b/zy-asrs-framework/src/main/resources/templates/vue/Controller.txt
new file mode 100644
index 0000000..d505653
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Controller.txt
@@ -0,0 +1,101 @@
+package com.zy.asrs.wms.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.R;
+import com.zy.asrs.wms.common.annotation.OperationLog;
+import com.zy.asrs.wms.common.domain.BaseParam;
+import com.zy.asrs.wms.common.domain.KeyValVo;
+import com.zy.asrs.wms.common.domain.PageParam;
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import @{COMPANYNAME}.service.@{ENTITYNAME}Service;
+import com.zy.asrs.wms.utils.ExcelUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+public class @{ENTITYNAME}Controller extends BaseController {
+
+    @Autowired
+    private @{ENTITYNAME}Service @{SIMPLEENTITYNAME}Service;
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:list')")
+    @PostMapping("/@{SIMPLEENTITYNAME}/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<@{ENTITYNAME}, BaseParam> pageParam = new PageParam<>(baseParam, @{ENTITYNAME}.class);
+        return R.ok().add(@{SIMPLEENTITYNAME}Service.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:list')")
+    @PostMapping("/@{SIMPLEENTITYNAME}/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(@{SIMPLEENTITYNAME}Service.list());
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:list')")
+    @GetMapping("/@{SIMPLEENTITYNAME}/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(@{SIMPLEENTITYNAME}Service.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:save')")
+    @OperationLog("娣诲姞@{TABLEDESC}")
+    @PostMapping("/@{SIMPLEENTITYNAME}/save")
+    public R save(@RequestBody @{ENTITYNAME} @{SIMPLEENTITYNAME}) {
+        if (!@{SIMPLEENTITYNAME}Service.save(@{SIMPLEENTITYNAME})) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:update')")
+    @OperationLog("淇敼@{TABLEDESC}")
+    @PostMapping("/@{SIMPLEENTITYNAME}/update")
+    public R update(@RequestBody @{ENTITYNAME} @{SIMPLEENTITYNAME}) {
+        if (!@{SIMPLEENTITYNAME}Service.updateById(@{SIMPLEENTITYNAME})) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:remove')")
+    @OperationLog("鍒犻櫎@{TABLEDESC}")
+    @PostMapping("/@{SIMPLEENTITYNAME}/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!@{SIMPLEENTITYNAME}Service.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:list')")
+    @PostMapping("/@{SIMPLEENTITYNAME}/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<@{ENTITYNAME}> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(@{ENTITYNAME}::get@{MAJORCOLUMN_UP}, condition);
+        }
+        @{SIMPLEENTITYNAME}Service.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getId(), item.get@{MAJORCOLUMN_UP}()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('@{ITEMNAME}:@{SIMPLEENTITYNAME}:list')")
+    @PostMapping("/@{SIMPLEENTITYNAME}/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(@{SIMPLEENTITYNAME}Service.list(), @{ENTITYNAME}.class), response);
+    }
+
+}
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Edit.txt b/zy-asrs-framework/src/main/resources/templates/vue/Edit.txt
new file mode 100644
index 0000000..cf8b9f5
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Edit.txt
@@ -0,0 +1,72 @@
+import React, { useState, useRef, useEffect } from 'react';
+import {
+    ProForm,
+    ProFormDigit,
+    ProFormText,
+    ProFormSelect,
+    ProFormDateTimePicker
+} from '@ant-design/pro-components';
+import { Form, Modal } from 'antd';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import moment from 'moment';
+import Http from '@/utils/http';
+
+const Edit = (props) => {
+    const intl = useIntl();
+    const [form] = Form.useForm();
+    const { } = props;
+
+    useEffect(() => {
+        form.resetFields();
+        form.setFieldsValue({
+            ...props.values
+        })
+    }, [form, props])
+
+    const handleCancel = () => {
+        props.onCancel();
+    };
+
+    const handleOk = () => {
+        form.submit();
+    }
+
+    const handleFinish = async (values) => {
+        props.onSubmit({ ...values });
+    }
+
+    return (
+        <>
+            <Modal
+                title={
+                    Object.keys(props.values).length > 0
+                        ? intl.formatMessage({ id: 'page.edit', defaultMessage: '缂栬緫' })
+                        : intl.formatMessage({ id: 'page.add', defaultMessage: '娣诲姞' })
+                }
+                width={640}
+                forceRender
+                destroyOnClose
+                open={props.open}
+                onCancel={handleCancel}
+                onOk={handleOk}
+            >
+                <ProForm
+                    form={form}
+                    submitter={false}
+                    onFinish={handleFinish}
+                    layout="horizontal"
+                    grid={true}
+                >
+                    <ProFormDigit
+                        name="id"
+                        disabled
+                        hidden={true}
+                    />
+@{FORMEDITCOLUMNS}
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
\ No newline at end of file
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Entity.txt b/zy-asrs-framework/src/main/resources/templates/vue/Entity.txt
new file mode 100644
index 0000000..c8c054a
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Entity.txt
@@ -0,0 +1,26 @@
+package @{COMPANYNAME}.entity;
+
+@{ENTITYIMPORT}
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.SpringUtils;
+import com.zy.asrs.wms.system.service.UserService;
+import com.zy.asrs.wms.system.service.HostService;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("@{TABLENAME}")
+public class @{ENTITYNAME} implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+@{ENTITYCONTENT}
+}
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Index.txt b/zy-asrs-framework/src/main/resources/templates/vue/Index.txt
new file mode 100644
index 0000000..093d3a0
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Index.txt
@@ -0,0 +1,181 @@
+<script setup>
+import { getCurrentInstance, ref, computed, reactive } from 'vue';
+import { useRouter } from "vue-router";
+import { get, post, postBlob } from '@/utils/request.js'
+import { message, Modal } from 'ant-design-vue';
+import { logout } from '@/config.js';
+import EditView from './edit.vue'
+import { formatMessage } from '@/utils/localeUtils.js';
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+
+const router = useRouter();
+
+const TABLE_KEY = 'table-@{SIMPLEENTITYNAME}';
+let currentPage = 1;
+let pageSize = 10;
+const searchInput = ref("")
+const editChild = ref(null)
+
+let tableData = ref([]);
+getPage();
+
+const columns = [
+@{TABLECOLUMNS}
+  {
+    title: '鎿嶄綔',
+    name: 'oper',
+    dataIndex: 'oper',
+    key: 'oper',
+  },
+];
+
+const state = reactive({
+  selectedRowKeys: [],
+  loading: false,
+});
+const hasSelected = computed(() => state.selectedRowKeys.length > 0);
+const start = () => {
+  state.loading = true;
+  // ajax request after empty completing
+  setTimeout(() => {
+    state.loading = false;
+    state.selectedRowKeys = [];
+  }, 1000);
+};
+const onSelectChange = selectedRowKeys => {
+  // console.log('selectedRowKeys changed: ', selectedRowKeys);
+  state.selectedRowKeys = selectedRowKeys;
+};
+
+function getPage() {
+  post('/api/@{SIMPLEENTITYNAME}/page', {
+    current: currentPage,
+    pageSize: pageSize,
+    condition: searchInput.value
+  }).then((resp) => {
+    let result = resp.data;
+    if (result.code == 200) {
+      let data = result.data;
+      tableData.value = data;
+    } else if (result.code === 401) {
+      message.error(result.msg);
+      logout()
+    } else {
+      message.error(result.msg);
+    }
+  })
+}
+
+const handleEdit = (item) => {
+  editChild.value.open = true;
+  editChild.value.formData = item == null ? editChild.value.initFormData : JSON.parse(JSON.stringify(item));
+  editChild.value.isSave = item == null;
+}
+
+const handleDel = (rows) => {
+  Modal.confirm({
+    title: formatMessage('page.delete', '鍒犻櫎'),
+    content: formatMessage('page.delete.confirm', '纭畾鍒犻櫎璇ラ」鍚楋紵'),
+    maskClosable: true,
+    onOk: async () => {
+      post('/api/@{SIMPLEENTITYNAME}/remove/' + rows.map((row) => row.id).join(','), {}).then(resp => {
+        let result = resp.data;
+        if (result.code === 200) {
+          message.success(result.msg);
+        } else {
+          message.error(result.msg);
+        }
+        getPage()
+      })
+    },
+  });
+}
+
+const handleExport = async (intl) => {
+  postBlob('/api/@{SIMPLEENTITYNAME}/export', {}).then(result => {
+    const blob = new Blob([result.data], { type: 'application/vnd.ms-excel' });
+    window.location.href = window.URL.createObjectURL(blob);
+    return true;
+  })
+};
+
+const onSearch = () => {
+  // console.log('search');
+  getPage()
+}
+
+const onPageChange = (page, size) => {
+  currentPage = page;
+  pageSize = size;
+  getPage();
+}
+
+function handleTableReload(value) {
+  getPage()
+}
+
+</script>
+
+<script>
+export default {
+  name: '@{fullEntityName}'
+}
+</script>
+
+<template>
+  <div>
+    <EditView ref="editChild" @tableReload="handleTableReload" />
+    <div class="table-header">
+      <a-input-search v-model:value="searchInput" :placeholder="formatMessage('page.input', '璇疯緭鍏�')" style="width: 200px;" @search="onSearch" />
+      <div class="table-header-right">
+        <a-button @click="handleEdit(null)" type="primary">{{ formatMessage('page.add', '娣诲姞') }}</a-button>
+        <a-button @click="handleExport">{{ formatMessage('page.export', '瀵煎嚭') }}</a-button>
+      </div>
+    </div>
+    <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+      :data-source="tableData.records" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id"
+      :pagination="{ total: tableData.total, onChange: onPageChange }"
+      :scroll="{ y: 768, scrollToFirstRowOnChange: true }">
+      @{TABLECOLUMNS}
+      <a-table-column title="绫诲瀷" key="type" data-index="type" />
+      <a-table-column title="鎿嶄綔" key="oper" data-index="oper">
+        <template #default="{ record }">
+          <div style="display: flex;justify-content: space-evenly;">
+            <a-button type="link" primary @click="handleEdit(record)">{{ formatMessage('page.edit', '缂栬緫') }}</a-button>
+            <a-button type="link" danger @click="handleDel([record])">{{ formatMessage('page.delete', '鍒犻櫎') }}</a-button>
+          </div>
+        </template>
+      </a-table-column>
+    </a-table>
+  </div>
+</template>
+
+<template>
+  <div>
+    <EditView ref="editChild" @tableReload="handleTableReload" />
+    <div class="table-header">
+      <a-input-search v-model:value="searchInput" :placeholder="formatMessage('page.input', '璇疯緭鍏�')"
+        style="width: 200px;" @search="onSearch" />
+      <div class="table-header-right">
+        <a-button @click="handleEdit(null)" type="primary">{{ formatMessage('page.add', '娣诲姞') }}</a-button>
+        <a-button @click="handleExport">{{ formatMessage('page.export', '瀵煎嚭') }}</a-button>
+      </div>
+    </div>
+    <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+      :data-source="tableData.records" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id"
+      :pagination="{ total: tableData.total, onChange: onPageChange }"
+      :scroll="{ y: 768, scrollToFirstRowOnChange: true }" :columns="columns">
+      <template #bodyCell="{ column, text, record }">
+        <template v-if="column.dataIndex === 'oper'">
+          <div style="display: flex;justify-content: space-evenly;">
+            <a-button type="link" primary @click="handleEdit(record)">{{ formatMessage('page.edit', '缂栬緫') }}</a-button>
+            <a-button type="link" danger @click="handleDel([record])">{{ formatMessage('page.delete', '鍒犻櫎')
+              }}</a-button>
+          </div>
+        </template>
+      </template>
+    </a-table>
+  </div>
+</template>
+
+<style></style>
\ No newline at end of file
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Mapper.txt b/zy-asrs-framework/src/main/resources/templates/vue/Mapper.txt
new file mode 100644
index 0000000..5815c97
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Mapper.txt
@@ -0,0 +1,12 @@
+package @{COMPANYNAME}.mapper;
+
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface @{ENTITYNAME}Mapper extends BaseMapper<@{ENTITYNAME}> {
+
+}
\ No newline at end of file
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Service.txt b/zy-asrs-framework/src/main/resources/templates/vue/Service.txt
new file mode 100644
index 0000000..6129c08
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Service.txt
@@ -0,0 +1,8 @@
+package @{COMPANYNAME}.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+
+public interface @{ENTITYNAME}Service extends IService<@{ENTITYNAME}> {
+
+}
\ No newline at end of file
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/ServiceImpl.txt b/zy-asrs-framework/src/main/resources/templates/vue/ServiceImpl.txt
new file mode 100644
index 0000000..63944cf
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/ServiceImpl.txt
@@ -0,0 +1,12 @@
+package @{COMPANYNAME}.service.impl;
+
+import @{COMPANYNAME}.mapper.@{ENTITYNAME}Mapper;
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import @{COMPANYNAME}.service.@{ENTITYNAME}Service;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("@{SIMPLEENTITYNAME}Service")
+public class @{ENTITYNAME}ServiceImpl extends ServiceImpl<@{ENTITYNAME}Mapper, @{ENTITYNAME}> implements @{ENTITYNAME}Service {
+
+}
\ No newline at end of file
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Sql.txt b/zy-asrs-framework/src/main/resources/templates/vue/Sql.txt
new file mode 100644
index 0000000..9905504
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Sql.txt
@@ -0,0 +1,9 @@
+-- save @{SIMPLEENTITYNAME} record
+-- mysql
+insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( '@{TABLEDESC}绠$悊', '0', '/@{ITEMNAME}/@{SIMPLEENTITYNAME}', '/@{ITEMNAME}/@{SIMPLEENTITYNAME}', '0' , '0', '1' , '1');
+
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鏌ヨ@{TABLEDESC}', '', '1', '@{ITEMNAME}:@{SIMPLEENTITYNAME}:list', '0', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '娣诲姞@{TABLEDESC}', '', '1', '@{ITEMNAME}:@{SIMPLEENTITYNAME}:save', '1', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '淇敼@{TABLEDESC}', '', '1', '@{ITEMNAME}:@{SIMPLEENTITYNAME}:update', '2', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鍒犻櫎@{TABLEDESC}', '', '1', '@{ITEMNAME}:@{SIMPLEENTITYNAME}:remove', '3', '1', '1');
+
diff --git a/zy-asrs-framework/src/main/resources/templates/vue/Xml.txt b/zy-asrs-framework/src/main/resources/templates/vue/Xml.txt
new file mode 100644
index 0000000..94924d8
--- /dev/null
+++ b/zy-asrs-framework/src/main/resources/templates/vue/Xml.txt
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="@{COMPANYNAME}.mapper.@{ENTITYNAME}Mapper">
+
+</mapper>
\ No newline at end of file
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java
index 7f6808b..a99e90c 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java
@@ -1,7 +1,7 @@
 package com.zy.asrs.wms.utils;
 
 
-import com.zy.asrs.framework.generators.BetterGenerator;
+import com.zy.asrs.framework.generators.VueGenerator;
 import com.zy.asrs.framework.generators.constant.SqlOsType;
 
 /**
@@ -10,20 +10,20 @@
 public class CodeBuilder {
 
     public static void main(String[] args) throws Exception {
-        BetterGenerator generator = new BetterGenerator();
+        VueGenerator generator = new VueGenerator();
         generator.backendPrefixPath = "zy-asrs-wms/";
-        generator.frontendPrefixPath = "zy-asrs-flow/";
+        generator.frontendPrefixPath = "zy-asrs-admin/";
 
         generator.sqlOsType = SqlOsType.MYSQL;
         generator.url="localhost:3306/asrs";
         generator.username="root";
-        generator.password="xltys1995";
+        generator.password="root";
 //        generator.url="47.97.1.152:51433;databasename=jkasrs";
 //        generator.username="sa";
 //        generator.password="Zoneyung@zy56$";
 
-        generator.table="sys_operation_record";
-        generator.tableName="鎿嶄綔鏃ュ織";
+        generator.table="sys_user";
+        generator.tableName="鐢ㄦ埛绠$悊";
         generator.packagePath="com.zy.asrs.wms.system";
 
         generator.build();
diff --git a/zy-asrs-wms/src/main/java/user.sql b/zy-asrs-wms/src/main/java/user.sql
new file mode 100644
index 0000000..a704325
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/user.sql
@@ -0,0 +1,9 @@
+-- save user record
+-- mysql
+insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( '鐢ㄦ埛绠$悊绠$悊', '0', '/system/user', '/system/user', '0' , '0', '1' , '1');
+
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鏌ヨ鐢ㄦ埛绠$悊', '', '1', 'system:user:list', '0', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '娣诲姞鐢ㄦ埛绠$悊', '', '1', 'system:user:save', '1', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '淇敼鐢ㄦ埛绠$悊', '', '1', 'system:user:update', '2', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鍒犻櫎鐢ㄦ埛绠$悊', '', '1', 'system:user:remove', '3', '1', '1');
+

--
Gitblit v1.9.1