Ver código fonte

first commit

sky 3 anos atrás
commit
04a37b8079

+ 24 - 0
.gitignore

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

+ 3 - 0
.vscode/extensions.json

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

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

+ 14 - 0
index.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+      <meta  name="referrer" content="no-referrer">
+    <title>Vite + Vue</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 1827 - 0
package-lock.json

@@ -0,0 +1,1827 @@
+{
+  "name": "frontend",
+  "version": "0.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "frontend",
+      "version": "0.0.0",
+      "dependencies": {
+        "axios": "^1.3.5",
+        "element-plus": "^2.3.3",
+        "muse-ui": "^3.0.2",
+        "vue": "^3.2.47",
+        "vue-router": "^4.1.6"
+      },
+      "devDependencies": {
+        "@vitejs/plugin-vue": "^4.1.0",
+        "vite": "^4.2.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz",
+      "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@ctrl/tinycolor": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz",
+      "integrity": "sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@element-plus/icons-vue": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
+      "integrity": "sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==",
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.16.tgz",
+      "integrity": "sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.16.tgz",
+      "integrity": "sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.16.tgz",
+      "integrity": "sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.16.tgz",
+      "integrity": "sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.16.tgz",
+      "integrity": "sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.16.tgz",
+      "integrity": "sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.16.tgz",
+      "integrity": "sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.16.tgz",
+      "integrity": "sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.16.tgz",
+      "integrity": "sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.16.tgz",
+      "integrity": "sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.16.tgz",
+      "integrity": "sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.16.tgz",
+      "integrity": "sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.16.tgz",
+      "integrity": "sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.16.tgz",
+      "integrity": "sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.16.tgz",
+      "integrity": "sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.16.tgz",
+      "integrity": "sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.16.tgz",
+      "integrity": "sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.16.tgz",
+      "integrity": "sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.16.tgz",
+      "integrity": "sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.16.tgz",
+      "integrity": "sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.16.tgz",
+      "integrity": "sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.16.tgz",
+      "integrity": "sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@floating-ui/core": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz",
+      "integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg=="
+    },
+    "node_modules/@floating-ui/dom": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.6.tgz",
+      "integrity": "sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==",
+      "dependencies": {
+        "@floating-ui/core": "^1.2.6"
+      }
+    },
+    "node_modules/@popperjs/core": {
+      "name": "@sxzz/popperjs-es",
+      "version": "2.11.7",
+      "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
+      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
+    "node_modules/@types/lodash": {
+      "version": "4.14.194",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz",
+      "integrity": "sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g=="
+    },
+    "node_modules/@types/lodash-es": {
+      "version": "4.17.7",
+      "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz",
+      "integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==",
+      "dependencies": {
+        "@types/lodash": "*"
+      }
+    },
+    "node_modules/@types/web-bluetooth": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
+      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+    },
+    "node_modules/@vitejs/plugin-vue": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz",
+      "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==",
+      "dev": true,
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^4.0.0",
+        "vue": "^3.2.25"
+      }
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
+      "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz",
+      "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==",
+      "dependencies": {
+        "@vue/compiler-core": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz",
+      "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.47",
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/compiler-ssr": "3.2.47",
+        "@vue/reactivity-transform": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7",
+        "postcss": "^8.1.10",
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz",
+      "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/devtools-api": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
+      "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz",
+      "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==",
+      "dependencies": {
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/reactivity-transform": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz",
+      "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz",
+      "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==",
+      "dependencies": {
+        "@vue/reactivity": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz",
+      "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==",
+      "dependencies": {
+        "@vue/runtime-core": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "csstype": "^2.6.8"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz",
+      "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.2.47",
+        "@vue/shared": "3.2.47"
+      },
+      "peerDependencies": {
+        "vue": "3.2.47"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
+      "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
+    },
+    "node_modules/@vueuse/core": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
+      "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
+      "dependencies": {
+        "@types/web-bluetooth": "^0.0.16",
+        "@vueuse/metadata": "9.13.0",
+        "@vueuse/shared": "9.13.0",
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/core/node_modules/vue-demi": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
+      "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
+      "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/@vueuse/metadata": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
+      "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/shared": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
+      "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
+      "dependencies": {
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/shared/node_modules/vue-demi": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
+      "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
+      "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/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.3.5",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
+      "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
+      "dependencies": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/body-scroll-lock": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-2.7.1.tgz",
+      "integrity": "sha512-hS53SQ8RhM0e4DsQ3PKz6Gr2O7Kpdh59TWU98GHjaQznL7y4dFycEPk7pFQAikqBaUSCArkc5E3pe7CWIt2fZA=="
+    },
+    "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/csstype": {
+      "version": "2.6.21",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
+      "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
+    },
+    "node_modules/dayjs": {
+      "version": "1.11.7",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
+      "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
+    },
+    "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/element-plus": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.3.3.tgz",
+      "integrity": "sha512-Zy61OXrG6b4FF3h29A9ZOUkaEQXjCuFwNa7DlpB3Vo+42Tw5zBbHe5a4BY7i56TVJG5xTbS9UQyA726J91pDqg==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.4.1",
+        "@element-plus/icons-vue": "^2.0.6",
+        "@floating-ui/dom": "^1.0.1",
+        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+        "@types/lodash": "^4.14.182",
+        "@types/lodash-es": "^4.17.6",
+        "@vueuse/core": "^9.1.0",
+        "async-validator": "^4.2.5",
+        "dayjs": "^1.11.3",
+        "escape-html": "^1.0.3",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.21",
+        "lodash-unified": "^1.0.2",
+        "memoize-one": "^6.0.0",
+        "normalize-wheel-es": "^1.2.0"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.16.tgz",
+      "integrity": "sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.17.16",
+        "@esbuild/android-arm64": "0.17.16",
+        "@esbuild/android-x64": "0.17.16",
+        "@esbuild/darwin-arm64": "0.17.16",
+        "@esbuild/darwin-x64": "0.17.16",
+        "@esbuild/freebsd-arm64": "0.17.16",
+        "@esbuild/freebsd-x64": "0.17.16",
+        "@esbuild/linux-arm": "0.17.16",
+        "@esbuild/linux-arm64": "0.17.16",
+        "@esbuild/linux-ia32": "0.17.16",
+        "@esbuild/linux-loong64": "0.17.16",
+        "@esbuild/linux-mips64el": "0.17.16",
+        "@esbuild/linux-ppc64": "0.17.16",
+        "@esbuild/linux-riscv64": "0.17.16",
+        "@esbuild/linux-s390x": "0.17.16",
+        "@esbuild/linux-x64": "0.17.16",
+        "@esbuild/netbsd-x64": "0.17.16",
+        "@esbuild/openbsd-x64": "0.17.16",
+        "@esbuild/sunos-x64": "0.17.16",
+        "@esbuild/win32-arm64": "0.17.16",
+        "@esbuild/win32-ia32": "0.17.16",
+        "@esbuild/win32-x64": "0.17.16"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "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.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "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.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
+      "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/keycode": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
+      "integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
+    },
+    "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/lodash-unified": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
+      "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+      "peerDependencies": {
+        "@types/lodash-es": "*",
+        "lodash": "*",
+        "lodash-es": "*"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.25.9",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+      "dependencies": {
+        "sourcemap-codec": "^1.4.8"
+      }
+    },
+    "node_modules/memoize-one": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+    },
+    "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/muse-ui": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/muse-ui/-/muse-ui-3.0.2.tgz",
+      "integrity": "sha512-oIH8wEKQqXA6xbb3HzprxC2xoF7P8G01uvF+Jhs6VtbxQjO7VVkKKFu2Mb2NmhX3mMU2EBCgE8wlTU29ffjkPA==",
+      "dependencies": {
+        "body-scroll-lock": "^2.6.1",
+        "dayjs": "^1.8.2",
+        "keycode": "^2.1.9",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.0"
+      },
+      "peerDependencies": {
+        "vue": "^2.5.0"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "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/normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
+    },
+    "node_modules/normalize-wheel-es": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+    },
+    "node_modules/postcss": {
+      "version": "8.4.21",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
+      "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.4",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "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/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/resolve": {
+      "version": "1.22.3",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz",
+      "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.12.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "3.20.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz",
+      "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
+      "dev": true,
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=14.18.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sourcemap-codec": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+      "deprecated": "Please use @jridgewell/sourcemap-codec instead"
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/vite": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
+      "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.17.5",
+        "postcss": "^8.4.21",
+        "resolve": "^1.22.1",
+        "rollup": "^3.18.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "@types/node": ">= 14",
+        "less": "*",
+        "sass": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz",
+      "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/compiler-sfc": "3.2.47",
+        "@vue/runtime-dom": "3.2.47",
+        "@vue/server-renderer": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/vue-router": {
+      "version": "4.1.6",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",
+      "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.4.5"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    }
+  },
+  "dependencies": {
+    "@babel/parser": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz",
+      "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw=="
+    },
+    "@ctrl/tinycolor": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz",
+      "integrity": "sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ=="
+    },
+    "@element-plus/icons-vue": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
+      "integrity": "sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==",
+      "requires": {}
+    },
+    "@esbuild/android-arm": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.16.tgz",
+      "integrity": "sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/android-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.16.tgz",
+      "integrity": "sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/android-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.16.tgz",
+      "integrity": "sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/darwin-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.16.tgz",
+      "integrity": "sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/darwin-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.16.tgz",
+      "integrity": "sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/freebsd-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.16.tgz",
+      "integrity": "sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/freebsd-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.16.tgz",
+      "integrity": "sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-arm": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.16.tgz",
+      "integrity": "sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.16.tgz",
+      "integrity": "sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-ia32": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.16.tgz",
+      "integrity": "sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-loong64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.16.tgz",
+      "integrity": "sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-mips64el": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.16.tgz",
+      "integrity": "sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-ppc64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.16.tgz",
+      "integrity": "sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-riscv64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.16.tgz",
+      "integrity": "sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-s390x": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.16.tgz",
+      "integrity": "sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.16.tgz",
+      "integrity": "sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/netbsd-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.16.tgz",
+      "integrity": "sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/openbsd-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.16.tgz",
+      "integrity": "sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/sunos-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.16.tgz",
+      "integrity": "sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-arm64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.16.tgz",
+      "integrity": "sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-ia32": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.16.tgz",
+      "integrity": "sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-x64": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.16.tgz",
+      "integrity": "sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==",
+      "dev": true,
+      "optional": true
+    },
+    "@floating-ui/core": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz",
+      "integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg=="
+    },
+    "@floating-ui/dom": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.6.tgz",
+      "integrity": "sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==",
+      "requires": {
+        "@floating-ui/core": "^1.2.6"
+      }
+    },
+    "@popperjs/core": {
+      "version": "npm:@sxzz/popperjs-es@2.11.7",
+      "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
+      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
+    },
+    "@types/lodash": {
+      "version": "4.14.194",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz",
+      "integrity": "sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g=="
+    },
+    "@types/lodash-es": {
+      "version": "4.17.7",
+      "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz",
+      "integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==",
+      "requires": {
+        "@types/lodash": "*"
+      }
+    },
+    "@types/web-bluetooth": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
+      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+    },
+    "@vitejs/plugin-vue": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz",
+      "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==",
+      "dev": true,
+      "requires": {}
+    },
+    "@vue/compiler-core": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
+      "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==",
+      "requires": {
+        "@babel/parser": "^7.16.4",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "source-map": "^0.6.1"
+      }
+    },
+    "@vue/compiler-dom": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz",
+      "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==",
+      "requires": {
+        "@vue/compiler-core": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "@vue/compiler-sfc": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz",
+      "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==",
+      "requires": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.47",
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/compiler-ssr": "3.2.47",
+        "@vue/reactivity-transform": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7",
+        "postcss": "^8.1.10",
+        "source-map": "^0.6.1"
+      }
+    },
+    "@vue/compiler-ssr": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz",
+      "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==",
+      "requires": {
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "@vue/devtools-api": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
+      "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+    },
+    "@vue/reactivity": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz",
+      "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==",
+      "requires": {
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "@vue/reactivity-transform": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz",
+      "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==",
+      "requires": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7"
+      }
+    },
+    "@vue/runtime-core": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz",
+      "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==",
+      "requires": {
+        "@vue/reactivity": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "@vue/runtime-dom": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz",
+      "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==",
+      "requires": {
+        "@vue/runtime-core": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "csstype": "^2.6.8"
+      }
+    },
+    "@vue/server-renderer": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz",
+      "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==",
+      "requires": {
+        "@vue/compiler-ssr": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "@vue/shared": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
+      "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
+    },
+    "@vueuse/core": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
+      "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
+      "requires": {
+        "@types/web-bluetooth": "^0.0.16",
+        "@vueuse/metadata": "9.13.0",
+        "@vueuse/shared": "9.13.0",
+        "vue-demi": "*"
+      },
+      "dependencies": {
+        "vue-demi": {
+          "version": "0.14.0",
+          "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
+          "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
+          "requires": {}
+        }
+      }
+    },
+    "@vueuse/metadata": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
+      "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ=="
+    },
+    "@vueuse/shared": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
+      "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
+      "requires": {
+        "vue-demi": "*"
+      },
+      "dependencies": {
+        "vue-demi": {
+          "version": "0.14.0",
+          "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
+          "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
+          "requires": {}
+        }
+      }
+    },
+    "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.3.5",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
+      "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
+      "requires": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "body-scroll-lock": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-2.7.1.tgz",
+      "integrity": "sha512-hS53SQ8RhM0e4DsQ3PKz6Gr2O7Kpdh59TWU98GHjaQznL7y4dFycEPk7pFQAikqBaUSCArkc5E3pe7CWIt2fZA=="
+    },
+    "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"
+      }
+    },
+    "csstype": {
+      "version": "2.6.21",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
+      "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
+    },
+    "dayjs": {
+      "version": "1.11.7",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
+      "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+    },
+    "element-plus": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.3.3.tgz",
+      "integrity": "sha512-Zy61OXrG6b4FF3h29A9ZOUkaEQXjCuFwNa7DlpB3Vo+42Tw5zBbHe5a4BY7i56TVJG5xTbS9UQyA726J91pDqg==",
+      "requires": {
+        "@ctrl/tinycolor": "^3.4.1",
+        "@element-plus/icons-vue": "^2.0.6",
+        "@floating-ui/dom": "^1.0.1",
+        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+        "@types/lodash": "^4.14.182",
+        "@types/lodash-es": "^4.17.6",
+        "@vueuse/core": "^9.1.0",
+        "async-validator": "^4.2.5",
+        "dayjs": "^1.11.3",
+        "escape-html": "^1.0.3",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.21",
+        "lodash-unified": "^1.0.2",
+        "memoize-one": "^6.0.0",
+        "normalize-wheel-es": "^1.2.0"
+      }
+    },
+    "esbuild": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.16.tgz",
+      "integrity": "sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==",
+      "dev": true,
+      "requires": {
+        "@esbuild/android-arm": "0.17.16",
+        "@esbuild/android-arm64": "0.17.16",
+        "@esbuild/android-x64": "0.17.16",
+        "@esbuild/darwin-arm64": "0.17.16",
+        "@esbuild/darwin-x64": "0.17.16",
+        "@esbuild/freebsd-arm64": "0.17.16",
+        "@esbuild/freebsd-x64": "0.17.16",
+        "@esbuild/linux-arm": "0.17.16",
+        "@esbuild/linux-arm64": "0.17.16",
+        "@esbuild/linux-ia32": "0.17.16",
+        "@esbuild/linux-loong64": "0.17.16",
+        "@esbuild/linux-mips64el": "0.17.16",
+        "@esbuild/linux-ppc64": "0.17.16",
+        "@esbuild/linux-riscv64": "0.17.16",
+        "@esbuild/linux-s390x": "0.17.16",
+        "@esbuild/linux-x64": "0.17.16",
+        "@esbuild/netbsd-x64": "0.17.16",
+        "@esbuild/openbsd-x64": "0.17.16",
+        "@esbuild/sunos-x64": "0.17.16",
+        "@esbuild/win32-arm64": "0.17.16",
+        "@esbuild/win32-ia32": "0.17.16",
+        "@esbuild/win32-x64": "0.17.16"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "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.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
+    },
+    "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.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "is-core-module": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
+      "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "keycode": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
+      "integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
+    },
+    "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=="
+    },
+    "lodash-unified": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
+      "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+      "requires": {}
+    },
+    "magic-string": {
+      "version": "0.25.9",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+      "requires": {
+        "sourcemap-codec": "^1.4.8"
+      }
+    },
+    "memoize-one": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+    },
+    "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"
+      }
+    },
+    "muse-ui": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/muse-ui/-/muse-ui-3.0.2.tgz",
+      "integrity": "sha512-oIH8wEKQqXA6xbb3HzprxC2xoF7P8G01uvF+Jhs6VtbxQjO7VVkKKFu2Mb2NmhX3mMU2EBCgE8wlTU29ffjkPA==",
+      "requires": {
+        "body-scroll-lock": "^2.6.1",
+        "dayjs": "^1.8.2",
+        "keycode": "^2.1.9",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.0"
+      }
+    },
+    "nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
+    },
+    "normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
+    },
+    "normalize-wheel-es": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
+    },
+    "path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
+    },
+    "picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+    },
+    "postcss": {
+      "version": "8.4.21",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
+      "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
+      "requires": {
+        "nanoid": "^3.3.4",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "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=="
+    },
+    "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=="
+    },
+    "resolve": {
+      "version": "1.22.3",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz",
+      "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==",
+      "dev": true,
+      "requires": {
+        "is-core-module": "^2.12.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      }
+    },
+    "rollup": {
+      "version": "3.20.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz",
+      "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
+      "dev": true,
+      "requires": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+    },
+    "source-map-js": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
+    },
+    "sourcemap-codec": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
+    },
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true
+    },
+    "vite": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
+      "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
+      "dev": true,
+      "requires": {
+        "esbuild": "^0.17.5",
+        "fsevents": "~2.3.2",
+        "postcss": "^8.4.21",
+        "resolve": "^1.22.1",
+        "rollup": "^3.18.0"
+      }
+    },
+    "vue": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz",
+      "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==",
+      "requires": {
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/compiler-sfc": "3.2.47",
+        "@vue/runtime-dom": "3.2.47",
+        "@vue/server-renderer": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "vue-router": {
+      "version": "4.1.6",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",
+      "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==",
+      "requires": {
+        "@vue/devtools-api": "^6.4.5"
+      }
+    }
+  }
+}

+ 25 - 0
package.json

@@ -0,0 +1,25 @@
+{
+  "name": "frontend",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "axios": "^1.3.5",
+    "dayjs": "^1.11.7",
+    "element-plus": "^2.3.3",
+    "marked": "^4.3.0",
+    "muse-ui": "^3.0.2",
+    "sass": "^1.62.0",
+    "vue": "^3.2.47",
+    "vue-router": "^4.1.6"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^4.1.0",
+    "vite": "^4.2.0"
+  }
+}

+ 919 - 0
pnpm-lock.yaml

@@ -0,0 +1,919 @@
+lockfileVersion: 5.4
+
+specifiers:
+  '@vitejs/plugin-vue': ^4.1.0
+  axios: ^1.3.5
+  dayjs: ^1.11.7
+  element-plus: ^2.3.3
+  marked: ^4.3.0
+  muse-ui: ^3.0.2
+  sass: ^1.62.0
+  vite: ^4.2.0
+  vue: ^3.2.47
+  vue-router: ^4.1.6
+
+dependencies:
+  axios: 1.3.5
+  dayjs: 1.11.7
+  element-plus: 2.3.3_vue@3.2.47
+  marked: 4.3.0
+  muse-ui: r2.cnpmjs.org/muse-ui/3.0.2_vue@3.2.47
+  sass: 1.62.0
+  vue: 3.2.47
+  vue-router: 4.1.6_vue@3.2.47
+
+devDependencies:
+  '@vitejs/plugin-vue': 4.1.0_vite@4.2.1+vue@3.2.47
+  vite: 4.2.1_sass@1.62.0
+
+packages:
+
+  /@babel/helper-string-parser/7.19.4:
+    resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/helper-validator-identifier/7.19.1:
+    resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
+    engines: {node: '>=6.9.0'}
+
+  /@babel/parser/7.21.4:
+    resolution: {integrity: sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.21.4
+
+  /@babel/types/7.21.4:
+    resolution: {integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-string-parser': 7.19.4
+      '@babel/helper-validator-identifier': 7.19.1
+      to-fast-properties: r2.cnpmjs.org/to-fast-properties/2.0.0
+
+  /@ctrl/tinycolor/3.6.0:
+    resolution: {integrity: sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==}
+    engines: {node: '>=10'}
+    dev: false
+
+  /@element-plus/icons-vue/2.1.0_vue@3.2.47:
+    resolution: {integrity: sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      vue: 3.2.47
+    dev: false
+
+  /@esbuild/android-arm/0.17.16:
+    resolution: {integrity: sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-arm64/0.17.16:
+    resolution: {integrity: sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-x64/0.17.16:
+    resolution: {integrity: sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-arm64/0.17.16:
+    resolution: {integrity: sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-x64/0.17.16:
+    resolution: {integrity: sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-arm64/0.17.16:
+    resolution: {integrity: sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-x64/0.17.16:
+    resolution: {integrity: sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm/0.17.16:
+    resolution: {integrity: sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm64/0.17.16:
+    resolution: {integrity: sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ia32/0.17.16:
+    resolution: {integrity: sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-loong64/0.17.16:
+    resolution: {integrity: sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==}
+    engines: {node: '>=12'}
+    cpu: [loong64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-mips64el/0.17.16:
+    resolution: {integrity: sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==}
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ppc64/0.17.16:
+    resolution: {integrity: sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-riscv64/0.17.16:
+    resolution: {integrity: sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==}
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-s390x/0.17.16:
+    resolution: {integrity: sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==}
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-x64/0.17.16:
+    resolution: {integrity: sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/netbsd-x64/0.17.16:
+    resolution: {integrity: sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/openbsd-x64/0.17.16:
+    resolution: {integrity: sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/sunos-x64/0.17.16:
+    resolution: {integrity: sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-arm64/0.17.16:
+    resolution: {integrity: sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-ia32/0.17.16:
+    resolution: {integrity: sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-x64/0.17.16:
+    resolution: {integrity: sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@floating-ui/core/1.2.6:
+    resolution: {integrity: sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==}
+    dev: false
+
+  /@floating-ui/dom/1.2.6:
+    resolution: {integrity: sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==}
+    dependencies:
+      '@floating-ui/core': 1.2.6
+    dev: false
+
+  /@sxzz/popperjs-es/2.11.7:
+    resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
+    dev: false
+
+  /@types/lodash-es/4.17.7:
+    resolution: {integrity: sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==}
+    dependencies:
+      '@types/lodash': 4.14.194
+    dev: false
+
+  /@types/lodash/4.14.194:
+    resolution: {integrity: sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==}
+    dev: false
+
+  /@types/web-bluetooth/0.0.16:
+    resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
+    dev: false
+
+  /@vitejs/plugin-vue/4.1.0_vite@4.2.1+vue@3.2.47:
+    resolution: {integrity: sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    peerDependencies:
+      vite: ^4.0.0
+      vue: ^3.2.25
+    dependencies:
+      vite: 4.2.1_sass@1.62.0
+      vue: 3.2.47
+    dev: true
+
+  /@vue/compiler-core/3.2.47:
+    resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==}
+    dependencies:
+      '@babel/parser': 7.21.4
+      '@vue/shared': 3.2.47
+      estree-walker: r2.cnpmjs.org/estree-walker/2.0.2
+      source-map: r2.cnpmjs.org/source-map/0.6.1
+
+  /@vue/compiler-dom/3.2.47:
+    resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==}
+    dependencies:
+      '@vue/compiler-core': 3.2.47
+      '@vue/shared': 3.2.47
+
+  /@vue/compiler-sfc/3.2.47:
+    resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==}
+    dependencies:
+      '@babel/parser': 7.21.4
+      '@vue/compiler-core': 3.2.47
+      '@vue/compiler-dom': 3.2.47
+      '@vue/compiler-ssr': 3.2.47
+      '@vue/reactivity-transform': 3.2.47
+      '@vue/shared': 3.2.47
+      estree-walker: r2.cnpmjs.org/estree-walker/2.0.2
+      magic-string: 0.25.9
+      postcss: 8.4.21
+      source-map: r2.cnpmjs.org/source-map/0.6.1
+
+  /@vue/compiler-ssr/3.2.47:
+    resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==}
+    dependencies:
+      '@vue/compiler-dom': 3.2.47
+      '@vue/shared': 3.2.47
+
+  /@vue/devtools-api/6.5.0:
+    resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
+    dev: false
+
+  /@vue/reactivity-transform/3.2.47:
+    resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==}
+    dependencies:
+      '@babel/parser': 7.21.4
+      '@vue/compiler-core': 3.2.47
+      '@vue/shared': 3.2.47
+      estree-walker: r2.cnpmjs.org/estree-walker/2.0.2
+      magic-string: 0.25.9
+
+  /@vue/reactivity/3.2.47:
+    resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==}
+    dependencies:
+      '@vue/shared': 3.2.47
+
+  /@vue/runtime-core/3.2.47:
+    resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==}
+    dependencies:
+      '@vue/reactivity': 3.2.47
+      '@vue/shared': 3.2.47
+
+  /@vue/runtime-dom/3.2.47:
+    resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==}
+    dependencies:
+      '@vue/runtime-core': 3.2.47
+      '@vue/shared': 3.2.47
+      csstype: 2.6.21
+
+  /@vue/server-renderer/3.2.47_vue@3.2.47:
+    resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==}
+    peerDependencies:
+      vue: 3.2.47
+    dependencies:
+      '@vue/compiler-ssr': 3.2.47
+      '@vue/shared': 3.2.47
+      vue: 3.2.47
+
+  /@vue/shared/3.2.47:
+    resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==}
+
+  /@vueuse/core/9.13.0_vue@3.2.47:
+    resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
+    dependencies:
+      '@types/web-bluetooth': 0.0.16
+      '@vueuse/metadata': 9.13.0
+      '@vueuse/shared': 9.13.0_vue@3.2.47
+      vue-demi: 0.14.0_vue@3.2.47
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
+  /@vueuse/metadata/9.13.0:
+    resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
+    dev: false
+
+  /@vueuse/shared/9.13.0_vue@3.2.47:
+    resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
+    dependencies:
+      vue-demi: 0.14.0_vue@3.2.47
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
+  /anymatch/3.1.3:
+    resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+    engines: {node: '>= 8'}
+    dependencies:
+      normalize-path: r2.cnpmjs.org/normalize-path/3.0.0
+      picomatch: 2.3.1
+
+  /async-validator/4.2.5:
+    resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+    dev: false
+
+  /axios/1.3.5:
+    resolution: {integrity: sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==}
+    dependencies:
+      follow-redirects: 1.15.2
+      form-data: r2.cnpmjs.org/form-data/4.0.0
+      proxy-from-env: r2.cnpmjs.org/proxy-from-env/1.1.0
+    transitivePeerDependencies:
+      - debug
+    dev: false
+
+  /chokidar/3.5.3:
+    resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+    engines: {node: '>= 8.10.0'}
+    dependencies:
+      anymatch: 3.1.3
+      braces: r2.cnpmjs.org/braces/3.0.2
+      glob-parent: r2.cnpmjs.org/glob-parent/5.1.2
+      is-binary-path: r2.cnpmjs.org/is-binary-path/2.1.0
+      is-glob: r2.cnpmjs.org/is-glob/4.0.3
+      normalize-path: r2.cnpmjs.org/normalize-path/3.0.0
+      readdirp: r2.cnpmjs.org/readdirp/3.6.0
+    optionalDependencies:
+      fsevents: r2.cnpmjs.org/fsevents/2.3.2
+
+  /csstype/2.6.21:
+    resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
+
+  /dayjs/1.11.7:
+    resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==}
+    dev: false
+
+  /element-plus/2.3.3_vue@3.2.47:
+    resolution: {integrity: sha512-Zy61OXrG6b4FF3h29A9ZOUkaEQXjCuFwNa7DlpB3Vo+42Tw5zBbHe5a4BY7i56TVJG5xTbS9UQyA726J91pDqg==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@ctrl/tinycolor': 3.6.0
+      '@element-plus/icons-vue': 2.1.0_vue@3.2.47
+      '@floating-ui/dom': 1.2.6
+      '@popperjs/core': /@sxzz/popperjs-es/2.11.7
+      '@types/lodash': 4.14.194
+      '@types/lodash-es': 4.17.7
+      '@vueuse/core': 9.13.0_vue@3.2.47
+      async-validator: 4.2.5
+      dayjs: 1.11.7
+      escape-html: r2.cnpmjs.org/escape-html/1.0.3
+      lodash: r2.cnpmjs.org/lodash/4.17.21
+      lodash-es: r2.cnpmjs.org/lodash-es/4.17.21
+      lodash-unified: 1.0.3_tknf7errc3xdqocd3ryzzla7vq
+      memoize-one: r2.cnpmjs.org/memoize-one/6.0.0
+      normalize-wheel-es: 1.2.0
+      vue: 3.2.47
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+    dev: false
+
+  /esbuild/0.17.16:
+    resolution: {integrity: sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      '@esbuild/android-arm': 0.17.16
+      '@esbuild/android-arm64': 0.17.16
+      '@esbuild/android-x64': 0.17.16
+      '@esbuild/darwin-arm64': 0.17.16
+      '@esbuild/darwin-x64': 0.17.16
+      '@esbuild/freebsd-arm64': 0.17.16
+      '@esbuild/freebsd-x64': 0.17.16
+      '@esbuild/linux-arm': 0.17.16
+      '@esbuild/linux-arm64': 0.17.16
+      '@esbuild/linux-ia32': 0.17.16
+      '@esbuild/linux-loong64': 0.17.16
+      '@esbuild/linux-mips64el': 0.17.16
+      '@esbuild/linux-ppc64': 0.17.16
+      '@esbuild/linux-riscv64': 0.17.16
+      '@esbuild/linux-s390x': 0.17.16
+      '@esbuild/linux-x64': 0.17.16
+      '@esbuild/netbsd-x64': 0.17.16
+      '@esbuild/openbsd-x64': 0.17.16
+      '@esbuild/sunos-x64': 0.17.16
+      '@esbuild/win32-arm64': 0.17.16
+      '@esbuild/win32-ia32': 0.17.16
+      '@esbuild/win32-x64': 0.17.16
+    dev: true
+
+  /follow-redirects/1.15.2:
+    resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      debug: '*'
+    peerDependenciesMeta:
+      debug:
+        optional: true
+    dev: false
+
+  /immutable/4.3.0:
+    resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==}
+
+  /is-core-module/2.12.0:
+    resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==}
+    dependencies:
+      has: r2.cnpmjs.org/has/1.0.3
+    dev: true
+
+  /lodash-unified/1.0.3_tknf7errc3xdqocd3ryzzla7vq:
+    resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==}
+    peerDependencies:
+      '@types/lodash-es': '*'
+      lodash: '*'
+      lodash-es: '*'
+    dependencies:
+      '@types/lodash-es': 4.17.7
+      lodash: r2.cnpmjs.org/lodash/4.17.21
+      lodash-es: r2.cnpmjs.org/lodash-es/4.17.21
+    dev: false
+
+  /magic-string/0.25.9:
+    resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
+    dependencies:
+      sourcemap-codec: r2.cnpmjs.org/sourcemap-codec/1.4.8
+
+  /marked/4.3.0:
+    resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
+    engines: {node: '>= 12'}
+    hasBin: true
+    dev: false
+
+  /mime-db/1.52.0:
+    resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /mime-types/2.1.35:
+    resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-db: 1.52.0
+    dev: false
+
+  /nanoid/3.3.6:
+    resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+
+  /normalize-wheel-es/1.2.0:
+    resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
+    dev: false
+
+  /picomatch/2.3.1:
+    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+    engines: {node: '>=8.6'}
+
+  /postcss/8.4.21:
+    resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.3.6
+      picocolors: r2.cnpmjs.org/picocolors/1.0.0
+      source-map-js: 1.0.2
+
+  /resolve/1.22.2:
+    resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
+    hasBin: true
+    dependencies:
+      is-core-module: 2.12.0
+      path-parse: r2.cnpmjs.org/path-parse/1.0.7
+      supports-preserve-symlinks-flag: 1.0.0
+    dev: true
+
+  /rollup/3.20.2:
+    resolution: {integrity: sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==}
+    engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+    hasBin: true
+    optionalDependencies:
+      fsevents: r2.cnpmjs.org/fsevents/2.3.2
+    dev: true
+
+  /sass/1.62.0:
+    resolution: {integrity: sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==}
+    engines: {node: '>=14.0.0'}
+    hasBin: true
+    dependencies:
+      chokidar: 3.5.3
+      immutable: 4.3.0
+      source-map-js: 1.0.2
+
+  /source-map-js/1.0.2:
+    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+    engines: {node: '>=0.10.0'}
+
+  /supports-preserve-symlinks-flag/1.0.0:
+    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /vite/4.2.1_sass@1.62.0:
+    resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': '>= 14'
+      less: '*'
+      sass: '*'
+      stylus: '*'
+      sugarss: '*'
+      terser: ^5.4.0
+    peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      less:
+        optional: true
+      sass:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+    dependencies:
+      esbuild: 0.17.16
+      postcss: 8.4.21
+      resolve: 1.22.2
+      rollup: 3.20.2
+      sass: 1.62.0
+    optionalDependencies:
+      fsevents: r2.cnpmjs.org/fsevents/2.3.2
+    dev: true
+
+  /vue-demi/0.14.0_vue@3.2.47:
+    resolution: {integrity: sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    peerDependencies:
+      '@vue/composition-api': ^1.0.0-rc.1
+      vue: ^3.0.0-0 || ^2.6.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+    dependencies:
+      vue: 3.2.47
+    dev: false
+
+  /vue-router/4.1.6_vue@3.2.47:
+    resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@vue/devtools-api': 6.5.0
+      vue: 3.2.47
+    dev: false
+
+  /vue/3.2.47:
+    resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==}
+    dependencies:
+      '@vue/compiler-dom': 3.2.47
+      '@vue/compiler-sfc': 3.2.47
+      '@vue/runtime-dom': 3.2.47
+      '@vue/server-renderer': 3.2.47_vue@3.2.47
+      '@vue/shared': 3.2.47
+
+  r2.cnpmjs.org/asynckit/0.4.0:
+    resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/asynckit/-/asynckit-0.4.0.tgz}
+    name: asynckit
+    version: 0.4.0
+    dev: false
+
+  r2.cnpmjs.org/binary-extensions/2.2.0:
+    resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz}
+    name: binary-extensions
+    version: 2.2.0
+    engines: {node: '>=8'}
+
+  r2.cnpmjs.org/body-scroll-lock/2.7.1:
+    resolution: {integrity: sha512-hS53SQ8RhM0e4DsQ3PKz6Gr2O7Kpdh59TWU98GHjaQznL7y4dFycEPk7pFQAikqBaUSCArkc5E3pe7CWIt2fZA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/body-scroll-lock/-/body-scroll-lock-2.7.1.tgz}
+    name: body-scroll-lock
+    version: 2.7.1
+    dev: false
+
+  r2.cnpmjs.org/braces/3.0.2:
+    resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/braces/-/braces-3.0.2.tgz}
+    name: braces
+    version: 3.0.2
+    engines: {node: '>=8'}
+    dependencies:
+      fill-range: r2.cnpmjs.org/fill-range/7.0.1
+
+  r2.cnpmjs.org/combined-stream/1.0.8:
+    resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/combined-stream/-/combined-stream-1.0.8.tgz}
+    name: combined-stream
+    version: 1.0.8
+    engines: {node: '>= 0.8'}
+    dependencies:
+      delayed-stream: r2.cnpmjs.org/delayed-stream/1.0.0
+    dev: false
+
+  r2.cnpmjs.org/delayed-stream/1.0.0:
+    resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz}
+    name: delayed-stream
+    version: 1.0.0
+    engines: {node: '>=0.4.0'}
+    dev: false
+
+  r2.cnpmjs.org/escape-html/1.0.3:
+    resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/escape-html/-/escape-html-1.0.3.tgz}
+    name: escape-html
+    version: 1.0.3
+    dev: false
+
+  r2.cnpmjs.org/estree-walker/2.0.2:
+    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/estree-walker/-/estree-walker-2.0.2.tgz}
+    name: estree-walker
+    version: 2.0.2
+
+  r2.cnpmjs.org/fill-range/7.0.1:
+    resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/fill-range/-/fill-range-7.0.1.tgz}
+    name: fill-range
+    version: 7.0.1
+    engines: {node: '>=8'}
+    dependencies:
+      to-regex-range: r2.cnpmjs.org/to-regex-range/5.0.1
+
+  r2.cnpmjs.org/form-data/4.0.0:
+    resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/form-data/-/form-data-4.0.0.tgz}
+    name: form-data
+    version: 4.0.0
+    engines: {node: '>= 6'}
+    dependencies:
+      asynckit: r2.cnpmjs.org/asynckit/0.4.0
+      combined-stream: r2.cnpmjs.org/combined-stream/1.0.8
+      mime-types: 2.1.35
+    dev: false
+
+  r2.cnpmjs.org/fsevents/2.3.2:
+    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/fsevents/-/fsevents-2.3.2.tgz}
+    name: fsevents
+    version: 2.3.2
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    requiresBuild: true
+    optional: true
+
+  r2.cnpmjs.org/function-bind/1.1.1:
+    resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/function-bind/-/function-bind-1.1.1.tgz}
+    name: function-bind
+    version: 1.1.1
+    dev: true
+
+  r2.cnpmjs.org/glob-parent/5.1.2:
+    resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/glob-parent/-/glob-parent-5.1.2.tgz}
+    name: glob-parent
+    version: 5.1.2
+    engines: {node: '>= 6'}
+    dependencies:
+      is-glob: r2.cnpmjs.org/is-glob/4.0.3
+
+  r2.cnpmjs.org/has/1.0.3:
+    resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/has/-/has-1.0.3.tgz}
+    name: has
+    version: 1.0.3
+    engines: {node: '>= 0.4.0'}
+    dependencies:
+      function-bind: r2.cnpmjs.org/function-bind/1.1.1
+    dev: true
+
+  r2.cnpmjs.org/is-binary-path/2.1.0:
+    resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz}
+    name: is-binary-path
+    version: 2.1.0
+    engines: {node: '>=8'}
+    dependencies:
+      binary-extensions: r2.cnpmjs.org/binary-extensions/2.2.0
+
+  r2.cnpmjs.org/is-extglob/2.1.1:
+    resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/is-extglob/-/is-extglob-2.1.1.tgz}
+    name: is-extglob
+    version: 2.1.1
+    engines: {node: '>=0.10.0'}
+
+  r2.cnpmjs.org/is-glob/4.0.3:
+    resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/is-glob/-/is-glob-4.0.3.tgz}
+    name: is-glob
+    version: 4.0.3
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extglob: r2.cnpmjs.org/is-extglob/2.1.1
+
+  r2.cnpmjs.org/is-number/7.0.0:
+    resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/is-number/-/is-number-7.0.0.tgz}
+    name: is-number
+    version: 7.0.0
+    engines: {node: '>=0.12.0'}
+
+  r2.cnpmjs.org/keycode/2.2.1:
+    resolution: {integrity: sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/keycode/-/keycode-2.2.1.tgz}
+    name: keycode
+    version: 2.2.1
+    dev: false
+
+  r2.cnpmjs.org/lodash-es/4.17.21:
+    resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/lodash-es/-/lodash-es-4.17.21.tgz}
+    name: lodash-es
+    version: 4.17.21
+    dev: false
+
+  r2.cnpmjs.org/lodash/4.17.21:
+    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/lodash/-/lodash-4.17.21.tgz}
+    name: lodash
+    version: 4.17.21
+    dev: false
+
+  r2.cnpmjs.org/memoize-one/6.0.0:
+    resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/memoize-one/-/memoize-one-6.0.0.tgz}
+    name: memoize-one
+    version: 6.0.0
+    dev: false
+
+  r2.cnpmjs.org/muse-ui/3.0.2_vue@3.2.47:
+    resolution: {integrity: sha512-oIH8wEKQqXA6xbb3HzprxC2xoF7P8G01uvF+Jhs6VtbxQjO7VVkKKFu2Mb2NmhX3mMU2EBCgE8wlTU29ffjkPA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/muse-ui/-/muse-ui-3.0.2.tgz}
+    id: r2.cnpmjs.org/muse-ui/3.0.2
+    name: muse-ui
+    version: 3.0.2
+    peerDependencies:
+      vue: ^2.5.0
+    dependencies:
+      body-scroll-lock: r2.cnpmjs.org/body-scroll-lock/2.7.1
+      dayjs: 1.11.7
+      keycode: r2.cnpmjs.org/keycode/2.2.1
+      normalize-wheel: r2.cnpmjs.org/normalize-wheel/1.0.1
+      resize-observer-polyfill: r2.cnpmjs.org/resize-observer-polyfill/1.5.1
+      vue: 3.2.47
+    dev: false
+
+  r2.cnpmjs.org/normalize-path/3.0.0:
+    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/normalize-path/-/normalize-path-3.0.0.tgz}
+    name: normalize-path
+    version: 3.0.0
+    engines: {node: '>=0.10.0'}
+
+  r2.cnpmjs.org/normalize-wheel/1.0.1:
+    resolution: {integrity: sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz}
+    name: normalize-wheel
+    version: 1.0.1
+    dev: false
+
+  r2.cnpmjs.org/path-parse/1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/path-parse/-/path-parse-1.0.7.tgz}
+    name: path-parse
+    version: 1.0.7
+    dev: true
+
+  r2.cnpmjs.org/picocolors/1.0.0:
+    resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/picocolors/-/picocolors-1.0.0.tgz}
+    name: picocolors
+    version: 1.0.0
+
+  r2.cnpmjs.org/proxy-from-env/1.1.0:
+    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz}
+    name: proxy-from-env
+    version: 1.1.0
+    dev: false
+
+  r2.cnpmjs.org/readdirp/3.6.0:
+    resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/readdirp/-/readdirp-3.6.0.tgz}
+    name: readdirp
+    version: 3.6.0
+    engines: {node: '>=8.10.0'}
+    dependencies:
+      picomatch: 2.3.1
+
+  r2.cnpmjs.org/resize-observer-polyfill/1.5.1:
+    resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz}
+    name: resize-observer-polyfill
+    version: 1.5.1
+    dev: false
+
+  r2.cnpmjs.org/source-map/0.6.1:
+    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/source-map/-/source-map-0.6.1.tgz}
+    name: source-map
+    version: 0.6.1
+    engines: {node: '>=0.10.0'}
+
+  r2.cnpmjs.org/sourcemap-codec/1.4.8:
+    resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz}
+    name: sourcemap-codec
+    version: 1.4.8
+    deprecated: Please use @jridgewell/sourcemap-codec instead
+
+  r2.cnpmjs.org/to-fast-properties/2.0.0:
+    resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz}
+    name: to-fast-properties
+    version: 2.0.0
+    engines: {node: '>=4'}
+
+  r2.cnpmjs.org/to-regex-range/5.0.1:
+    resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, registry: https://r.cnpmjs.org/, tarball: https://r2.cnpmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz}
+    name: to-regex-range
+    version: 5.0.1
+    engines: {node: '>=8.0'}
+    dependencies:
+      is-number: r2.cnpmjs.org/is-number/7.0.0

+ 1 - 0
public/vite.svg

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

+ 10 - 0
src/App.vue

@@ -0,0 +1,10 @@
+<template>
+  <router-view></router-view>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+</style>

+ 36 - 0
src/apis/axiosConfig.js

@@ -0,0 +1,36 @@
+import axios from "axios";
+
+//创建axios实例
+const axiosInstance = axios.create();
+
+axiosInstance.interceptors.request.use(
+    (config ) => {
+        // 请求头中携带token信息
+        const token = sessionStorage.getItem("token");
+        if(token) {
+            return {
+                ...config,
+                headers: {
+                    'Authorization': token,
+                }
+            };
+        }
+        return config;
+    },
+    (error) => {
+        //请求报错
+        Promise.reject(error);
+    }
+);
+
+axiosInstance.interceptors.response.use(
+    (response) => {
+        return response;
+    },
+    (error) => {
+        console.log("返回报错", error);
+    }
+);
+
+export default axiosInstance;
+

+ 7 - 0
src/apis/test.js

@@ -0,0 +1,7 @@
+import axiosInstance from "./axiosConfig.js";
+
+const TEST_PREFIX = '/api/test';
+
+export const test = () => {
+    return axiosInstance.get(`${TEST_PREFIX}`);
+}

+ 1 - 0
src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 51 - 0
src/common/const.js

@@ -0,0 +1,51 @@
+// 部署url
+export const REQUEST_BASE_URL_PROD = "http://ismzl.com/";
+// 开发url (mock的地址
+export const REQUEST_BASE_URL_DEV = "http://localhost:8080";
+
+export const ROLE = {
+  SEEC: 'SEEC',
+  TEACHER: 'TEACHER',
+  STUDENT: 'STUDENT',
+  ADMIN: 'ADMIN',
+};
+
+
+export const PATH = {
+  HOME: {
+    path: '/home',
+    requiresAuth: [ROLE.STUDENT, ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  },
+  EVAL_MANAGE: {
+    path: '/evalManage',
+    requiresAuth: [ROLE.STUDENT, ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  },
+  STUDENT_STATUS: {
+    path: '/studentStatus',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  },
+  EXCEPTION_MONITOR: {
+    path: '/exceptionMonitor',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  },
+  STUDENT_MONITOR: {
+    path: '/studentMonitor',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN]
+  },
+  STUDENT_MONITOR_2: {
+    path: '/studentMonitor2',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN]
+  },
+  VIDEO_MONITOR: {
+    path: '/videoMonitor',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  },
+  EXCEPTION_HANDLE: {
+    path: '/exceptionHandle',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  },
+  MONITOR_MANAGE: {
+    path: '/monitorManage',
+    requiresAuth: [ROLE.SEEC, ROLE.TEACHER, ROLE.ADMIN],
+  }
+}

+ 9 - 0
src/common/markdown.js

@@ -0,0 +1,9 @@
+import {marked} from 'marked'
+
+export function markdownToHTML(markdownData = '') {
+    return marked(markdownData, {
+        pedantic: false,
+        breaks: false,
+        gfm: true
+    })
+}

+ 40 - 0
src/common/util.js

@@ -0,0 +1,40 @@
+import dayjs from 'dayjs';
+import Duration from 'dayjs/plugin/duration'
+dayjs.extend(Duration)
+
+export const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
+
+export const timeLength = function(
+    start,
+    end,
+    second = false
+) {
+    const s = dayjs(start, TIME_FORMAT).valueOf()
+    const e = dayjs(end, TIME_FORMAT).valueOf()
+    const t = e - s
+
+    const duration = dayjs.duration(t, 'millisecond')
+    let day = dayjs(end, TIME_FORMAT).diff(
+        dayjs(start, TIME_FORMAT).valueOf(),
+        'day'
+    )
+    let hour = duration.get('hour')
+    let min = duration.get('minute')
+
+    let format = ''
+
+    if (day > 0) {
+        format = `${day}天${hour}小时${min}分`
+    } else if (hour > 0) {
+        format = `${hour}小时${min}分`
+    } else {
+        format = `${min}分`
+    }
+
+    if (second) {
+        let second = duration.get('second')
+        format += `${second}秒`
+    }
+
+    return format
+}

+ 39 - 0
src/components/CustomTitle.vue

@@ -0,0 +1,39 @@
+<template>
+  <div class="common-title">
+    <h1>{{title}}</h1>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "CustomTitle",
+  components: {},
+  props: {
+    title: String,
+  },
+  data() {
+    return {};
+  },
+  created() {},
+  mounted() {},
+  methods: {},
+  computed: {},
+  watch: {},
+};
+</script>
+
+<style scoped>
+h1 {
+  font-weight: 400;
+  font-family: Roboto,sans-serif;
+  font-size: 3rem!important;
+  line-height: 3.125rem;
+  letter-spacing: normal!important;
+  margin: 0;
+}
+.common-title {
+  padding-bottom: 20px;
+  margin-bottom: 20px;
+  border-bottom: solid 1px rgb(204, 204, 204);
+}
+</style>

+ 154 - 0
src/components/ExamQuestionsInfo.vue

@@ -0,0 +1,154 @@
+<template>
+  <div class="question-container">
+    <div v-for="question in examQuestions" :key="question.id">
+      <el-divider></el-divider>
+      <div class="question-box">
+        <div style="width: 10%;">
+          <div v-if="!analysis" class="sequence">{{ examQuestions.indexOf(question) + 1 }}</div>
+          <div v-else :class="['sequence',
+            submitAnswers.get(question.id) === question.answer.replace(/[;]/gi, '') ? 'success': 'error']">
+            {{ examQuestions.indexOf(question) + 1 }}
+          </div>
+        </div>
+        <div style="width: 80%; padding: 0 20px;">
+          <markdown-text
+              :raw="question.stem + mergeOptions(question.options)"
+              style="height: 100%;width: 100%"
+          ></markdown-text>
+        </div>
+        <div v-if="question.keyPoints" style="width: 10%;">
+          关键词: {{ question.keyPoints }}
+        </div>
+      </div>
+
+<!--      <v-row class="px-10 d-block" v-if="analysis && question.type !== 'code'">-->
+<!--        <v-col class="grey lighten-3 py-1">-->
+<!--          <markdown-text-->
+<!--            :raw="question.analysis"-->
+<!--            style="height: 100%;width: 100%"-->
+<!--          ></markdown-text>-->
+<!--        </v-col>-->
+<!--        <v-col-->
+<!--          class="d-flex align-center justify-end"-->
+<!--          v-if="question.type !== 'short_answer'"-->
+<!--        >-->
+<!--          我的答案:-->
+<!--          <v-chip-->
+<!--            label-->
+<!--            :color="-->
+<!--              submitAnswers.get(question.id) ===-->
+<!--              question.answer.replace(/[;]/gi, '')-->
+<!--                ? 'success'-->
+<!--                : 'error'-->
+<!--            "-->
+<!--            class="ml-2 mr-4"-->
+<!--            v-if="submitAnswers.size > 0"-->
+<!--          >-->
+<!--            {{ submitAnswers.get(question.id) }}-->
+<!--          </v-chip>-->
+<!--          正确答案:-->
+<!--          <v-chip label color="success" class="ml-2">-->
+<!--            {{ question.answer.replace(/[;]/gi, '') }}-->
+<!--          </v-chip>-->
+<!--          &lt;!&ndash;  简答题解析即为答案        &ndash;&gt;-->
+<!--        </v-col>-->
+<!--      </v-row>-->
+    </div>
+  </div>
+</template>
+
+<script>
+import MarkdownText from "./MarkdownText.vue";
+
+export default {
+  name: 'ExamQuestionsInfo',
+  props: {
+    examQuestions: {
+      type: Array,
+      required: true
+    },
+    analysis: {
+      type: Boolean,
+      default: false
+    }
+  },
+  components: {
+    MarkdownText
+  },
+  data() {
+    return {
+      submitAnswers: {},
+    }
+  },
+  methods: {
+    mergeOptions(options) {
+      if (!options) {
+        return ''
+      }
+
+      let keys = Object.keys(options)
+      let values = Object.values(options)
+      let entries = []
+
+      for (let i = 0; i < keys.length; i++) {
+        entries.push(keys[i] + ' : ' + values[i])
+      }
+      return '\n' + entries.join(' ')
+    },
+    async fetchAnswers() {
+      const examId = this.$route.params.examId
+      getExamSubmitRecordsByUserId(examId).then(({ data }) => {
+        let records = data.result
+        if (records && records.length > 0) {
+          this.submitAnswers = new Map()
+          records.forEach((val) => {
+            this.submitAnswers.set(
+              val.questionId,
+              val.submitAnswer === ''
+                ? '无'
+                : val.submitAnswer === 't'
+                ? 'true'
+                : val.submitAnswer === 'f'
+                ? 'false'
+                : val.submitAnswer.replace(/[;]/gi, '')
+            )
+          })
+        } else {
+          this.submitAnswers = new Map()
+          this.examQuestions.forEach((val) => {
+            this.submitAnswers.set(val.id, '无')
+          })
+        }
+      })
+    }
+  },
+  mounted() {
+    if (this.analysis) {
+      this.fetchAnswers()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.question-container {
+  padding: 0 24px 16px;
+
+  .question-box {
+    display: flex;
+    align-items: center;
+    .sequence {
+      margin-left: calc(40% - 16px);
+      width: 32px;
+      height: 32px;
+      border-radius: 4px;
+      background-color: #e0e0e0;
+      text-align: center;
+      line-height: 32px;
+    }
+  }
+
+
+
+}
+</style>

+ 202 - 0
src/components/Layout.vue

@@ -0,0 +1,202 @@
+<template>
+  <el-container style="height: 100%; border: 1px solid #eee">
+    <el-aside width="250px" style="background-color: #545c64">
+      <header class="title">
+        <div class="title-inner">SEEC-EVAL</div>
+      </header>
+      <el-menu
+          :default-active="getActivePath"
+          class="el-menu-vertical-demo"
+          background-color="#fff"
+          text-color="#000000DE"
+          @open="handleOpen"
+          @close="handleClose"
+          active-text-color="#7e57c2"
+          router
+      >
+        <el-menu-item :index="PATH.HOME.path">
+          <template #title>
+            <i class="el-icon-receiving"></i>
+            <span slot="title">首页</span>
+          </template>
+        </el-menu-item>
+
+        <el-menu-item :index="PATH.MONITOR_MANAGE.path">
+          <template #title>
+            <i class="el-icon-receiving"></i>
+            <span slot="title">评测管理</span>
+          </template>
+        </el-menu-item>
+
+        <el-sub-menu index="3">
+          <template #title>
+            <i class="el-icon-sell"></i>
+            <span slot="title">监考管理</span>
+          </template>
+          <el-menu-item
+              :index="PATH.STUDENT_STATUS.path"
+          >
+            <i class="el-icon-receiving"></i>
+            <span slot="title">考生状态</span>
+          </el-menu-item>
+          <el-menu-item
+              :index="PATH.EXCEPTION_MONITOR.path"
+          >
+            <i class="el-icon-receiving"></i>
+            <span slot="title">异常检测</span>
+          </el-menu-item>
+          <el-menu-item
+              :index="PATH.VIDEO_MONITOR.path"
+          >
+            <i class="el-icon-receiving"></i>
+            <span slot="title">视频监控</span>
+          </el-menu-item>
+          <el-menu-item
+              :index="PATH.EXCEPTION_HANDLE.path"
+          >
+            <i class="el-icon-receiving"></i>
+            <span slot="title">异常处理</span>
+          </el-menu-item>
+        </el-sub-menu>
+      </el-menu>
+      <div class="logout-fix">
+        <el-tooltip
+            class="item"
+            effect="light"
+            :content="getUserRole"
+            placement="right"
+        >
+          <div class="logout-name">{{ getUsername() }}</div>
+        </el-tooltip>
+        <div class="logout" @click="logout()">退出登录</div>
+      </div>
+    </el-aside>
+
+    <el-main style="overflow-x: hidden">
+      <slot></slot>
+    </el-main>
+  </el-container>
+</template>
+
+<script>
+import {ROLE, PATH} from "../common/const.js";
+
+export default {
+  name: "Layout",
+  props: {
+    activePath: String
+  },
+  data() {
+    return {
+      ROLE,
+      PATH
+    };
+  },
+  mounted() {
+  },
+  computed: {
+    getActivePath() {
+      if (this.activePath == null) {
+        return this.$route.path;
+      } else {
+        return this.activePath;
+      }
+    },
+    getUserRole() {
+      return sessionStorage.getItem("role");
+    }
+  },
+  methods: {
+    handleOpen(key, keyPath) {
+      console.log(key, keyPath);
+    },
+    handleClose(key, keyPath) {
+      console.log(key, keyPath);
+    },
+    logout() {
+      sessionStorage.removeItem("name"); // name
+      sessionStorage.removeItem("role"); // role
+      sessionStorage.removeItem("token"); // token
+      location.href = "/";
+    },
+    getUsername() {
+      return sessionStorage.getItem("name");
+    },
+    permit(arr) {
+      return arr.some(role => role === sessionStorage.getItem("role"));
+    }
+  }
+};
+</script>
+
+<style>
+.title {
+  padding: 16px;
+  margin-bottom: 10px;
+}
+.title-inner {
+  background-color: #9fa8da !important;
+  border-color: #9fa8da !important;
+  border-radius: 8px !important;
+  line-height: 40px;
+  height: 40px;
+  text-align: center;
+  font-size: 21px;
+  font-weight: bold;
+}
+.el-aside {
+  background-color: #fff !important;
+  margin-right: 10px;
+}
+.el-menu {
+  border-right: solid 1px #fff;
+}
+.el-menu-item {
+  width: 92%;
+  margin: 0 auto;
+  padding: 0 10px !important;
+  height: 40px;
+  line-height: 40px;
+  font-size: 13px;
+}
+.el-menu-item > i {
+  margin-right: 30px !important;
+}
+.el-menu-item:focus,
+.el-menu-item:hover {
+  outline: 0;
+  background-color: #f6f6f6 !important;
+}
+.el-menu-item.is-active {
+  color: #7e57c2;
+  background-color: #f0ebf8 !important;
+}
+.logout-fix {
+  position: fixed;
+  left: 30px;
+  bottom: 30px;
+}
+.logout-fix .logout-name {
+  min-width: 60px;
+  background-color: #7e57c2 !important;
+  border-color: #7e57c2 !important;
+  color: #fff;
+  border-radius: 16px;
+  font-size: 14px;
+  height: 32px;
+  text-align: center;
+  padding: 0 10px;
+  margin-left: -10px;
+  line-height: 32px;
+  margin-bottom: 14px;
+  cursor: pointer;
+}
+.logout-fix .logout {
+  color: #00000099;
+  font-size: 14px;
+  cursor: pointer;
+}
+.logout-fix .logout:hover {
+  color: #000000;
+}
+</style>

+ 41 - 0
src/components/MarkdownText.vue

@@ -0,0 +1,41 @@
+<template>
+  <div v-html="markdownToHTML(trimmedRaw)" class="markdown-content"></div>
+</template>
+
+<script>
+import { markdownToHTML } from '../common/markdown.js'
+
+export default {
+  name: 'MarkdownText',
+  props: {
+    raw: String
+  },
+  data() {
+    return {
+      trimmedRaw: ''
+    }
+  },
+  methods: {
+    markdownToHTML
+  },
+  mounted() {
+    this.trimmedRaw = this.raw.trim()
+  }
+}
+</script>
+
+<style lang="scss">
+.markdown-content {
+  word-break: break-all;
+  white-space: pre-wrap;
+  margin-top: 16px;
+  p {
+    font-size: 16px;
+    color: #212121;
+    margin-bottom: 0;
+  }
+  img {
+    max-width: 100%;
+  }
+}
+</style>

+ 12 - 0
src/main.js

@@ -0,0 +1,12 @@
+import { createApp } from 'vue'
+import './style.css'
+import App from './App.vue'
+import router from "./router/index.js";
+
+import ElementPlus from 'element-plus';
+import 'element-plus/dist/index.css';
+
+const app = createApp(App);
+app.use(router);
+app.use(ElementPlus);
+app.mount('#app')

+ 20 - 0
src/pages/EvalManage/evalManage.vue

@@ -0,0 +1,20 @@
+<template>
+  <layout>
+    <div>评测管理</div>
+  </layout>
+</template>
+
+<script>
+import layout from "../../components/Layout.vue";
+
+export default {
+  name: "evalManage",
+  components: {
+    layout
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 24 - 0
src/pages/Home/Home.vue

@@ -0,0 +1,24 @@
+<template>
+  <Layout>
+    <CustomTitle title="主页"></CustomTitle>
+    <div class="main">主页</div>
+  </Layout>
+</template>
+
+<script>
+import Layout from "../../components/Layout.vue";
+import CustomTitle from "../../components/CustomTitle.vue"
+
+export default {
+  name: "Home",
+  components: {CustomTitle, Layout}
+}
+</script>
+
+<style scoped>
+.main {
+  width: 80%;
+  margin: 0 auto;
+}
+
+</style>

+ 20 - 0
src/pages/MonitorManage/exceptionHandle/exceptionHandle.vue

@@ -0,0 +1,20 @@
+<template>
+  <Layout>
+    <CustomTitle title="异常处理"></CustomTitle>
+    <div>异常处理</div>
+  </Layout>
+
+</template>
+
+<script>
+import Layout from "../../../components/Layout.vue";
+import CustomTitle from "../../../components/CustomTitle.vue";
+export default {
+  name: "exceptionHandle",
+  components: {CustomTitle, Layout}
+}
+</script>
+
+<style scoped>
+
+</style>

+ 323 - 0
src/pages/MonitorManage/exceptionMonitor/exceptionMonitor.vue

@@ -0,0 +1,323 @@
+<template>
+  <Layout>
+    <header class="Monitor-title">
+        <div class="h1">异常监测</div>
+        <div class="flex-div">
+          <div class="e1" float-div @click="() =>{
+            this.$router.push('/home');
+          }">
+            主页
+          </div>
+          <div float-div>/</div>
+          <div class="e2" float-div >
+            监考管理
+          </div>
+          <div float-div>/</div>
+          <div class="e3" float-div>
+            异常监测
+          </div>
+          <div class="e2" float-div>
+            2023春季软件——测评考试2
+          </div>
+          <div class="b1">
+          <el-button color="#7E5ED0"
+          @click="() =>{
+            this.$router.push('/home');
+          }">退出监考</el-button>
+          </div>
+          <div class="icon1">
+          <svg t="1681547872625" class="icon" 
+          viewBox="0 0 1024 1024" 
+          version="1.1" 
+          xmlns="http://www.w3.org/2000/svg" 
+          p-id="2704" 
+          width="30" 
+          height="30"
+          >
+          <path 
+          d="M512 22C241.38 22 22 241.38 22 512s219.38 490 490 490 490-219.38 490-490S782.62 22 512 22z 
+          m263.33 312.74l-23.11 124.2-4.02 21.61c-1.81 9.71-11.14 16.12-20.85 
+          14.31l-20.54-3.82-125.41-23.33c-9.71-1.81-16.12-11.14-14.31-20.86l4.02-21.61c1.81-9.71 
+          11.14-16.12 20.85-14.31l61.93 11.52c-46.05-80.06-146.94-112.77-231.92-72.7-89.46 
+          42.18-127.92 149.28-85.74 238.74 42.18 89.46 149.28 127.92 238.74 85.74 17.67-8.33 
+          38.76-0.76 47.09 16.91 8.33 17.67 0.76 38.75-16.91 47.09-49.22 23.21-102.28 28.91-152.09 
+          19.64-76.42-14.22-145.21-63.68-180.82-139.2-58.82-124.75-5.19-274.09 119.56-332.92 115.19-54.32 251.35-12.74 317.85 
+          92.16l9.96-53.55c1.81-9.71 11.14-16.12 20.85-14.31l20.54 3.82c9.73 1.82 16.13 11.16 14.33 20.87z" 
+          fill="#2c2c2c" p-id="2705"></path></svg>
+          </div>
+        </div>
+    </header>
+    <el-row :gutter="24">
+      <el-col :span="10">
+        <div class="contain" float-div>IP异常列表
+        <el-table :data="ip_err" height="220" border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true" 
+        @row-click="jump">
+          <el-table-column prop="id" label="IP异常id" width="50">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="86">
+          </el-table-column>
+          <el-table-column prop="last_ip" label="上次登录IP" width="86">
+          </el-table-column>
+          <el-table-column prop="last_time" label="上次登录时间" width="86">
+          </el-table-column>
+          <el-table-column prop="cur_ip" label="本次登录IP" width="86">
+          </el-table-column>
+          <el-table-column prop="cur_time" label="本次登录时间" width="86">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="10">
+        <div class="contain" float-div>人数检测异常列表
+        <el-table :data="count_err" height="220"  border class="data_table" style="font-size: 1px"
+        :header-cell-style="rowClass" stripe="true"
+        @row-click="jump">
+          <el-table-column prop="id" label="人数异常id" width="71">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="102">
+          </el-table-column>
+          <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+          </el-table-column>
+          <el-table-column prop="valid_count" label="有效入镜人数" width="102">
+          </el-table-column>
+          <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="contain2" float-div>掉线异常列表
+        <el-table :data="offline" height="220"  border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true"
+        @row-click="jump">
+          <el-table-column prop="id" label="掉线异常id" width="60">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="55">
+          </el-table-column>
+          <el-table-column prop="last_time" label="掉线时刻" width="55">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+    </el-row>
+    <el-row :gutter="24">
+      <el-col :span="10">
+        <div class="contain" float-div>姿态检测异常列表
+        <el-table :data="pos_err" height="220" border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true"
+        @row-click="jump">
+          <el-table-column prop="id" label="姿态异常id" width="71">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="102">
+          </el-table-column>
+          <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+          </el-table-column>
+          <el-table-column prop="reason" label="异常原因" width="102">
+          </el-table-column>
+          <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="10">
+        <div class="contain" float-div>人脸识别异常列表
+        <el-table :data="face_err" height="220"  border class="data_table" style="font-size: 1px"
+        :header-cell-style="rowClass" stripe="true"
+        @row-click="jump">
+          <el-table-column prop="id" label="人脸识别异常id" width="71">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="102">
+          </el-table-column>
+          <el-table-column prop="org_img" label="用户原画像" width="102">
+          </el-table-column>
+          <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+          </el-table-column>
+          <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="contain2" float-div>总异常排行
+        <el-table :data="total_err" height="220"  border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true"
+        @row-click="jump">
+          <el-table-column prop="name" label="用户名" width="85">
+          </el-table-column>
+          <el-table-column prop="err_count" label="异常次数" width="85">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+    </el-row>
+
+
+    
+  </Layout>
+</template>
+
+<script>
+import Layout from "../../../components/Layout.vue";
+export default {
+  name: "exceptionMonitor",
+  components: {Layout},
+  data(){
+    return {
+      ip_err:[{
+        id: '16',
+        name: 'MF21320019',
+        last_ip: '183.209.132.59',
+        last_time: '2023-04-09 14:00:00',
+        cur_ip: '180.98.19.28',
+        cur_time: '2023-04-09 14:02:32'
+      },
+
+    ],count_err:[{
+      id: '5',
+      name: 'MF21320019',
+      cur_img: 'picture',
+      valid_count: '0',
+      shot_time: '2023-04-09 14:11:30'
+    },{
+      id: '6',
+      name: 'MF21320019',
+      cur_img: 'picture',
+      valid_count: '2',
+      shot_time: '2023-04-09 14:15:05'
+    },{
+      id: '7',
+      name: 'MF21320019',
+      cur_img: 'picture',
+      valid_count: '3',
+      shot_time: '2023-04-09 14:18:05'
+    }],offline:[{
+      id:'4',
+      name: 'MF21320019',
+      last_time: '2023-04-09 14:30:05'
+
+    }],pos_err:[{
+      id: '21',
+      name: 'MF21320019',
+      cur_img: 'picture',
+      reason: '朝右转动角度过大',
+      shot_time: '2023-04-09 14:18:25'
+    },{
+      id: '22',
+      name: 'MF21320019',
+      cur_img: 'picture',
+      reason: '朝右转动角度过大',
+      shot_time: '2023-04-09 14:18:30'
+    },{
+      id: '23',
+      name: 'MF21320019',
+      cur_img: 'picture',
+      reason: '朝左转动角度过大',
+      shot_time: '2023-04-09 14:19:00'
+    }],face_err:[{
+      id: '7',
+      name: 'MF21320019',
+      org_img: 'picture',
+      cur_img: 'picture',
+      shot_time: '2023-04-09 13:56:24'
+    }],total_err:[{
+      name:'MF21320019',
+      err_count:'8'
+    }]
+
+
+    }
+  },
+  /*methods: {
+    tableRowClassName({row,rowIndex}){
+      if(rowIndex%2==0){
+        return 'warning-row';
+      }
+      else{
+        return '';
+      }
+    }
+  }*/
+  methods: {
+    rowClass({rowIndex}){
+      if(rowIndex===0){
+        return {background:'#E8EAF6'};
+      }else{
+        return {background:'white'};
+      }
+    },
+    jump(){
+      this.$router.push('studentMonitor');
+    }
+  }
+};
+</script>
+
+<style scoped>
+.h1{
+  font-weight: 400;
+  font-family: Roboto,sans-serif;
+  font-size: 3rem!important;
+  line-height: 3.125rem;
+  letter-spacing: normal!important;
+  margin: 0;
+  padding-bottom: 15px;
+}
+.Monitor-title {
+  margin-top: 20px;
+  padding-bottom: 15px;
+  margin-bottom: 20px;
+  border-bottom: solid 1px rgb(204, 204, 204);
+}
+.flex-div{
+  display: flex;
+  width: auto;
+}
+.e1{
+  color: #7E5ED0;
+  font-size: 10%;
+  padding-right: 20px;
+  margin-top:2.5px ;
+  margin-left:10px ;
+}
+.e2{
+  color: #7E5ED0;
+  font-size: 10%;
+  padding-left: 20px;
+  padding-right: 20px;
+  margin-top:2.5px ;
+}
+.e3{
+  color: #909EC3;
+  font-size: 10%;
+  padding-left: 20px;
+  padding-right: 650px;
+  margin-top:2.5px ;
+}
+.b1{
+  
+}
+.icon1{
+  padding-left: 20px;
+}
+.contain{
+  background-color:white;
+  margin-top: 10px;
+  padding-top: 10px;
+  font-size: 80%;
+  padding-left: 10px;
+  padding-right: 10px;
+  height: 250px;
+}
+.contain2{
+  background-color:white;
+  margin-top: 10px;
+  padding-top: 10px;
+  font-size: 80%;
+  padding-left: 10px;
+  height: 250px;
+}
+/*.el-table .warning-row {
+  background: #E8EA;
+} */
+</style>

+ 448 - 0
src/pages/MonitorManage/exceptionMonitor/studentMonitor.vue

@@ -0,0 +1,448 @@
+<template>
+    <Layout>
+      <header class="Monitor-title">
+          <div class="h1">个人监测</div>
+          <div class="flex-div">
+            <div class="e1" float-div @click="() =>{
+            this.$router.push('/home');
+          }">
+            主页
+          </div>
+            <div float-div>/</div>
+            <div class="e2" float-div>
+              监考管理
+            </div>
+            <div float-div>/</div>
+            <div class="e2" float-div @click="() =>{
+            this.$router.push('/exceptionMonitor');
+          }">
+              异常监测
+            </div>
+            <div float-div>/</div>
+            <div class="e3" float-div>
+            个人监测
+          </div>
+            <div class="e2" float-div>
+              2023春季软件——测评考试2
+            </div>
+            
+            <el-button color="#7E5ED0"
+            @click="LogDialogVisible = true">
+              发起异常行为处理
+            </el-button>
+            
+            <div class="icon1">
+            <svg t="1681547872625" class="icon" 
+            viewBox="0 0 1024 1024" 
+            version="1.1" 
+            xmlns="http://www.w3.org/2000/svg" 
+            p-id="2704" 
+            width="30" 
+            height="30"
+            >
+            <path 
+            d="M512 22C241.38 22 22 241.38 22 512s219.38 490 490 490 490-219.38 490-490S782.62 22 512 22z 
+            m263.33 312.74l-23.11 124.2-4.02 21.61c-1.81 9.71-11.14 16.12-20.85 
+            14.31l-20.54-3.82-125.41-23.33c-9.71-1.81-16.12-11.14-14.31-20.86l4.02-21.61c1.81-9.71 
+            11.14-16.12 20.85-14.31l61.93 11.52c-46.05-80.06-146.94-112.77-231.92-72.7-89.46 
+            42.18-127.92 149.28-85.74 238.74 42.18 89.46 149.28 127.92 238.74 85.74 17.67-8.33 
+            38.76-0.76 47.09 16.91 8.33 17.67 0.76 38.75-16.91 47.09-49.22 23.21-102.28 28.91-152.09 
+            19.64-76.42-14.22-145.21-63.68-180.82-139.2-58.82-124.75-5.19-274.09 119.56-332.92 115.19-54.32 251.35-12.74 317.85 
+            92.16l9.96-53.55c1.81-9.71 11.14-16.12 20.85-14.31l20.54 3.82c9.73 1.82 16.13 11.16 14.33 20.87z" 
+            fill="#2c2c2c" p-id="2705"></path></svg>
+            </div>
+          </div>
+      </header>
+      <el-row :gutter="24">
+        <el-col :span="10">
+          <div class="contain" float-div>IP异常列表
+          
+          <el-table :data="ip_err" height="220" border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true" 
+          >
+            <el-table-column prop="id" label="IP异常id" width="50">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="86">
+            </el-table-column>
+            <el-table-column prop="last_ip" label="上次登录IP" width="86">
+            </el-table-column>
+            <el-table-column prop="last_time" label="上次登录时间" width="86">
+            </el-table-column>
+            <el-table-column prop="cur_ip" label="本次登录IP" width="86">
+            </el-table-column>
+            <el-table-column prop="cur_time" label="本次登录时间" width="86">
+            </el-table-column>
+          </el-table>
+        </div>
+        
+        </el-col>
+        <el-col :span="10">
+          <div class="contain" float-div>人数检测异常列表
+          <el-table :data="count_err" height="220"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="人数异常id" width="71">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="102">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+            </el-table-column>
+            <el-table-column prop="valid_count" label="有效入镜人数" width="102">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="contain2" float-div>掉线异常列表
+          <el-table :data="offline" height="220"  border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="掉线异常id" width="60">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="55">
+            </el-table-column>
+            <el-table-column prop="last_time" label="掉线时刻" width="55">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+      </el-row>
+      <el-row :gutter="24">
+        <el-col :span="10">
+          <div class="contain" float-div>姿态检测异常列表
+          <el-table :data="pos_err" height="220" border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="姿态异常id" width="71">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="102">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+            </el-table-column>
+            <el-table-column prop="reason" label="异常原因" width="102">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+        <el-col :span="10">
+          <div class="contain" float-div>人脸识别异常列表
+          <el-table :data="face_err" height="220"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="人脸识别异常id" width="71">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="102">
+            </el-table-column>
+            <el-table-column prop="org_img" label="用户原画像" width="102">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="contain2" float-div>监控
+          <el-table :data="total_err" height="220"  border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="name" label="用户名" width="85">
+            </el-table-column>
+            <el-table-column prop="err_count" label="异常次数" width="85">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+      </el-row>
+
+    
+      
+    </Layout>
+    <!--弹出页面的内容-->
+    <el-dialog v-model="LogDialogVisible">
+      <div>IP异常列表
+        <el-table :data="ip_err" height="200" border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="60">
+            </el-table-column>
+            <el-table-column prop="id" label="IP异常id" width="60">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="100">
+            </el-table-column>
+            <el-table-column prop="last_ip" label="上次登录IP" width="120">
+            </el-table-column>
+            <el-table-column prop="last_time" label="上次登录时间" width="135">
+            </el-table-column>
+            <el-table-column prop="cur_ip" label="本次登录IP" width="120">
+            </el-table-column>
+            <el-table-column prop="cur_time" label="本次登录时间" width="135">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>人数检测异常列表
+        <el-table :data="count_err" height="200"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="人数异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="150">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="150">
+            </el-table-column>
+            <el-table-column prop="valid_count" label="有效入镜人数" width="150">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="150">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>姿态异常检测列表
+        <el-table :data="pos_err" height="200"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="姿态异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="150">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="150">
+            </el-table-column>
+            <el-table-column prop="reason" label="异常原因" width="150">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="150">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>人脸识别异常列表
+        <el-table :data="face_err" height="200"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="人脸识别异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="150">
+            </el-table-column>
+            <el-table-column prop="org_img" label="用户原画像" width="150">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="150">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="150">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>掉线异常列表
+          <el-table :data="offline" height="200"  border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="掉线异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="300">
+            </el-table-column>
+            <el-table-column prop="last_time" label="掉线时刻" width="300">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>发起理由
+      <div class="text-area">
+        <textarea placeholder="请输入内容">
+        </textarea>
+      </div>
+    </div>
+     
+    <el-button color="#7F83F7"
+    @click="() =>{
+            this.$router.push('studentMonitor2');
+          }">
+    确认
+    </el-button>
+             
+    <el-button color="#DE868F"
+    @click="() =>{
+            this.$router.push('exceptionMonitor');
+          }">
+    取消
+    </el-button>
+    </el-dialog>
+  </template>
+  
+  <script>
+  import Layout from "../../../components/Layout.vue";
+  import MuContainer from "muse-ui/src/Grid/Container";
+  export default {
+    name: "exceptionMonitor",
+    components: {Layout,MuContainer},
+    data(){
+      return {
+        LogDialogVisible: false,
+        ip_err:[{
+          id: '16',
+          name: 'MF21320019',
+          last_ip: '183.209.132.59',
+          last_time: '2023-04-09 14:00:00',
+          cur_ip: '180.98.19.28',
+          cur_time: '2023-04-09 14:02:32'
+        },
+  
+      ],count_err:[{
+        id: '5',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        valid_count: '0',
+        shot_time: '2023-04-09 14:11:30'
+      },{
+        id: '6',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        valid_count: '2',
+        shot_time: '2023-04-09 14:15:05'
+      },{
+        id: '7',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        valid_count: '3',
+        shot_time: '2023-04-09 14:18:05'
+      }],offline:[{
+        id:'4',
+        name: 'MF21320019',
+        last_time: '2023-04-09 14:30:05'
+  
+      }],pos_err:[{
+        id: '21',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        reason: '朝右转动角度过大',
+        shot_time: '2023-04-09 14:18:25'
+      },{
+        id: '22',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        reason: '朝右转动角度过大',
+        shot_time: '2023-04-09 14:18:30'
+      },{
+        id: '23',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        reason: '朝左转动角度过大',
+        shot_time: '2023-04-09 14:19:00'
+      }],face_err:[{
+        id: '7',
+        name: 'MF21320019',
+        org_img: 'picture',
+        cur_img: 'picture',
+        shot_time: '2023-04-09 13:56:24'
+      }],total_err:[{
+        name:'MF21320019',
+        err_count:'8'
+      }]
+
+      }
+    },
+    methods: {
+      rowClass({rowIndex}){
+        if(rowIndex===0){
+          return {background:'#E8EAF6'};
+        }else{
+          return {background:'white'};
+        }
+      },
+      
+      doSelectChange(val){
+        console.log(val);
+      }
+    }
+  };
+  </script>
+  
+  <style scoped>
+  .h1{
+    font-weight: 400;
+    font-family: Roboto,sans-serif;
+    font-size: 3rem!important;
+    line-height: 3.125rem;
+    letter-spacing: normal!important;
+    margin: 0;
+    padding-bottom: 15px;
+  }
+  .Monitor-title {
+    margin-top: 20px;
+    padding-bottom: 15px;
+    margin-bottom: 20px;
+    border-bottom: solid 1px rgb(204, 204, 204);
+  }
+  .flex-div{
+    display: flex;
+    width: auto;
+  }
+  .e1{
+    color: #7E5ED0;
+    font-size: 10%;
+    padding-right: 20px;
+    margin-top:2.5px ;
+    margin-left:10px ;
+  }
+  .e2{
+    color: #7E5ED0;
+    font-size: 10%;
+    padding-left: 20px;
+    padding-right: 20px;
+    margin-top:2.5px ;
+  }
+  .e3{
+    color: #909EC3;
+    font-size: 10%;
+    padding-left: 20px;
+    padding-right: 500px;
+    margin-top:2.5px ;
+  }
+  
+  .icon1{
+    padding-left: 20px;
+  }
+  .contain{
+    background-color:white;
+    margin-top: 10px;
+    padding-top: 10px;
+    font-size: 80%;
+    padding-left: 10px;
+    padding-right: 10px;
+    height: 250px;
+  }
+  .contain2{
+    background-color:white;
+    margin-top: 10px;
+    padding-top: 10px;
+    font-size: 80%;
+    padding-left: 10px;
+    height: 250px;
+  }
+  /*.el-table .warning-row {
+    background: #E8EA;
+  } */
+  .text-area{
+    width: 100%;
+    border-top:1px solid gainsboro;
+    border-bottom:1px solid gainsboro;
+ 
+  }
+  .text-area textarea {
+    width: 100%;
+    margin: 0.75rem  0;
+    border: none;
+    outline: none;
+    padding-left: 1.125rem;
+    height: 6.5rem ;
+  }
+ 
+  .text-area textarea::-webkit-input-placeholder {
+    color: #9E9E9E;
+ 
+  }
+
+  </style>
+  

+ 434 - 0
src/pages/MonitorManage/exceptionMonitor/studentMonitor2.vue

@@ -0,0 +1,434 @@
+<template>
+    <Layout>
+      <header class="Monitor-title">
+          <div class="h1">个人监测</div>
+          <div class="flex-div">
+            <div class="e1" float-div @click="() =>{
+            this.$router.push('/home');
+          }">
+            主页
+          </div>
+            <div float-div>/</div>
+            <div class="e2" float-div>
+              监考管理
+            </div>
+            <div float-div>/</div>
+            <div class="e2" float-div @click="() =>{
+            this.$router.push('/exceptionMonitor');
+          }">
+              异常监测
+            </div>
+            <div float-div>/</div>
+            <div class="e3" float-div>
+            个人监测
+          </div>
+            <div class="e2" float-div>
+              2023春季软件——测评考试2
+            </div>
+            
+            <el-button color="#D593C7"
+            @click="() =>{
+            this.$router.push('exceptionHandle');
+          }">
+              查看异常行为处理
+            </el-button>
+            
+            <div class="icon1">
+            <svg t="1681547872625" class="icon" 
+            viewBox="0 0 1024 1024" 
+            version="1.1" 
+            xmlns="http://www.w3.org/2000/svg" 
+            p-id="2704" 
+            width="30" 
+            height="30"
+            >
+            <path 
+            d="M512 22C241.38 22 22 241.38 22 512s219.38 490 490 490 490-219.38 490-490S782.62 22 512 22z 
+            m263.33 312.74l-23.11 124.2-4.02 21.61c-1.81 9.71-11.14 16.12-20.85 
+            14.31l-20.54-3.82-125.41-23.33c-9.71-1.81-16.12-11.14-14.31-20.86l4.02-21.61c1.81-9.71 
+            11.14-16.12 20.85-14.31l61.93 11.52c-46.05-80.06-146.94-112.77-231.92-72.7-89.46 
+            42.18-127.92 149.28-85.74 238.74 42.18 89.46 149.28 127.92 238.74 85.74 17.67-8.33 
+            38.76-0.76 47.09 16.91 8.33 17.67 0.76 38.75-16.91 47.09-49.22 23.21-102.28 28.91-152.09 
+            19.64-76.42-14.22-145.21-63.68-180.82-139.2-58.82-124.75-5.19-274.09 119.56-332.92 115.19-54.32 251.35-12.74 317.85 
+            92.16l9.96-53.55c1.81-9.71 11.14-16.12 20.85-14.31l20.54 3.82c9.73 1.82 16.13 11.16 14.33 20.87z" 
+            fill="#2c2c2c" p-id="2705"></path></svg>
+            </div>
+          </div>
+      </header>
+      <el-row :gutter="24">
+        <el-col :span="10">
+          <div class="contain" float-div>IP异常列表
+          
+          <el-table :data="ip_err" height="220" border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true" 
+          @row-click="jump">
+            <el-table-column prop="id" label="IP异常id" width="50">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="86">
+            </el-table-column>
+            <el-table-column prop="last_ip" label="上次登录IP" width="86">
+            </el-table-column>
+            <el-table-column prop="last_time" label="上次登录时间" width="86">
+            </el-table-column>
+            <el-table-column prop="cur_ip" label="本次登录IP" width="86">
+            </el-table-column>
+            <el-table-column prop="cur_time" label="本次登录时间" width="86">
+            </el-table-column>
+          </el-table>
+        </div>
+        
+        </el-col>
+        <el-col :span="10">
+          <div class="contain" float-div>人数检测异常列表
+          <el-table :data="count_err" height="220"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="人数异常id" width="71">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="102">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+            </el-table-column>
+            <el-table-column prop="valid_count" label="有效入镜人数" width="102">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="contain2" float-div>掉线异常列表
+          <el-table :data="offline" height="220"  border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="掉线异常id" width="60">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="55">
+            </el-table-column>
+            <el-table-column prop="last_time" label="掉线时刻" width="55">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+      </el-row>
+      <el-row :gutter="24">
+        <el-col :span="10">
+          <div class="contain" float-div>姿态检测异常列表
+          <el-table :data="pos_err" height="220" border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="姿态异常id" width="71">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="102">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+            </el-table-column>
+            <el-table-column prop="reason" label="异常原因" width="102">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+        <el-col :span="10">
+          <div class="contain" float-div>人脸识别异常列表
+          <el-table :data="face_err" height="220"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="id" label="人脸识别异常id" width="71">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="102">
+            </el-table-column>
+            <el-table-column prop="org_img" label="用户原画像" width="102">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="contain2" float-div>监控
+          <el-table :data="total_err" height="220"  border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true">
+            <el-table-column prop="name" label="用户名" width="85">
+            </el-table-column>
+            <el-table-column prop="err_count" label="异常次数" width="85">
+            </el-table-column>
+          </el-table>
+        </div>
+        </el-col>
+      </el-row>
+
+    
+      
+    </Layout>
+    <!--弹出页面的内容
+    <el-dialog v-model="LogDialogVisible">
+      <div>IP异常列表
+        <el-table :data="ip_err" height="200" border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="60">
+            </el-table-column>
+            <el-table-column prop="id" label="IP异常id" width="60">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="100">
+            </el-table-column>
+            <el-table-column prop="last_ip" label="上次登录IP" width="120">
+            </el-table-column>
+            <el-table-column prop="last_time" label="上次登录时间" width="135">
+            </el-table-column>
+            <el-table-column prop="cur_ip" label="本次登录IP" width="120">
+            </el-table-column>
+            <el-table-column prop="cur_time" label="本次登录时间" width="135">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>人数检测异常列表
+        <el-table :data="count_err" height="200"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="人数异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="150">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="150">
+            </el-table-column>
+            <el-table-column prop="valid_count" label="有效入镜人数" width="150">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="150">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>姿态异常检测列表
+        <el-table :data="pos_err" height="200"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="姿态异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="150">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="150">
+            </el-table-column>
+            <el-table-column prop="reason" label="异常原因" width="150">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="150">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>人脸识别异常列表
+        <el-table :data="face_err" height="200"  border class="data_table" style="font-size: 1px"
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="人脸识别异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="150">
+            </el-table-column>
+            <el-table-column prop="org_img" label="用户原画像" width="150">
+            </el-table-column>
+            <el-table-column prop="cur_img" label="当前拍摄画像" width="150">
+            </el-table-column>
+            <el-table-column prop="shot_time" label="画面拍摄时间" width="150">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>掉线异常列表
+          <el-table :data="offline" height="200"  border class="data_table" style="font-size: 1px" 
+          :header-cell-style="rowClass" stripe="true" row-key="id"
+          ref="checkTable" @selection-change="doSelectChange">
+            <el-table-column type="selection" label= "勾选" width="65">
+            </el-table-column>
+            <el-table-column prop="id" label="掉线异常id" width="65">
+            </el-table-column>
+            <el-table-column prop="name" label="用户名" width="300">
+            </el-table-column>
+            <el-table-column prop="last_time" label="掉线时刻" width="300">
+            </el-table-column>
+          </el-table>
+      </div>
+      <div>发起理由
+      <div class="text-area">
+        <textarea placeholder="请输入内容">
+        </textarea>
+      </div>
+    </div>
+     
+    <el-button color="#7F83F7"
+    @click="() =>{
+            this.$router.push('studentMonitor2');
+          }">
+    确认
+    </el-button>
+             
+    <el-button color="#DE868F"
+    @click="() =>{
+            this.$router.push('exceptionMonitor');
+          }">
+    取消
+    </el-button>
+    </el-dialog>-->
+  </template>
+  
+  <script>
+  import Layout from "../../../components/Layout.vue";
+  import MuContainer from "muse-ui/src/Grid/Container";
+  export default {
+    name: "exceptionMonitor",
+    components: {Layout,MuContainer},
+    data(){
+      return {
+        LogDialogVisible: false,
+        ip_err:[{
+          id: '16',
+          name: 'MF21320019',
+          last_ip: '183.209.132.59',
+          last_time: '2023-04-09 14:00:00',
+          cur_ip: '180.98.19.28',
+          cur_time: '2023-04-09 14:02:32'
+        },
+  
+      ],count_err:[{
+        id: '5',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        valid_count: '0',
+        shot_time: '2023-04-09 14:11:30'
+      },{
+        id: '6',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        valid_count: '2',
+        shot_time: '2023-04-09 14:15:05'
+      },{
+        id: '7',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        valid_count: '3',
+        shot_time: '2023-04-09 14:18:05'
+      }],offline:[{
+        id:'4',
+        name: 'MF21320019',
+        last_time: '2023-04-09 14:30:05'
+  
+      }],pos_err:[{
+        id: '21',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        reason: '朝右转动角度过大',
+        shot_time: '2023-04-09 14:18:25'
+      },{
+        id: '22',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        reason: '朝右转动角度过大',
+        shot_time: '2023-04-09 14:18:30'
+      },{
+        id: '23',
+        name: 'MF21320019',
+        cur_img: 'picture',
+        reason: '朝左转动角度过大',
+        shot_time: '2023-04-09 14:19:00'
+      }],face_err:[{
+        id: '7',
+        name: 'MF21320019',
+        org_img: 'picture',
+        cur_img: 'picture',
+        shot_time: '2023-04-09 13:56:24'
+      }],total_err:[{
+        name:'MF21320019',
+        err_count:'8'
+      }]
+
+      }
+    },
+    methods: {
+      rowClass({rowIndex}){
+        if(rowIndex===0){
+          return {background:'#E8EAF6'};
+        }else{
+          return {background:'white'};
+        }
+      },
+      jump(){
+        this.$router.push('studentMonitor');
+      },
+      doSelectChange(val){
+        console.log(val);
+      }
+    }
+  };
+  </script>
+  
+  <style scoped>
+  .h1{
+    font-weight: 400;
+    font-family: Roboto,sans-serif;
+    font-size: 3rem!important;
+    line-height: 3.125rem;
+    letter-spacing: normal!important;
+    margin: 0;
+    padding-bottom: 15px;
+  }
+  .Monitor-title {
+    margin-top: 20px;
+    padding-bottom: 15px;
+    margin-bottom: 20px;
+    border-bottom: solid 1px rgb(204, 204, 204);
+  }
+  .flex-div{
+    display: flex;
+    width: auto;
+  }
+  .e1{
+    color: #7E5ED0;
+    font-size: 10%;
+    padding-right: 20px;
+    margin-top:2.5px ;
+    margin-left:10px ;
+  }
+  .e2{
+    color: #7E5ED0;
+    font-size: 10%;
+    padding-left: 20px;
+    padding-right: 20px;
+    margin-top:2.5px ;
+  }
+  .e3{
+    color: #909EC3;
+    font-size: 10%;
+    padding-left: 20px;
+    padding-right: 500px;
+    margin-top:2.5px ;
+  }
+  
+  .icon1{
+    padding-left: 20px;
+  }
+  .contain{
+    background-color:white;
+    margin-top: 10px;
+    padding-top: 10px;
+    font-size: 80%;
+    padding-left: 10px;
+    padding-right: 10px;
+    height: 250px;
+  }
+  .contain2{
+    background-color:white;
+    margin-top: 10px;
+    padding-top: 10px;
+    font-size: 80%;
+    padding-left: 10px;
+    height: 250px;
+  }
+  /*.el-table .warning-row {
+    background: #E8EA;
+  } */
+  
+
+  </style>
+  

+ 585 - 0
src/pages/MonitorManage/monitorManage.vue

@@ -0,0 +1,585 @@
+<template>
+  <Layout>
+    <CustomTitle title="评测详情"></CustomTitle>
+    <el-container>
+      <el-main>
+        <el-collapse
+          v-model="examInfoCollapse"
+          @change="handleExamInfoCollapseChange"
+        >
+          <el-collapse-item name="1">
+            <template #title>
+              <div class="info-title">评测信息</div>
+            </template>
+            <div class="info-body" v-if="examInfo">
+              <div
+                style="
+                  padding: 16px;
+                  font-size: 1.25rem;
+                  font-weight: 500;
+                  letter-spacing: 0.125rem;
+                  line-height: 2rem;
+                "
+              >
+                评测「{{ examInfo.examName }}」
+              </div>
+              <div class="info-line">
+                <div>
+                  评测邀请码:{{
+                    examInfo.inviteCode ? examInfo.inviteCode : "无"
+                  }}
+                </div>
+                <div>当前难度值:{{ examInfo.difficulty }}</div>
+              </div>
+              <div class="info-line">
+                <div>开始时间:{{ examInfo.startTime }}</div>
+                <div>结束时间:{{ examInfo.endTime }}</div>
+              </div>
+              <div class="info-line">
+                <div>
+                  考试时长:{{
+                    getExamLength(examInfo.startTime, examInfo.endTime)
+                  }}
+                </div>
+              </div>
+              <div class="info-line">
+                <div>职位:{{ examInfo.position }}</div>
+                <div>技能点:{{ examInfo.skills.join(" ") }}</div>
+              </div>
+              <div class="info-line">
+                <div>
+                  备注:{{ examInfo.comment ? examInfo.comment : "无" }}
+                </div>
+              </div>
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+
+        <el-collapse v-model="questionCollapse"
+                     @change="handleQuestionCollapseChange">
+          <el-collapse-item name="1">
+            <template #title>
+              <div class="info-title">试卷题目</div>
+            </template>
+            <div v-if="!fetching">
+              <exam-questions-info
+                  :exam-questions="examQuestions"
+              ></exam-questions-info>
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+
+        <el-collapse v-model="listCollapse"
+                     @change="handleListCollapseChange">
+          <el-collapse-item name="1">
+            <template #title>
+              <div class="info-title">评测名单</div>
+            </template>
+            <div class="list-container">
+              <div class="list-header">
+                <div style="width: 10%;">序号</div>
+                <div style="width: 30%;">用户名</div>
+                <div style="width: 30%;">邮箱</div>
+                <div style="width: 30%;">成绩</div>
+              </div>
+              <div v-for="user in joinedUsers" class="list-body">
+                <div style="width: 10%;"><div class="sequence">{{joinedUsers.indexOf(user) + 1}}</div></div>
+                <div style="width: 30%;">{{ user.name }}</div>
+                <div style="width: 30%;">{{ user.email }}</div>
+                <div style="width: 30%;">{{ user.score }}</div>
+              </div>
+            </div>
+
+
+          </el-collapse-item>
+        </el-collapse>
+
+        <el-collapse v-model="cheatCollapse"
+                     @change="handleCheatCollapseChange">
+          <el-collapse-item name="1">
+            <template #title>
+              <div class="info-title">作弊名单</div>
+            </template>
+            <div class="list-container">
+              <div class="list-header">
+                <div style="width: 10%;">序号</div>
+                <div style="width: 30%;">用户名</div>
+                <div style="width: 30%;">邮箱</div>
+                <div style="width: 30%;">异常行为报告</div>
+              </div>
+              <div v-for="user in cheatUsers" class="list-body">
+                <div style="width: 10%;"><div class="sequence">{{cheatUsers.indexOf(user) + 1}}</div></div>
+                <div style="width: 30%;">{{ user.name }}</div>
+                <div style="width: 30%;">{{ user.email }}</div>
+                <div style="width: 30%;"><el-button type="text" @click="jumpToExceptionPage(user.id)">查看详情</el-button></div>
+              </div>
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+
+        <el-collapse v-model="duplicateCheckCollapse"
+                     @change="handleDuplicateCheckCollapseChange">
+          <div style="font-size: 34px; width: 100%; text-align: center; padding: 10px 0; background-color: white;">代码查重结果</div>
+          <el-collapse-item name="1">
+            <template #title>
+              <div class="info-title" style="font-size: 24px;">JPLAG</div>
+            </template>
+            <div class="list-container">
+              <div class="list-header">
+                <div style="width: 10%;">序号</div>
+                <div style="width: 30%;">用户名一</div>
+                <div style="width: 30%;">用户名二</div>
+                <div style="width: 30%;">代码相似度</div>
+              </div>
+              <div v-for="res in jplagResults" class="list-body">
+                <div style="width: 10%;"><div class="sequence">{{jplagResults.indexOf(res) + 1}}</div></div>
+                <div style="width: 30%;">{{ res.username1 }}</div>
+                <div style="width: 30%;">{{ res.username2 }}</div>
+                <div style="width: 30%;">{{ res.similarity }}</div>
+              </div>
+            </div>
+          </el-collapse-item>
+          <el-collapse-item name="2">
+            <template #title>
+              <div class="info-title" style="font-size: 24px;">simple-dpg</div>
+            </template>
+            <div class="list-container">
+              <div class="list-header">
+                <div style="width: 10%;">序号</div>
+                <div style="width: 30%;">用户名一</div>
+                <div style="width: 30%;">用户名二</div>
+                <div style="width: 30%;">代码相似度</div>
+              </div>
+              <div v-for="res in simpleDpgResults" class="list-body">
+                <div style="width: 10%;"><div class="sequence">{{simpleDpgResults.indexOf(res) + 1}}</div></div>
+                <div style="width: 30%;">{{ res.username1 }}</div>
+                <div style="width: 30%;">{{ res.username2 }}</div>
+                <div style="width: 30%;">{{ res.similarity }}</div>
+              </div>
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+      </el-main>
+    </el-container>
+  </Layout>
+</template>
+
+<script>
+import Layout from "../../components/Layout.vue";
+import CustomTitle from "../../components/CustomTitle.vue";
+import examQuestionsInfo from "../../components/ExamQuestionsInfo.vue";
+import {timeLength} from "../../common/util.js";
+
+export default {
+  name: "monitorManage",
+  components: {CustomTitle, Layout, examQuestionsInfo},
+  data(){
+    return {
+      examInfo: {
+        antiCheating: true,
+        comment: '评论',
+        creatorId: 230,
+        difficulty: 250,
+        endTime: '2023-04-16 23:59:59',
+        position: 'Java工程师',
+        skills: ['Java', 'C++'],
+        startTime: '2023-04-15 23:59:59',
+        examName: '测试多次考试功能',
+        isPublic: true,
+        isHidden: true,
+        courseId: 123,
+        course: {
+          id: 123,
+          name: 'kecheng',
+          code: '123',
+          isPublic: true,
+          isJoined: true,
+        },
+        examId: 12,
+        inviteCode: '',
+        isJoined: true, // 该变量仅在/exam/list 中有意义,其他接口要注意处理
+        isFinished: false,
+      },
+      examInfoCollapse: ['1'],
+      questionCollapse: ['1'],
+      listCollapse: ['1'],
+      cheatCollapse: ['1'],
+      duplicateCheckCollapse: ['1', '2'],
+
+      examQuestions: [
+        {
+          "id": "19030",
+          "stem": "系统可维护性的评价指标不包括()。",
+          "type": "choice",
+          "options": {
+            "A": "可理解性",
+            "B": "可测试性",
+            "C": "可移植性",
+            "D": "可修改性"
+          },
+          "answer": "C",
+          "keyPoints": "软件质量",
+          "analysis": "软件的可维护性是指纠正软件系统出现的错误和缺陷,以及为满足新的要求进行修改.扩充或压缩的容易程度,是软件开发阶段各个时期的关键目标。其中可理解性、可测试性和可修改性是衡量可维护性的重要指标。",
+          "knowledgeId": ["SQ.PC.SQR"],
+          "lastModifiedTime": "2020-03-07T15:53:12.523Z"
+        },
+        {
+          "id": "19031",
+          "stem": "逆向工程从源代码或目标代码中提取设计信息,通常在原软件生命周期的()阶段进行。",
+          "type": "choice",
+          "options": {
+            "A": "需求分析",
+            "B": "软件设计",
+            "C": "软件实现",
+            "D": "软件维护"
+          },
+          "answer": "D",
+          "keyPoints": "软件工程",
+          "analysis": "逆向工程从详细的源代码实现中抽取抽象规格说明,一般来说是在原软件交付用户使用之后进行的,即在原软件的维护阶段进行。",
+          "knowledgeId": ["SM.TM.RE"],
+          "lastModifiedTime": "2020-03-07T15:53:12.523Z"
+        },
+        {
+          "id": "19033",
+          "stem": ". ()不是单元测试主要检查的内容。",
+          "type": "choice",
+          "options": {
+            "A": "模块接口",
+            "B": "局部数据结构",
+            "C": "全局数据结构",
+            "D": "重要的执行路径"
+          },
+          "answer": "C",
+          "keyPoints": "软件测试",
+          "analysis": "单元测试又称为模块测试,是针对软件设计的最小单元(程序模块),进行正确性检验的测试。其目的在于发现个模块内不可能存在的各种问题和错误。单元测试需要从程序的内部结构出发设计测试用例。模块可以单独进行单元测试。单元测试测试以下几个方面:模块接口、局部数据结构、执行路径、错误处理和边界。",
+          "knowledgeId": ["ST.STF.TRT"],
+          "lastModifiedTime": "2020-03-07T15:53:12.523Z"
+        },
+        {
+          "id": "19035",
+          "stem": "在执行如下所示的 UML 活动图时,能同时运行的最大线程数为()。\n![](https://seec.oss-cn-beijing.aliyuncs.com/%E9%A2%98%E5%BA%93/%E9%A2%98%E7%9B%AE%E5%9B%BE%E7%89%87%E6%95%B0%E6%8D%AE/10/media/image5.png)",
+          "type": "choice",
+          "options": {
+            "A": "4",
+            "B": "3",
+            "C": "2",
+            "D": "1"
+          },
+          "answer": "C",
+          "keyPoints": "统一建模语言(UML)",
+          "analysis": "UML活动图用于构建系统的活动。建模用例执行过程中对象如何通过消息相互交互,将系统作为一个整体或者几个子系统进行考虑。对象在运行时可能会存在两个或多个并发运行的控制流,为了对并发控制流进行建模,UML 中引入同步的概念,用同步棒黑色粗线条表示并发分支与汇合。",
+          "knowledgeId": ["SD.SDN.BDDV"],
+          "lastModifiedTime": "2020-03-07T15:53:12.523Z"
+        },
+        {
+          "id": "19037",
+          "stem": "在面向对象技术中,()定义了超类和之类之间的关系,子类中以更具体的方式实现从父类继承来的方法称为 () ,不同类的对象通过 ()相互通信。",
+          "type": "choice",
+          "options": {
+            "A": "覆盖, 继承, 消息",
+            "B": "继承, 多态, 覆盖",
+            "C": "消息, 继承, 覆盖",
+            "D": "多态, 覆盖, 消息"
+          },
+          "answer": "D",
+          "keyPoints": "面向对象",
+          "analysis": "在面向对象技术中,继承关系是一种模仿现实世界中继承关系的一种类之间的关\n系,是超类(父类)和予类之间共享数据和方法的机制。在定义和实现一个类的时候,可以在一个已经存在的类的基础上来进行,子类可以继承其父类中的属性和操作作为自己的内容而不必自己定义,也可以用更具体地方式实现从父类继承来的方法,称为覆盖。不同的对象收到同一消息可以进行不同的响应,产生完全不同的结果,用户可以发送一个通用的消息,而实现细节则由接收对象自行决定,使得同一个消息就可以调用不同的方法,即一个对象具有多种形态,称为多态。不同类的对象通过消息相互通信。",
+          "knowledgeId": ["SD.SDSM.OOD"],
+          "lastModifiedTime": "2020-03-07T15:53:12.523Z"
+        }
+      ],
+
+      joinedUsers: [
+          {
+        "id": 3257,
+        "role": "STUDENT",
+        "name": "测试账号yhd",
+        "email": "181250171@smail.nju.edu.cn",
+        "phone": "17739736385"
+      }, {
+        "id": 3432,
+        "role": "STUDENT",
+        "name": "MakiseKurisu",
+        "email": "liuyanqi20050415@qq.com",
+        "phone": "16691571378"
+      }, {
+        "id": 1455,
+        "role": "STUDENT",
+        "name": "LiXueSong",
+        "email": "443093653@qq.com",
+        "phone": "18981522667"
+      }, {
+        "id": 3414,
+        "role": "STUDENT",
+        "name": "Hann",
+        "email": "744757403@qq.com",
+        "phone": "18503763003"
+      }, {
+        "id": 3396,
+        "role": "STUDENT",
+        "name": "Dreamer",
+        "email": "221250078@smail.nju.edu.cn",
+        "phone": "18551089616"
+      }, {
+        "id": 3497,
+        "role": "STUDENT",
+        "name": "菜菜-捞捞",
+        "email": "859112428@qq.com",
+        "phone": "18779638115"
+      }, {
+        "id": 3687,
+        "role": "STUDENT",
+        "name": "arctan40",
+        "email": "221830203@smail.nju.edu.cn",
+        "phone": "13561175557"
+      }, {
+        "id": 3517,
+        "role": "STUDENT",
+        "name": "姚天瑜",
+        "email": "211870074@smail.nju.edu.cn",
+        "phone": "19952830402"
+      }, {
+        "id": 3723,
+        "role": "STUDENT",
+        "name": "周屿杨",
+        "email": "221870148@smail.nju.edu.cn",
+        "phone": "19962638018"
+      }, {
+        "id": 3482,
+        "role": "STUDENT",
+        "name": "编不出来了",
+        "email": "2105054767@qq.com",
+        "phone": "19887016128"
+      }],
+
+      reports: [
+        {
+          "id": 539,
+          "score": 40.0,
+          "rank": 0,
+          "submitTime": "2023-03-04 15:39:39",
+          "userId": 3257
+        }, {
+          "id": 540,
+          "score": 40.0,
+          "rank": 0,
+          "submitTime": "2023-03-05 10:19:05",
+          "userId": 3432
+        }, {
+          "id": 544,
+          "score": 0.0,
+          "rank": 0,
+          "submitTime": null,
+          "userId": 1455
+        }, {
+          "id": 565,
+          "score": 20.0,
+          "rank": 0,
+          "submitTime": "2023-03-05 00:46:54",
+          "userId": 3414
+        }, {
+          "id": 567,
+          "score": 0.0,
+          "rank": 0,
+          "submitTime": null,
+          "userId": 3396
+        }, {
+          "id": 571,
+          "score": 0.0,
+          "rank": 0,
+          "submitTime": null,
+          "userId": 3497
+        }, {
+          "id": 587,
+          "score": 40.0,
+          "rank": 0,
+          "submitTime": "2023-03-05 15:30:46",
+          "userId": 3687
+        }, {
+          "id": 588,
+          "score": 20.0,
+          "rank": 0,
+          "submitTime": "2023-03-05 15:20:18",
+          "userId": 3517
+        }, {
+          "id": 594,
+          "score": 60.0,
+          "rank": 0,
+          "submitTime": "2023-03-05 16:50:24",
+          "userId": 3723
+        }, {
+          "id": 608,
+          "score": 40.0,
+          "rank": 0,
+          "submitTime": "2023-03-05 20:12:52",
+          "userId": 3482
+        }
+      ],
+
+      cheatUsers: [
+        {
+          "id": 3257,
+          "role": "STUDENT",
+          "name": "测试账号yhd",
+          "email": "181250171@smail.nju.edu.cn",
+          "phone": "17739736385",
+        }, {
+          "id": 3432,
+          "role": "STUDENT",
+          "name": "MakiseKurisu",
+          "email": "liuyanqi20050415@qq.com",
+          "phone": "16691571378"
+        }
+      ],
+
+      jplagResults: [
+        {
+          id: 123,
+          userid1: 3257,
+          username1: '测试账号yhd',
+          userid2: 3432,
+          username2: 'MakiseKurisu',
+          similarity: '80%'
+        },
+        {
+          id: 124,
+          userid1: 1455,
+          username1: 'LiXueSong',
+          userid2: 3414,
+          username2: 'Hann',
+          similarity: '99.9%'
+        }
+      ],
+      simpleDpgResults: [
+        {
+          id: 125,
+          userid1: 3396,
+          username1: 'Dreamer',
+          userid2: 3497,
+          username2: '菜菜-捞捞',
+          similarity: '10%'
+        },
+        {
+          id: 126,
+          userid1: 3687,
+          username1: 'arctan40',
+          userid2: 3517,
+          username2: '姚天瑜',
+          similarity: '50%'
+        }
+      ]
+    }
+  },
+  computed: {
+    fetching() {
+      return this.examQuestions.length === 0;
+    }
+  },
+  methods: {
+    getExamLength(startTime, endTime) {
+      return timeLength(startTime, endTime)
+    },
+    handleExamInfoCollapseChange(val) {
+      console.log(val);
+    },
+    handleQuestionCollapseChange(val) {
+      console.log(val);
+    },
+    handleListCollapseChange(val) {
+      console.log(val);
+    },
+    handleCheatCollapseChange(val) {
+      console.log(val);
+    },
+    jumpToExceptionPage(userId) {
+      console.log(`跳转到用户${userId}的异常报告界面`);
+    },
+    handleDuplicateCheckCollapseChange(val) {
+      console.log(val);
+    }
+  },
+  mounted() {
+    let that = this
+    this.joinedUsers.forEach((user) => {
+      this.reports.forEach((report) => {
+        if (report.userId === user.id) {
+          user['score'] = report.score
+          // that.$set(user, 'score', report.score)
+        }
+      })
+    })
+  }
+}
+</script>
+
+<style scoped>
+.info-title {
+  width: 100%;
+  font-size: 34px;
+  font-family: Roboto, sans-serif;
+  font-weight: 400;
+  text-align: center;
+}
+:deep(.el-collapse-item__header) {
+  padding: 10px;
+}
+
+:deep(.el-collapse) {
+  margin-bottom: 20px;
+  transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+  will-change: box-shadow;
+  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14),
+    0 1px 5px 0 rgba(0, 0, 0, 0.12);
+}
+
+.info-body {
+  padding: 0 24px 16px;
+}
+
+.info-line {
+  display: flex;
+  padding: 6px 20px 12px;
+  font-size: 0.875rem;
+  font-weight: 400;
+  line-height: 1.375rem;
+  letter-spacing: 0.0071428571em;
+  color: rgba(0, 0, 0, 0.87);
+}
+.info-line div {
+  width: 50%;
+}
+
+.list-header {
+  display: flex;
+  font-weight: 500;
+  padding-left: 20px;
+  padding-top: 10px;
+  padding-bottom: 5px;
+}
+
+.list-body {
+  display: flex;
+  align-items: center;
+  padding-left: 20px;
+  height: 56px;
+  font-family: Roboto, sans-serif;
+}
+.list-body:hover {
+  background-color: #f5f5f5;
+}
+
+.list-container {
+  padding: 0 24px 16px;
+  font-size: 16px;
+  color: #212121;
+}
+
+.sequence {
+  width: 32px;
+  height: 32px;
+  border-radius: 4px;
+  background-color: #e0e0e0;
+  text-align: center;
+  line-height: 32px;
+}
+</style>

+ 20 - 0
src/pages/MonitorManage/studentStatus/studentStatus.vue

@@ -0,0 +1,20 @@
+<template>
+  <layout>
+    <div>考生状态</div>
+  </layout>
+</template>
+
+<script>
+import layout from "../../../components/Layout.vue";
+
+export default {
+  name: "studentStatus",
+  components: {
+      layout
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 364 - 0
src/pages/MonitorManage/videoMonitor/videoMonitor.vue

@@ -0,0 +1,364 @@
+<template>
+  <Layout>
+    <header class="Monitor-title">
+        <div class="h1">视频监控</div>
+        <div class="flex-div">
+          <div class="e1" float-div @click="() =>{
+            this.$router.push('/home');
+          }">
+            主页
+          </div>
+          <div float-div>/</div>
+          <div class="e2" float-div >
+            监考管理
+          </div>
+          <div float-div>/</div>
+          <div class="e3" float-div>
+            视频监控
+          </div>
+          <div class="e2" float-div>
+            2023春季软件——测评考试2
+          </div>
+          <div class="b1">
+          <el-button color="#7E5ED0"
+          @click="() =>{
+            this.$router.push('/home');
+          }">退出监考</el-button>
+          </div>
+          <div class="icon1">
+          <svg t="1681547872625" class="icon" 
+          viewBox="0 0 1024 1024" 
+          version="1.1" 
+          xmlns="http://www.w3.org/2000/svg" 
+          p-id="2704" 
+          width="30" 
+          height="30"
+          >
+          <path 
+          d="M512 22C241.38 22 22 241.38 22 512s219.38 490 490 490 490-219.38 490-490S782.62 22 512 22z 
+          m263.33 312.74l-23.11 124.2-4.02 21.61c-1.81 9.71-11.14 16.12-20.85 
+          14.31l-20.54-3.82-125.41-23.33c-9.71-1.81-16.12-11.14-14.31-20.86l4.02-21.61c1.81-9.71 
+          11.14-16.12 20.85-14.31l61.93 11.52c-46.05-80.06-146.94-112.77-231.92-72.7-89.46 
+          42.18-127.92 149.28-85.74 238.74 42.18 89.46 149.28 127.92 238.74 85.74 17.67-8.33 
+          38.76-0.76 47.09 16.91 8.33 17.67 0.76 38.75-16.91 47.09-49.22 23.21-102.28 28.91-152.09 
+          19.64-76.42-14.22-145.21-63.68-180.82-139.2-58.82-124.75-5.19-274.09 119.56-332.92 115.19-54.32 251.35-12.74 317.85 
+          92.16l9.96-53.55c1.81-9.71 11.14-16.12 20.85-14.31l20.54 3.82c9.73 1.82 16.13 11.16 14.33 20.87z" 
+          fill="#2c2c2c" p-id="2705"></path></svg>
+          </div>
+        </div>
+    </header>
+    <!--<el-row :gutter="24">
+      <el-col :span="10">
+        <div class="contain" float-div>IP异常列表
+        <el-table :data="ip_err" height="220" border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true" 
+        @row-click="jump">
+          <el-table-column prop="id" label="IP异常id" width="50">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="86">
+          </el-table-column>
+          <el-table-column prop="last_ip" label="上次登录IP" width="86">
+          </el-table-column>
+          <el-table-column prop="last_time" label="上次登录时间" width="86">
+          </el-table-column>
+          <el-table-column prop="cur_ip" label="本次登录IP" width="86">
+          </el-table-column>
+          <el-table-column prop="cur_time" label="本次登录时间" width="86">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="10">
+        <div class="contain" float-div>人数检测异常列表
+        <el-table :data="count_err" height="220"  border class="data_table" style="font-size: 1px"
+        :header-cell-style="rowClass" stripe="true">
+          <el-table-column prop="id" label="人数异常id" width="71">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="102">
+          </el-table-column>
+          <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+          </el-table-column>
+          <el-table-column prop="valid_count" label="有效入镜人数" width="102">
+          </el-table-column>
+          <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="contain2" float-div>掉线异常列表
+        <el-table :data="offline" height="220"  border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true">
+          <el-table-column prop="id" label="掉线异常id" width="60">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="55">
+          </el-table-column>
+          <el-table-column prop="last_time" label="掉线时刻" width="55">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+    </el-row>
+    <el-row :gutter="24">
+      <el-col :span="10">
+        <div class="contain" float-div>姿态检测异常列表
+        <el-table :data="pos_err" height="220" border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true">
+          <el-table-column prop="id" label="姿态异常id" width="71">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="102">
+          </el-table-column>
+          <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+          </el-table-column>
+          <el-table-column prop="reason" label="异常原因" width="102">
+          </el-table-column>
+          <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="10">
+        <div class="contain" float-div>人脸识别异常列表
+        <el-table :data="face_err" height="220"  border class="data_table" style="font-size: 1px"
+        :header-cell-style="rowClass" stripe="true">
+          <el-table-column prop="id" label="人脸识别异常id" width="71">
+          </el-table-column>
+          <el-table-column prop="name" label="用户名" width="102">
+          </el-table-column>
+          <el-table-column prop="org_img" label="用户原画像" width="102">
+          </el-table-column>
+          <el-table-column prop="cur_img" label="当前拍摄画像" width="102">
+          </el-table-column>
+          <el-table-column prop="shot_time" label="画面拍摄时间" width="102">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="contain2" float-div>总异常排行
+        <el-table :data="total_err" height="220"  border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true">
+          <el-table-column prop="name" label="用户名" width="85">
+          </el-table-column>
+          <el-table-column prop="err_count" label="异常次数" width="85">
+          </el-table-column>
+        </el-table>
+      </div>
+      </el-col>
+    </el-row>-->
+    <el-row :gutter="24">
+      <el-col :span="18">
+        <el-row :gutter="24">
+          <el-col :span="8">
+            <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+
+        <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+
+        <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+          </el-col>
+          <el-col :span="8">
+            <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+
+        <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+
+        <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+          </el-col>
+          <el-col :span="8">
+            <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+
+        <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+
+        <div class="contain3" float-div>
+        <el-table :data="camera" height="80"  border class="data_table" style="font-size: 1px">
+          <el-table-column prop="name" label="用户名" width="133">
+          </el-table-column>
+          <el-table-column prop="err_count" label="总异常次数" width="133">
+          </el-table-column>
+        </el-table></div>
+          </el-col>
+        </el-row>
+
+        <!--<el-pagination @size-change="sizeChange" @current-change="currentChange"
+          :current-page="page" :page-size="size" :page-sizes="pageSizes"
+          layout="total, sizes, prev, pager, next, jumper" :total="total">
+        </el-pagination>-->
+
+      </el-col>
+      <el-col :span="6">
+        <div class="contain2" float-div>未开摄像头学生列表
+        <el-table :data="student_list" height="700"  border class="data_table" style="font-size: 1px" 
+        :header-cell-style="rowClass" stripe="true">
+          <el-table-column prop="name" label="用户名" width="132">
+          </el-table-column>
+          <el-table-column prop="tel_number" label="手机号" width="140">
+          </el-table-column>
+        </el-table>
+      </div></el-col>
+    </el-row>
+
+
+    
+  </Layout>
+</template>
+
+<script>
+import Layout from "../../../components/Layout.vue";
+export default {
+  name: "exceptionMonitor",
+  components: {Layout},
+  data(){
+    return {
+      student_list:[{
+      name: 'MF21320019',
+      tel_number: '15061718022'
+    }],
+      camera:[{
+        name: 'MF21320019',
+        err_count: '8'
+      }]
+
+
+    }
+  },
+  
+  methods: {
+    rowClass({rowIndex}){
+      if(rowIndex===0){
+        return {background:'#E8EAF6'};
+      }else{
+        return {background:'white'};
+      }
+    },
+    /*currentChange(val){
+      console.log("翻页,当前为第几页", val);
+      this.page = val;
+      this.get
+    }*/
+  }
+};
+</script>
+
+<style scoped>
+.h1{
+  font-weight: 400;
+  font-family: Roboto,sans-serif;
+  font-size: 3rem!important;
+  line-height: 3.125rem;
+  letter-spacing: normal!important;
+  margin: 0;
+  padding-bottom: 15px;
+}
+.Monitor-title {
+  margin-top: 20px;
+  padding-bottom: 15px;
+  margin-bottom: 20px;
+  border-bottom: solid 1px rgb(204, 204, 204);
+}
+.flex-div{
+  display: flex;
+  width: auto;
+}
+.e1{
+  color: #7E5ED0;
+  font-size: 10%;
+  padding-right: 20px;
+  margin-top:2.5px ;
+  margin-left:10px ;
+}
+.e2{
+  color: #7E5ED0;
+  font-size: 10%;
+  padding-left: 20px;
+  padding-right: 20px;
+  margin-top:2.5px ;
+}
+.e3{
+  color: #909EC3;
+  font-size: 10%;
+  padding-left: 20px;
+  padding-right: 650px;
+  margin-top:2.5px ;
+}
+.b1{
+  
+}
+.icon1{
+  padding-left: 20px;
+}
+.contain{
+  background-color:white;
+  margin-top: 10px;
+  padding-top: 10px;
+  font-size: 80%;
+  padding-left: 10px;
+  padding-right: 10px;
+  height: 250px;
+}
+.contain2{
+  background-color:white;
+  margin-top: 10px;
+  padding-top: 10px;
+  font-size: 80%;
+  padding-left: 10px;
+  padding-right: 10px;
+  height: 790px;
+}
+.contain3{
+  background-color:white;
+  margin-top: 10px;
+  padding-top: 10px;
+  font-size: 80%;
+  padding-left: 10px;
+  padding-right: 10px;
+  height: 250px;
+}
+
+</style>

+ 80 - 0
src/router/index.js

@@ -0,0 +1,80 @@
+import { createRouter, createWebHashHistory } from 'vue-router'
+import {PATH} from "../common/const.js";
+
+const routes = [
+    {
+        path: '/',
+        name: 'home',
+        component: () => import('../App.vue'),
+        redirect: PATH.HOME.path,
+        children: [
+            {
+                path: PATH.HOME.path,
+                component: () => import('../pages/Home/Home.vue'),
+                meta: { requiresAuth: PATH.HOME.requiresAuth }
+            },
+            {
+                path: PATH.EVAL_MANAGE.path,
+                name: 'eval_manage',
+                component: () => import('../pages/EvalManage/evalManage.vue'),
+                meta: { requiresAuth: PATH.EVAL_MANAGE.requiresAuth }
+            },
+            {
+                path: PATH.MONITOR_MANAGE.path,
+                name: 'monitor_manage',
+                component: () => import('../pages/MonitorManage/monitorManage.vue'),
+                meta: { requiresAuth: PATH.MONITOR_MANAGE.requiresAuth }
+            },
+            {
+                path: PATH.EXCEPTION_MONITOR.path,
+                name: 'exception_monitor',
+                component: () => import('../pages/MonitorManage/exceptionMonitor/exceptionMonitor.vue'),
+                meta: { requiresAuth: PATH.EXCEPTION_MONITOR.requiresAuth }
+            },
+            {
+                path: PATH.STUDENT_MONITOR.path,
+                name: 'student_monitor',
+                component: () => import('../pages/MonitorManage/exceptionMonitor/studentMonitor.vue'),
+                meta: {requiresAuth: PATH.STUDENT_MONITOR.requiresAuth}
+            },
+            {
+                path: PATH.STUDENT_MONITOR_2.path,
+                name: 'student_monitor_2',
+                component: () => import('../pages/MonitorManage/exceptionMonitor/studentMonitor2.vue'),
+                meta: {requiresAuth: PATH.STUDENT_MONITOR_2.requiresAuth}
+            },  
+            {
+                path: PATH.STUDENT_STATUS.path,
+                name: 'student_status',
+                component: () => import('../pages/MonitorManage/studentStatus/studentStatus.vue'),
+                meta: { requiresAuth: PATH.STUDENT_STATUS.requiresAuth }
+            },
+            {
+                path: PATH.VIDEO_MONITOR.path,
+                name: 'video_monitor',
+                component: () => import('../pages/MonitorManage/videoMonitor/videoMonitor.vue'),
+                meta: { requiresAuth: PATH.VIDEO_MONITOR.requiresAuth }
+            },
+            {
+                path: PATH.EXCEPTION_HANDLE.path,
+                name: 'exception_handle',
+                component: () => import('../pages/MonitorManage/exceptionHandle/exceptionHandle.vue'),
+                meta: { requiresAuth: PATH.EXCEPTION_HANDLE.requiresAuth }
+            },
+        ]
+    },
+
+];
+
+
+const router = createRouter({
+    history: createWebHashHistory('/'),
+    routes,
+    scrollBehavior: () => ({ left: 0, top: 0 }),
+})
+
+router.beforeEach(async (to, from, next) => {
+    next();
+});
+
+export default router;

+ 47 - 0
src/style.css

@@ -0,0 +1,47 @@
+/*:root {*/
+/*    --card-deep : #f2f8f8;*/
+/*    --bgd-color: #f7f8fa;*/
+/*}*/
+
+
+/*.shkb-card {*/
+/*    box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);*/
+/*    background-color: #ffffff;*/
+/*    border-radius: 10px;*/
+/*}*/
+
+/*body {*/
+/*    min-width: 1200px;*/
+/*}*/
+html,body,#app {
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    background-color: #e8eaf6!important;
+}
+
+a {
+    text-decoration: none;
+    color: #999;
+}
+
+button,a {
+    outline: none;
+}
+
+ul {
+    list-style: none;
+    padding: 0;
+    margin: 0;
+}
+
+.clear-fix:after {/*伪元素是行内元素 正常浏览器清除浮动方法*/
+    content: "";
+    display: block;
+    height: 0;
+    clear:both;
+    visibility: hidden;
+}
+.clear-fix {
+    *zoom: 1;/*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/
+}

+ 16 - 0
vite.config.js

@@ -0,0 +1,16 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [vue()],
+  server: {
+    proxy: {
+      "/api": {
+        target: "http://localhost:8080",
+        changeOrigin: true,
+        rewrite: path => path.replace(/^\/api/, '')
+      },
+    }
+  }
+})