commit 0f6644557b0b1589deafe8af5488571912b46b12
Author: lq <13849061902@qq.com>
Date: Thu Jun 27 16:23:31 2024 +0800
add code
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8ee54e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..a7cea0b
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["Vue.volar"]
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f28ba52
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+# wps
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+npm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+npm run dev
+```
+
+### Compile and Minify for Production
+
+```sh
+npm run build
+```
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..99f583a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..5a1f2d2
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..0c34553
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1318 @@
+{
+ "name": "wps",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "wps",
+ "version": "0.0.0",
+ "dependencies": {
+ "@hufe921/canvas-editor": "^0.9.81",
+ "axios": "^1.7.2",
+ "element-plus": "^2.7.5",
+ "vue": "^3.4.21",
+ "vue-axios": "^3.5.2",
+ "vue-router": "^4.3.3"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.4",
+ "vite": "^5.2.8"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
+ "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@ctrl/tinycolor": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+ "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@element-plus/icons-vue": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
+ "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
+ "peerDependencies": {
+ "vue": "^3.2.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+ "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+ "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+ "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+ "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+ "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+ "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+ "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+ "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+ "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+ "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+ "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+ "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+ "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+ "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+ "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+ "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+ "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+ "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+ "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+ "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+ "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz",
+ "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.6.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz",
+ "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==",
+ "dependencies": {
+ "@floating-ui/core": "^1.0.0",
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
+ "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
+ },
+ "node_modules/@hufe921/canvas-editor": {
+ "version": "0.9.81",
+ "resolved": "https://registry.npmjs.org/@hufe921/canvas-editor/-/canvas-editor-0.9.81.tgz",
+ "integrity": "sha512-4jMcvUKSvueBpdjYntIvT66FJZsALCRXhHe6UBkX/78RzhHW9mS8MzyrUeVYv4wt95o+J2S7GNPkbOaidYoAoA==",
+ "engines": {
+ "node": ">=16.9.1"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+ },
+ "node_modules/@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/@rollup/rollup-android-arm-eabi": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
+ "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
+ "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
+ "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
+ "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
+ "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
+ "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
+ "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
+ "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
+ "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
+ "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
+ "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
+ "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
+ "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
+ "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
+ "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
+ "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true
+ },
+ "node_modules/@types/lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw=="
+ },
+ "node_modules/@types/lodash-es": {
+ "version": "4.17.12",
+ "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
+ "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
+ "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": "5.0.5",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz",
+ "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
+ "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
+ "dependencies": {
+ "@babel/parser": "^7.24.4",
+ "@vue/shared": "3.4.27",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
+ "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
+ "dependencies": {
+ "@vue/compiler-core": "3.4.27",
+ "@vue/shared": "3.4.27"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
+ "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
+ "dependencies": {
+ "@babel/parser": "^7.24.4",
+ "@vue/compiler-core": "3.4.27",
+ "@vue/compiler-dom": "3.4.27",
+ "@vue/compiler-ssr": "3.4.27",
+ "@vue/shared": "3.4.27",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.10",
+ "postcss": "^8.4.38",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
+ "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.4.27",
+ "@vue/shared": "3.4.27"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.3.tgz",
+ "integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw=="
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz",
+ "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
+ "dependencies": {
+ "@vue/shared": "3.4.27"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
+ "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
+ "dependencies": {
+ "@vue/reactivity": "3.4.27",
+ "@vue/shared": "3.4.27"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
+ "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
+ "dependencies": {
+ "@vue/runtime-core": "3.4.27",
+ "@vue/shared": "3.4.27",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
+ "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.4.27",
+ "@vue/shared": "3.4.27"
+ },
+ "peerDependencies": {
+ "vue": "3.4.27"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
+ "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
+ },
+ "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.8",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
+ "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@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.8",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
+ "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/async-validator": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+ "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "node_modules/axios": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+ "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/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": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.11",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz",
+ "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg=="
+ },
+ "node_modules/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.7.5",
+ "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.7.5.tgz",
+ "integrity": "sha512-e4oqhfRGBpdblgsjEBK+tA2+fg1H1KZ2Qinty1SaJl0X49FrMLK0lpXQNheWyBqI4V/pyjVOF9sRjz2hfyoctw==",
+ "dependencies": {
+ "@ctrl/tinycolor": "^3.4.1",
+ "@element-plus/icons-vue": "^2.3.1",
+ "@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/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+ "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.20.2",
+ "@esbuild/android-arm": "0.20.2",
+ "@esbuild/android-arm64": "0.20.2",
+ "@esbuild/android-x64": "0.20.2",
+ "@esbuild/darwin-arm64": "0.20.2",
+ "@esbuild/darwin-x64": "0.20.2",
+ "@esbuild/freebsd-arm64": "0.20.2",
+ "@esbuild/freebsd-x64": "0.20.2",
+ "@esbuild/linux-arm": "0.20.2",
+ "@esbuild/linux-arm64": "0.20.2",
+ "@esbuild/linux-ia32": "0.20.2",
+ "@esbuild/linux-loong64": "0.20.2",
+ "@esbuild/linux-mips64el": "0.20.2",
+ "@esbuild/linux-ppc64": "0.20.2",
+ "@esbuild/linux-riscv64": "0.20.2",
+ "@esbuild/linux-s390x": "0.20.2",
+ "@esbuild/linux-x64": "0.20.2",
+ "@esbuild/netbsd-x64": "0.20.2",
+ "@esbuild/openbsd-x64": "0.20.2",
+ "@esbuild/sunos-x64": "0.20.2",
+ "@esbuild/win32-arm64": "0.20.2",
+ "@esbuild/win32-ia32": "0.20.2",
+ "@esbuild/win32-x64": "0.20.2"
+ }
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "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.30.10",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
+ "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ }
+ },
+ "node_modules/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/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/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/picocolors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
+ },
+ "node_modules/postcss": {
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/rollup": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
+ "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.18.0",
+ "@rollup/rollup-android-arm64": "4.18.0",
+ "@rollup/rollup-darwin-arm64": "4.18.0",
+ "@rollup/rollup-darwin-x64": "4.18.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.18.0",
+ "@rollup/rollup-linux-arm64-musl": "4.18.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.18.0",
+ "@rollup/rollup-linux-x64-gnu": "4.18.0",
+ "@rollup/rollup-linux-x64-musl": "4.18.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.18.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.18.0",
+ "@rollup/rollup-win32-x64-msvc": "4.18.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.2.13",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz",
+ "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.20.1",
+ "postcss": "^8.4.38",
+ "rollup": "^4.13.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.4.27",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz",
+ "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.4.27",
+ "@vue/compiler-sfc": "3.4.27",
+ "@vue/runtime-dom": "3.4.27",
+ "@vue/server-renderer": "3.4.27",
+ "@vue/shared": "3.4.27"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-axios": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-3.5.2.tgz",
+ "integrity": "sha512-GP+dct7UlAWkl1qoP3ppw0z6jcSua5/IrMpjB5O8bh089iIiJ+hdxPYH2NPEpajlYgkW5EVMP95ttXWdas1O0g==",
+ "peerDependencies": {
+ "axios": "*",
+ "vue": "^3.0.0 || ^2.0.0"
+ }
+ },
+ "node_modules/vue-router": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.3.tgz",
+ "integrity": "sha512-8Q+u+WP4N2SXY38FDcF2H1dUEbYVHVPtPCPZj/GTZx8RCbiB8AtJP9+YIxn4Vs0svMTNQcLIzka4GH7Utkx9xQ==",
+ "dependencies": {
+ "@vue/devtools-api": "^6.5.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "vue": "^3.2.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..394965f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "wps",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@hufe921/canvas-editor": "^0.9.81",
+ "axios": "^1.7.2",
+ "element-plus": "^2.7.5",
+ "vue": "^3.4.21",
+ "vue-axios": "^3.5.2",
+ "vue-router": "^4.3.3"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.4",
+ "vite": "^5.2.8"
+ }
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..3927d67
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,1012 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是否展示
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Appaaa.vue b/src/Appaaa.vue
new file mode 100644
index 0000000..67450d0
--- /dev/null
+++ b/src/Appaaa.vue
@@ -0,0 +1,2197 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/base.css b/src/assets/base.css
new file mode 100644
index 0000000..8816868
--- /dev/null
+++ b/src/assets/base.css
@@ -0,0 +1,86 @@
+/* color palette from */
+:root {
+ --vt-c-white: #ffffff;
+ --vt-c-white-soft: #f8f8f8;
+ --vt-c-white-mute: #f2f2f2;
+
+ --vt-c-black: #181818;
+ --vt-c-black-soft: #222222;
+ --vt-c-black-mute: #282828;
+
+ --vt-c-indigo: #2c3e50;
+
+ --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
+ --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
+ --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
+ --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
+
+ --vt-c-text-light-1: var(--vt-c-indigo);
+ --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
+ --vt-c-text-dark-1: var(--vt-c-white);
+ --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
+}
+
+/* semantic color variables for this project */
+:root {
+ --color-background: var(--vt-c-white);
+ --color-background-soft: var(--vt-c-white-soft);
+ --color-background-mute: var(--vt-c-white-mute);
+
+ --color-border: var(--vt-c-divider-light-2);
+ --color-border-hover: var(--vt-c-divider-light-1);
+
+ --color-heading: var(--vt-c-text-light-1);
+ --color-text: var(--vt-c-text-light-1);
+
+ --section-gap: 160px;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --color-background: var(--vt-c-black);
+ --color-background-soft: var(--vt-c-black-soft);
+ --color-background-mute: var(--vt-c-black-mute);
+
+ --color-border: var(--vt-c-divider-dark-2);
+ --color-border-hover: var(--vt-c-divider-dark-1);
+
+ --color-heading: var(--vt-c-text-dark-1);
+ --color-text: var(--vt-c-text-dark-2);
+ }
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ margin: 0;
+ font-weight: normal;
+}
+
+body {
+ min-height: 100vh;
+ color: var(--color-text);
+ background: var(--color-background);
+ transition:
+ color 0.5s,
+ background-color 0.5s;
+ line-height: 1.6;
+ font-family:
+ Inter,
+ -apple-system,
+ BlinkMacSystemFont,
+ 'Segoe UI',
+ Roboto,
+ Oxygen,
+ Ubuntu,
+ Cantarell,
+ 'Fira Sans',
+ 'Droid Sans',
+ 'Helvetica Neue',
+ sans-serif;
+ font-size: 15px;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/src/assets/images/images/alignment.svg b/src/assets/images/images/alignment.svg
new file mode 100644
index 0000000..08b66e3
--- /dev/null
+++ b/src/assets/images/images/alignment.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/arrow-left.svg b/src/assets/images/images/arrow-left.svg
new file mode 100644
index 0000000..b55538b
--- /dev/null
+++ b/src/assets/images/images/arrow-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/arrow-right.svg b/src/assets/images/images/arrow-right.svg
new file mode 100644
index 0000000..1aadb00
--- /dev/null
+++ b/src/assets/images/images/arrow-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/block.svg b/src/assets/images/images/block.svg
new file mode 100644
index 0000000..38b1704
--- /dev/null
+++ b/src/assets/images/images/block.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/bold.svg b/src/assets/images/images/bold.svg
new file mode 100644
index 0000000..80728d0
--- /dev/null
+++ b/src/assets/images/images/bold.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/catalog.svg b/src/assets/images/images/catalog.svg
new file mode 100644
index 0000000..90d45c2
--- /dev/null
+++ b/src/assets/images/images/catalog.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/center.svg b/src/assets/images/images/center.svg
new file mode 100644
index 0000000..28dc13c
--- /dev/null
+++ b/src/assets/images/images/center.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/checkbox.svg b/src/assets/images/images/checkbox.svg
new file mode 100644
index 0000000..d522091
--- /dev/null
+++ b/src/assets/images/images/checkbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/close.svg b/src/assets/images/images/close.svg
new file mode 100644
index 0000000..e5b1c23
--- /dev/null
+++ b/src/assets/images/images/close.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/codeblock.svg b/src/assets/images/images/codeblock.svg
new file mode 100644
index 0000000..6c3163c
--- /dev/null
+++ b/src/assets/images/images/codeblock.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/color.svg b/src/assets/images/images/color.svg
new file mode 100644
index 0000000..2b84e88
--- /dev/null
+++ b/src/assets/images/images/color.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/control.svg b/src/assets/images/images/control.svg
new file mode 100644
index 0000000..3fde9fb
--- /dev/null
+++ b/src/assets/images/images/control.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/date.svg b/src/assets/images/images/date.svg
new file mode 100644
index 0000000..065db22
--- /dev/null
+++ b/src/assets/images/images/date.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/exit-fullscreen.svg b/src/assets/images/images/exit-fullscreen.svg
new file mode 100644
index 0000000..7999e25
--- /dev/null
+++ b/src/assets/images/images/exit-fullscreen.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/format.svg b/src/assets/images/images/format.svg
new file mode 100644
index 0000000..aae6e6b
--- /dev/null
+++ b/src/assets/images/images/format.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/highlight.svg b/src/assets/images/images/highlight.svg
new file mode 100644
index 0000000..c4b2e8b
--- /dev/null
+++ b/src/assets/images/images/highlight.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/hyperlink.svg b/src/assets/images/images/hyperlink.svg
new file mode 100644
index 0000000..45090f6
--- /dev/null
+++ b/src/assets/images/images/hyperlink.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/image.svg b/src/assets/images/images/image.svg
new file mode 100644
index 0000000..7b43678
--- /dev/null
+++ b/src/assets/images/images/image.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/italic.svg b/src/assets/images/images/italic.svg
new file mode 100644
index 0000000..73b2af5
--- /dev/null
+++ b/src/assets/images/images/italic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/latex.svg b/src/assets/images/images/latex.svg
new file mode 100644
index 0000000..ca5426b
--- /dev/null
+++ b/src/assets/images/images/latex.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/left.svg b/src/assets/images/images/left.svg
new file mode 100644
index 0000000..b41d2b2
--- /dev/null
+++ b/src/assets/images/images/left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/line-dash-dot-dot.svg b/src/assets/images/images/line-dash-dot-dot.svg
new file mode 100644
index 0000000..30ab5ac
--- /dev/null
+++ b/src/assets/images/images/line-dash-dot-dot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/line-dash-dot.svg b/src/assets/images/images/line-dash-dot.svg
new file mode 100644
index 0000000..1958671
--- /dev/null
+++ b/src/assets/images/images/line-dash-dot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/line-dash-large-gap.svg b/src/assets/images/images/line-dash-large-gap.svg
new file mode 100644
index 0000000..2e38e60
--- /dev/null
+++ b/src/assets/images/images/line-dash-large-gap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/line-dash-small-gap.svg b/src/assets/images/images/line-dash-small-gap.svg
new file mode 100644
index 0000000..88d6082
--- /dev/null
+++ b/src/assets/images/images/line-dash-small-gap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/line-dot.svg b/src/assets/images/images/line-dot.svg
new file mode 100644
index 0000000..c08b564
--- /dev/null
+++ b/src/assets/images/images/line-dot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/line-single.svg b/src/assets/images/images/line-single.svg
new file mode 100644
index 0000000..453d4fa
--- /dev/null
+++ b/src/assets/images/images/line-single.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/list.svg b/src/assets/images/images/list.svg
new file mode 100644
index 0000000..564897c
--- /dev/null
+++ b/src/assets/images/images/list.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/page-break.svg b/src/assets/images/images/page-break.svg
new file mode 100644
index 0000000..c40ec93
--- /dev/null
+++ b/src/assets/images/images/page-break.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/page-mode.svg b/src/assets/images/images/page-mode.svg
new file mode 100644
index 0000000..516f3a8
--- /dev/null
+++ b/src/assets/images/images/page-mode.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/page-scale-add.svg b/src/assets/images/images/page-scale-add.svg
new file mode 100644
index 0000000..bcfa9a3
--- /dev/null
+++ b/src/assets/images/images/page-scale-add.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/page-scale-minus.svg b/src/assets/images/images/page-scale-minus.svg
new file mode 100644
index 0000000..f85bf77
--- /dev/null
+++ b/src/assets/images/images/page-scale-minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/painter.svg b/src/assets/images/images/painter.svg
new file mode 100644
index 0000000..a865d1d
--- /dev/null
+++ b/src/assets/images/images/painter.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/paper-direction.svg b/src/assets/images/images/paper-direction.svg
new file mode 100644
index 0000000..ee90234
--- /dev/null
+++ b/src/assets/images/images/paper-direction.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/paper-margin.svg b/src/assets/images/images/paper-margin.svg
new file mode 100644
index 0000000..6188f36
--- /dev/null
+++ b/src/assets/images/images/paper-margin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/paper-size.svg b/src/assets/images/images/paper-size.svg
new file mode 100644
index 0000000..205a6aa
--- /dev/null
+++ b/src/assets/images/images/paper-size.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/print.svg b/src/assets/images/images/print.svg
new file mode 100644
index 0000000..5ee44a0
--- /dev/null
+++ b/src/assets/images/images/print.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/redo.svg b/src/assets/images/images/redo.svg
new file mode 100644
index 0000000..fc88331
--- /dev/null
+++ b/src/assets/images/images/redo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/request-fullscreen.svg b/src/assets/images/images/request-fullscreen.svg
new file mode 100644
index 0000000..cf47c4a
--- /dev/null
+++ b/src/assets/images/images/request-fullscreen.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/right.svg b/src/assets/images/images/right.svg
new file mode 100644
index 0000000..eca4643
--- /dev/null
+++ b/src/assets/images/images/right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/row-margin.svg b/src/assets/images/images/row-margin.svg
new file mode 100644
index 0000000..97f2baa
--- /dev/null
+++ b/src/assets/images/images/row-margin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/search.svg b/src/assets/images/images/search.svg
new file mode 100644
index 0000000..9d515dc
--- /dev/null
+++ b/src/assets/images/images/search.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/separator.svg b/src/assets/images/images/separator.svg
new file mode 100644
index 0000000..58225e9
--- /dev/null
+++ b/src/assets/images/images/separator.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/signature-undo.svg b/src/assets/images/images/signature-undo.svg
new file mode 100644
index 0000000..518a37f
--- /dev/null
+++ b/src/assets/images/images/signature-undo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/signature.svg b/src/assets/images/images/signature.svg
new file mode 100644
index 0000000..57a007f
--- /dev/null
+++ b/src/assets/images/images/signature.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/size-add.svg b/src/assets/images/images/size-add.svg
new file mode 100644
index 0000000..aa1073c
--- /dev/null
+++ b/src/assets/images/images/size-add.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/size-minus.svg b/src/assets/images/images/size-minus.svg
new file mode 100644
index 0000000..7bfa958
--- /dev/null
+++ b/src/assets/images/images/size-minus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/strikeout.svg b/src/assets/images/images/strikeout.svg
new file mode 100644
index 0000000..c2c83ca
--- /dev/null
+++ b/src/assets/images/images/strikeout.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/subscript.svg b/src/assets/images/images/subscript.svg
new file mode 100644
index 0000000..9ec06b7
--- /dev/null
+++ b/src/assets/images/images/subscript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/superscript.svg b/src/assets/images/images/superscript.svg
new file mode 100644
index 0000000..053bd3e
--- /dev/null
+++ b/src/assets/images/images/superscript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/table.svg b/src/assets/images/images/table.svg
new file mode 100644
index 0000000..0a349fe
--- /dev/null
+++ b/src/assets/images/images/table.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/title.svg b/src/assets/images/images/title.svg
new file mode 100644
index 0000000..c131320
--- /dev/null
+++ b/src/assets/images/images/title.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/trash.svg b/src/assets/images/images/trash.svg
new file mode 100644
index 0000000..c9852d1
--- /dev/null
+++ b/src/assets/images/images/trash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/underline.svg b/src/assets/images/images/underline.svg
new file mode 100644
index 0000000..dcd81b0
--- /dev/null
+++ b/src/assets/images/images/underline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/undo.svg b/src/assets/images/images/undo.svg
new file mode 100644
index 0000000..820f852
--- /dev/null
+++ b/src/assets/images/images/undo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/watermark.svg b/src/assets/images/images/watermark.svg
new file mode 100644
index 0000000..68de565
--- /dev/null
+++ b/src/assets/images/images/watermark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/images/images/word-tool.svg b/src/assets/images/images/word-tool.svg
new file mode 100644
index 0000000..21fbd33
--- /dev/null
+++ b/src/assets/images/images/word-tool.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
new file mode 100644
index 0000000..7565660
--- /dev/null
+++ b/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/src/assets/main.css b/src/assets/main.css
new file mode 100644
index 0000000..36fb845
--- /dev/null
+++ b/src/assets/main.css
@@ -0,0 +1,35 @@
+@import './base.css';
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ font-weight: normal;
+}
+
+a,
+.green {
+ text-decoration: none;
+ color: hsla(160, 100%, 37%, 1);
+ transition: 0.4s;
+ padding: 3px;
+}
+
+@media (hover: hover) {
+ a:hover {
+ background-color: hsla(160, 100%, 37%, 0.2);
+ }
+}
+
+@media (min-width: 1024px) {
+ body {
+ display: flex;
+ place-items: center;
+ }
+
+ #app {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ padding: 0 2rem;
+ }
+}
diff --git a/src/assets/style.css b/src/assets/style.css
new file mode 100644
index 0000000..896c91f
--- /dev/null
+++ b/src/assets/style.css
@@ -0,0 +1,1078 @@
+::-webkit-scrollbar {
+ height: 16px;
+ width: 16px;
+ overflow: visible;
+}
+
+::-webkit-scrollbar-button {
+ width: 0;
+ height: 0;
+}
+
+::-webkit-scrollbar-corner {
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background-color: #ddd;
+ background-clip: padding-box;
+ border: 4px solid #f2f4f7;
+ border-radius: 8px;
+ min-height: 24px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background-color: #c9c9c9;
+}
+
+::-webkit-scrollbar-track {
+ background: #f2f4f7;
+ background-clip: padding-box;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: #f2f4f7;
+}
+
+#app {
+ position: relative;
+}
+
+ul {
+ list-style: none;
+}
+
+.menu {
+ width: 100%;
+ height: 60px;
+ z-index: 9;
+ position: fixed !important;
+ left: 0;
+ top: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #f2f4f7;
+ box-shadow: 0 2px 4px 0 transparent;
+}
+
+.menu-divider {
+ width: 1px;
+ height: 16px;
+ margin: 0 8px;
+ display: inline-block;
+ background-color: #cfd2d8;
+}
+
+.menu-item {
+ height: 24px;
+ display: flex;
+ align-items: center;
+ position: relative;
+}
+
+.menu-item>div {
+ width: 24px;
+ height: 24px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin: 0 2px;
+}
+
+.menu-item>div:hover {
+ background: rgba(25, 55, 88, 0.04);
+}
+
+.menu-item>div.active {
+ background: rgba(25, 55, 88, 0.08);
+}
+
+.menu-item i {
+ width: 16px;
+ height: 16px;
+ display: inline-block;
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+.menu-item>div>span {
+ width: 16px;
+ height: 3px;
+ display: inline-block;
+ border: 1px solid #e2e6ed;
+}
+
+.menu-item .select {
+ border: none;
+ font-size: 12px;
+ line-height: 24px;
+ user-select: none;
+}
+
+.menu-item .select::after {
+ position: absolute;
+ content: '';
+ top: 11px;
+ width: 0;
+ height: 0;
+ right: 2px;
+ border-color: #767c85 transparent transparent;
+ border-style: solid solid none;
+ border-width: 3px 3px 0;
+}
+
+.menu-item .options {
+ width: 70px;
+ position: absolute;
+ left: 0;
+ top: 25px;
+ padding: 10px;
+ background: #fff;
+ font-size: 14px;
+ box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+ display: none;
+}
+
+.menu-item .options.visible {
+ display: block;
+}
+
+.menu-item .options li {
+ padding: 5px;
+ margin: 5px 0;
+ user-select: none;
+ transition: all 0.3s;
+}
+
+.menu-item .options li:hover {
+ background-color: #ebecef;
+}
+
+.menu-item .options li.active {
+ background-color: #e2e6ed;
+}
+
+.menu-item .menu-item__font {
+ width: 65px;
+ position: relative;
+}
+
+.menu-item .menu-item__size {
+ width: 50px;
+ text-align: center;
+ position: relative;
+}
+
+.menu-item__font .select,
+.menu-item__size .select {
+ width: 100%;
+ height: 100%;
+}
+
+.menu-item__undo.no-allow,
+.menu-item__redo.no-allow,
+.menu-item>div.disable {
+ color: #c0c4cc;
+ cursor: not-allowed;
+ opacity: 0.4;
+ pointer-events: none;
+}
+
+.menu-item__undo i {
+ background-image: url('/src/assets/images/images/undo.svg');
+}
+
+.menu-item__redo i {
+ background-image: url('/src/assets/images/images/redo.svg');
+}
+
+.menu-item__painter i {
+ background-image: url('/src/assets/images/images/painter.svg');
+}
+
+.menu-item__format i {
+ background-image: url('/src/assets/images/images/format.svg');
+}
+
+.menu-item__size-add i {
+ background-image: url('/src/assets/images/images/size-add.svg');
+}
+
+.menu-item__size-minus i {
+ background-image: url('/src/assets/images/images/size-minus.svg');
+}
+
+.menu-item__bold i {
+ background-image: url('/src/assets/images/images/bold.svg');
+}
+
+.menu-item__italic i {
+ background-image: url('/src/assets/images/images/italic.svg');
+}
+
+.menu-item .menu-item__underline {
+ width: 30px;
+ position: relative;
+}
+
+.menu-item__underline>i {
+ flex-shrink: 0;
+ background-image: url('/src/assets/images/images/underline.svg');
+}
+
+.menu-item__underline .select {
+ width: 100%;
+ height: 100%;
+}
+
+.menu-item .menu-item__underline .options {
+ width: 128px;
+}
+
+.menu-item .menu-item__underline li {
+ padding: 1px 5px;
+}
+
+.menu-item__underline li i {
+ pointer-events: none;
+}
+
+.menu-item__underline li[data-decoration-style='solid'] {
+ background-image: url('/src/assets/images/images/line-single.svg');
+}
+
+.menu-item__underline li[data-decoration-style='double'] {
+ background-image: url('/src/assets/images/images/line-double.svg');
+}
+
+.menu-item__underline li[data-decoration-style='dashed'] {
+ background-image: url('/src/assets/images/images/line-dash-small-gap.svg');
+}
+
+.menu-item__underline li[data-decoration-style='dotted'] {
+ background-image: url('/src/assets/images/images/line-dot.svg');
+}
+
+.menu-item__underline li[data-decoration-style='wavy'] {
+ background-image: url('/src/assets/images/images/line-wavy.svg');
+}
+
+.menu-item__strikeout i {
+ background-image: url('/src/assets/images/images/strikeout.svg');
+}
+
+.menu-item__superscript i {
+ background-image: url('/src/assets/images/images/superscript.svg');
+}
+
+.menu-item__subscript i {
+ background-image: url('/src/assets/images/images/subscript.svg');
+}
+
+.menu-item__color,
+.menu-item__highlight {
+ display: flex;
+ flex-direction: column;
+}
+
+.menu-item__color #color,
+.menu-item__highlight #highlight {
+ width: 1px;
+ height: 1px;
+ visibility: hidden;
+ outline: none;
+ appearance: none;
+}
+
+.menu-item__color i {
+ background-image: url('/src/assets/images/images/color.svg');
+}
+
+.menu-item__color span {
+ background-color: #000000;
+}
+
+.menu-item__highlight i {
+ background-image: url('/src/assets/images/images/highlight.svg');
+}
+
+.menu-item__highlight span {
+ background-color: #ffff00;
+}
+
+.menu-item .menu-item__title {
+ width: 60px;
+ position: relative;
+}
+
+.menu-item__title .select {
+ width: calc(100% - 20px);
+ height: 100%;
+}
+
+.menu-item__title i {
+ transform: translateX(-5px);
+ background-image: url('/src/assets/images/images/title.svg');
+}
+
+.menu-item__title .options {
+ width: 80px;
+}
+
+.menu-item__left i {
+ background-image: url('/src/assets/images/images/left.svg');
+}
+
+.menu-item__center i {
+ background-image: url('/src/assets/images/images/center.svg');
+}
+
+.menu-item__right i {
+ background-image: url('/src/assets/images/images/right.svg');
+}
+
+.menu-item__alignment i {
+ background-image: url('/src/assets/images/images/alignment.svg');
+}
+
+.menu-item__justify i {
+ background-image: url('/src/assets/images/images/list11.svg');
+}
+
+.menu-item__row-margin {
+ position: relative;
+}
+
+.menu-item__row-margin i {
+ background-image: url('/src/assets/images/images/row-margin.svg');
+}
+
+.menu-item__list {
+ position: relative;
+}
+
+.menu-item__list i {
+ background-image: url('/src/assets/images/images/list.svg');
+}
+
+.menu-item__list .options {
+ width: 110px;
+}
+
+.menu-item__list .options>ul>li * {
+ pointer-events: none;
+}
+
+.menu-item__list .options>ul>li li {
+ margin-left: 18px;
+}
+
+.menu-item__list .options>ul>li[data-list-style='checkbox'] li::marker {
+ font-size: 11px;
+}
+
+.menu-item__image i {
+ background-image: url('/src/assets/images/images/image.svg');
+}
+
+.menu-item__image input {
+ display: none;
+}
+
+.menu-item__table {
+ position: relative;
+}
+
+.menu-item__table i {
+ background-image: url('/src/assets/images/images/table.svg');
+}
+
+.menu-item .menu-item__table__collapse {
+ width: 270px;
+ height: 310px;
+ background: #fff;
+ box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
+ border: 1px solid #e2e6ed;
+ box-sizing: border-box;
+ border-radius: 2px;
+ position: absolute;
+ display: none;
+ z-index: 99;
+ top: 25px;
+ left: 0;
+ padding: 14px 27px;
+ cursor: auto;
+}
+
+.menu-item .menu-item__table__collapse .table-close {
+ position: absolute;
+ right: 10px;
+ top: 5px;
+ cursor: pointer;
+}
+
+.menu-item .menu-item__table__collapse .table-close:hover {
+ color: #7d7e80;
+}
+
+.menu-item .menu-item__table__collapse:hover {
+ background: #fff;
+}
+
+.menu-item .menu-item__table__collapse .table-title {
+ display: flex;
+ justify-content: flex-start;
+ padding-bottom: 5px;
+ border-bottom: 1px solid #e2e6ed;
+}
+
+.table-title span {
+ font-size: 12px;
+ color: #3d4757;
+ display: inline;
+ margin: 0;
+}
+
+.table-panel {
+ cursor: pointer;
+}
+
+.table-panel .table-row {
+ display: flex;
+ flex-wrap: nowrap;
+ margin-top: 10px;
+ pointer-events: none;
+}
+
+.table-panel .table-cel {
+ width: 16px !important;
+ height: 16px;
+ box-sizing: border-box;
+ border: 1px solid #e2e6ed;
+ background: #fff;
+ position: relative;
+ margin-right: 6px;
+ pointer-events: none;
+}
+
+.table-panel .table-cel.active {
+ border: 1px solid rgba(73, 145, 242, 0.2);
+ background: rgba(73, 145, 242, 0.15);
+}
+
+.table-panel .table-row .table-cel:last-child {
+ margin-right: 0;
+}
+
+.menu-item__hyperlink i {
+ background-image: url('/src/assets/images/images/hyperlink.svg');
+}
+
+.menu-item__separator {
+ position: relative;
+}
+
+.menu-item__separator>i {
+ background-image: url('/src/assets/images/images/separator.svg');
+}
+
+.menu-item .menu-item__separator .options {
+ width: 128px;
+}
+
+.menu-item .menu-item__separator li {
+ padding: 1px 5px;
+}
+
+.menu-item__separator li i {
+ pointer-events: none;
+}
+
+.menu-item__separator li[data-separator='0,0'] {
+ background-image: url('/src/assets/images/images/line-single.svg');
+}
+
+.menu-item__separator li[data-separator='1,1'] {
+ background-image: url('/src/assets/images/images/line-dot.svg');
+}
+
+.menu-item__separator li[data-separator='3,1'] {
+ background-image: url('/src/assets/images/images/line-dash-small-gap.svg');
+}
+
+.menu-item__separator li[data-separator='4,4'] {
+ background-image: url('/src/assets/images/images/line-dash-large-gap.svg');
+}
+
+.menu-item__separator li[data-separator='7,3,3,3'] {
+ background-image: url('/src/assets/images/images/line-dash-dot.svg');
+}
+
+.menu-item__separator li[data-separator='6,2,2,2,2,2'] {
+ background-image: url('/src/assets/images/images/line-dash-dot-dot.svg');
+}
+
+.menu-item__watermark>i {
+ background-image: url('/src/assets/images/images/watermark.svg');
+}
+
+.menu-item__watermark {
+ position: relative;
+}
+
+.menu-item__codeblock i {
+ background-image: url('/src/assets/images/images/codeblock.svg');
+}
+
+.menu-item__page-break i {
+ background-image: url('/src/assets/images/images/page-break.svg');
+}
+
+.menu-item__control {
+ position: relative;
+}
+
+.menu-item__control i {
+ background-image: url('/src/assets/images/images/control.svg');
+}
+
+.menu-item__checkbox i {
+ background-image: url('/src/assets/images/images/checkbox.svg');
+}
+
+.menu-item__radio i {
+ background-image: url('/src/assets/images/images/radio.svg');
+}
+
+.menu-item__latex i {
+ background-image: url('/src/assets/images/images/latex.svg');
+}
+
+.menu-item__date {
+ position: relative;
+}
+
+.menu-item__date i {
+ background-image: url('/src/assets/images/images/date.svg');
+}
+
+.menu-item__date .options {
+ width: 160px;
+}
+
+.menu-item__block i {
+ background-image: url('/src/assets/images/images/block.svg');
+}
+
+.menu-item .menu-item__control .options {
+ width: 55px;
+}
+
+.menu-item__search {
+ position: relative;
+}
+
+.menu-item__search i {
+ background-image: url('/src/assets/images/images/search.svg');
+}
+
+.menu-item .menu-item__search__collapse {
+ width: 260px;
+ height: 72px;
+ box-sizing: border-box;
+ position: absolute;
+ display: none;
+ z-index: 99;
+ top: 25px;
+ left: 0;
+ background: #ffffff;
+ box-shadow: 0px 5px 5px #e3dfdf;
+}
+
+.menu-item .menu-item__search__collapse:hover {
+ background: #ffffff;
+}
+
+.menu-item .menu-item__search__collapse>div {
+ width: 250px;
+ height: 36px;
+ padding: 0 5px;
+ line-height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ border-radius: 4px;
+}
+
+.menu-item .menu-item__search__collapse>div input {
+ width: 205px;
+ height: 27px;
+ appearance: none;
+ background-color: #fff;
+ background-image: none;
+ border-radius: 4px;
+ border: 1px solid #ebebeb;
+ box-sizing: border-box;
+ color: #606266;
+ display: inline-block;
+ line-height: 27px;
+ outline: none;
+ padding: 0 5px;
+}
+
+.menu-item .menu-item__search__collapse>div span {
+ height: 100%;
+ color: #dcdfe6;
+ font-size: 25px;
+ display: inline-block;
+ border: 0;
+ padding: 0 10px;
+}
+
+.menu-item .menu-item__search__collapse__replace button {
+ display: inline-block;
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+ background: #fff;
+ line-height: 22px;
+ padding: 0 6px;
+ white-space: nowrap;
+ margin-left: 4px;
+ cursor: pointer;
+ font-size: 12px;
+}
+
+.menu-item .menu-item__search__collapse__replace button:hover {
+ background: rgba(25, 55, 88, 0.04);
+}
+
+.menu-item .menu-item__search__collapse__search {
+ position: relative;
+}
+
+.menu-item .menu-item__search__collapse__search label {
+ right: 110px;
+ font-size: 12px;
+ color: #3d4757;
+ position: absolute;
+}
+
+.menu-item .menu-item__search__collapse__search>input {
+ padding: 5px 90px 5px 5px !important;
+}
+
+.menu-item .menu-item__search__collapse__search>div {
+ width: 28px;
+ height: 27px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ border-left: 1px solid #e2e6ed;
+ transition: all 0.5s;
+}
+
+.menu-item .menu-item__search__collapse__search>div:hover {
+ background-color: rgba(25, 55, 88, 0.04);
+}
+
+.menu-item .menu-item__search__collapse__search i {
+ width: 6px;
+ height: 8px;
+ transform: translateY(1px);
+}
+
+.menu-item .menu-item__search__collapse__search .arrow-left {
+ right: 76px;
+}
+
+.menu-item .menu-item__search__collapse__search .arrow-left i {
+ background: url(/src/assets/images/images/arrow-left.svg) no-repeat;
+}
+
+.menu-item .menu-item__search__collapse__search .arrow-right {
+ right: 48px;
+}
+
+.menu-item .menu-item__search__collapse__search .arrow-right i {
+ background: url(/src/assets/images/images/arrow-right.svg) no-repeat;
+}
+
+.menu-item__print i {
+ background-image: url('/src/assets/images/images/print.svg');
+}
+
+.catalog {
+ width: 250px;
+ position: fixed;
+ left: 0;
+ bottom: 0;
+ top: 100px;
+ padding: 0 20px 40px 20px;
+}
+
+.catalog .catalog__header {
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ border-bottom: 1px solid #e2e6ed;
+}
+
+.catalog .catalog__header span {
+ color: #3d4757;
+ font-size: 14px;
+ font-weight: bold;
+}
+
+.catalog .catalog__header i {
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ display: inline-block;
+ background: url(/src/assets/images/images/close.svg) no-repeat;
+ transition: all 0.2s;
+}
+
+.catalog .catalog__header>div:hover {
+ background: rgba(235, 238, 241);
+}
+
+.catalog__main {
+ height: calc(100% - 60px);
+ padding: 10px 0;
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+.catalog__main .catalog-item {
+ width: 100%;
+ padding-left: 10px;
+ box-sizing: border-box;
+}
+
+.catalog__main>.catalog-item {
+ padding-left: 0;
+}
+
+.catalog__main .catalog-item .catalog-item__content {
+ width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.catalog__main .catalog-item .catalog-item__content:hover>span {
+ color: #4991f2;
+}
+
+.catalog__main .catalog-item .catalog-item__content span {
+ color: #3d4757;
+ line-height: 30px;
+ font-size: 12px;
+ white-space: nowrap;
+ cursor: pointer;
+ user-select: none;
+}
+
+.editor>div {
+ margin: 80px auto;
+}
+
+.ce-page-container canvas {
+ box-shadow: rgb(158 161 165 / 40%) 0px 2px 12px 0px;
+}
+
+.comment {
+ width: 250px;
+ height: 650px;
+ position: fixed;
+ transform: translateX(420px);
+ top: 200px;
+ left: 50%;
+ overflow-y: auto;
+}
+
+.comment-item {
+ background: #ffffff;
+ border: 1px solid #e2e6ed;
+ position: relative;
+ border-radius: 8px;
+ padding: 15px;
+ font-size: 14px;
+ margin-bottom: 20px;
+ cursor: pointer;
+ transition: all 0.5s;
+}
+
+.comment-item:hover {
+ border-color: #c0c6cf;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.comment-item.active {
+ border-color: #e99d00;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.comment-item__title {
+ height: 22px;
+ position: relative;
+ display: flex;
+ align-items: center;
+ color: #c1c6ce;
+}
+
+.comment-item__title span:first-child {
+ background-color: #dbdbdb;
+ width: 4px;
+ height: 16px;
+ margin-right: 5px;
+ display: inline-block;
+ border-radius: 999px;
+}
+
+.comment-item__title span:nth-child(2) {
+ width: 200px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.comment-item__title i {
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ position: absolute;
+ right: -8px;
+ top: -8px;
+ background: url(/src/assets/images/images/close.svg) no-repeat;
+}
+
+.comment-item__title i:hover {
+ opacity: 0.6;
+}
+
+.comment-item__info {
+ height: 28px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.comment-item__info>span:first-child {
+ font-weight: 600;
+}
+
+.comment-item__info>span:last-child {
+ color: #c1c6ce;
+}
+
+.comment-item__content {
+ line-height: 22px;
+}
+
+.footer {
+ width: 100%;
+ height: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: #f2f4f7;
+ z-index: 9;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ font-size: 12px;
+ padding: 0 4px 0 20px;
+ box-sizing: border-box;
+}
+
+.footer>div:first-child {
+ display: flex;
+ align-items: center;
+}
+
+.footer .catalog-mode {
+ padding: 1px;
+ position: relative;
+}
+
+.footer .catalog-mode i {
+ width: 16px;
+ height: 16px;
+ margin-right: 5px;
+ cursor: pointer;
+ display: inline-block;
+ background-image: url('/src/assets/images/images/catalog.svg');
+}
+
+.footer .page-mode {
+ padding: 1px;
+ position: relative;
+}
+
+.footer .page-mode i {
+ width: 16px;
+ height: 16px;
+ margin-right: 5px;
+ cursor: pointer;
+ display: inline-block;
+ background-image: url('/src/assets/images/images/page-mode.svg');
+}
+
+.footer .options {
+ width: 70px;
+ position: absolute;
+ left: 0;
+ bottom: 25px;
+ padding: 10px;
+ background: #fff;
+ font-size: 14px;
+ box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+ display: none;
+}
+
+.footer .options.visible {
+ display: block;
+}
+
+.footer .options li {
+ padding: 5px;
+ margin: 5px 0;
+ user-select: none;
+ transition: all 0.3s;
+ text-align: center;
+ cursor: pointer;
+}
+
+.footer .options li:hover {
+ background-color: #ebecef;
+}
+
+.footer .options li.active {
+ background-color: #e2e6ed;
+}
+
+.footer>div:first-child>span {
+ display: inline-block;
+ margin-right: 5px;
+ letter-spacing: 1px;
+}
+
+.footer>div:last-child {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.footer>div:last-child>div {
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.footer>div:last-child>div:hover {
+ background: rgba(25, 55, 88, 0.04);
+}
+
+.footer>div:last-child i {
+ width: 16px;
+ height: 16px;
+ display: inline-block;
+ cursor: pointer;
+}
+
+.footer .editor-option i {
+ background-image: url('/src/assets/images/images/option.svg');
+}
+
+.footer .page-scale-minus i {
+ background-image: url('/src/assets/images/images/page-scale-minus.svg');
+}
+
+.footer .page-scale-add i {
+ background-image: url('/src/assets/images/images/page-scale-add.svg');
+}
+
+.footer .page-scale-percentage {
+ cursor: pointer;
+ user-select: none;
+}
+
+.footer .fullscreen i {
+ background-image: url('/src/assets/images/images/request-fullscreen.svg');
+}
+
+.footer .fullscreen.exist i {
+ background-image: url('/src/assets/images/images/exit-fullscreen.svg');
+}
+
+.footer .paper-margin i {
+ background-image: url('/src/assets/images/images/paper-margin.svg');
+}
+
+.footer .editor-mode {
+ cursor: pointer;
+ user-select: none;
+}
+
+.footer .paper-size {
+ position: relative;
+}
+
+.footer .paper-size i {
+ background-image: url('/src/assets/images/images/paper-size.svg');
+}
+
+.footer .paper-size .options {
+ right: 0;
+ left: unset;
+}
+
+.footer .paper-direction {
+ position: relative;
+}
+
+.footer .paper-direction i {
+ background-image: url('/src/assets/images/images/paper-direction.svg');
+}
+
+.footer .paper-direction .options {
+ right: 0;
+ left: unset;
+}
+
+.ce-contextmenu-signature {
+ background-image: url('/src/assets/images/images/signature.svg');
+}
+
+.ce-contextmenu-word-tool {
+ background-image: url('/src/assets/images/images/word-tool.svg');
+}
+
+.main_right {
+ margin-top: 100px;
+ position: absolute;
+ right: 10px;
+ top: 0;
+}
+
+.main_left {
+ position: absolute;
+ right: 300px;
+ top: 155px;
+}
\ No newline at end of file
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
new file mode 100644
index 0000000..ee135b0
--- /dev/null
+++ b/src/components/HelloWorld.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TheWelcome.vue b/src/components/TheWelcome.vue
new file mode 100644
index 0000000..9342be7
--- /dev/null
+++ b/src/components/TheWelcome.vue
@@ -0,0 +1,12 @@
+
+
+
+ aaa
+
diff --git a/src/components/WelcomeItem.vue b/src/components/WelcomeItem.vue
new file mode 100644
index 0000000..6d7086a
--- /dev/null
+++ b/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
diff --git a/src/components/dialog/Dialog.ts b/src/components/dialog/Dialog.ts
new file mode 100644
index 0000000..f10ad91
--- /dev/null
+++ b/src/components/dialog/Dialog.ts
@@ -0,0 +1,171 @@
+import { EditorComponent, EDITOR_COMPONENT } from '@hufe921/canvas-editor'
+import './dialog.css'
+
+export interface IDialogData {
+ type: string
+ label?: string
+ name: string
+ value?: string
+ options?: { label: string; value: string }[]
+ placeholder?: string
+ width?: number
+ height?: number
+ required?: boolean
+}
+
+export interface IDialogConfirm {
+ name: string
+ value: string
+}
+
+export interface IDialogOptions {
+ onClose?: () => void
+ onCancel?: () => void
+ onConfirm?: (payload: IDialogConfirm[]) => void
+ title: string
+ data: IDialogData[]
+}
+
+export class Dialog {
+ private options: IDialogOptions
+ private mask: HTMLDivElement | null
+ private container: HTMLDivElement | null
+ private inputList: (
+ | HTMLInputElement
+ | HTMLTextAreaElement
+ | HTMLSelectElement
+ )[]
+
+ constructor(options: IDialogOptions) {
+ this.options = options
+ this.mask = null
+ this.container = null
+ this.inputList = []
+ this._render()
+ }
+
+ private _render() {
+ const { title, data, onClose, onCancel, onConfirm } = this.options
+ // 渲染遮罩层
+ const mask = document.createElement('div')
+ mask.classList.add('dialog-mask')
+ mask.setAttribute(EDITOR_COMPONENT, EditorComponent.COMPONENT)
+ document.body.append(mask)
+ // 渲染容器
+ const container = document.createElement('div')
+ container.classList.add('dialog-container')
+ container.setAttribute(EDITOR_COMPONENT, EditorComponent.COMPONENT)
+ // 弹窗
+ const dialogContainer = document.createElement('div')
+ dialogContainer.classList.add('dialog')
+ container.append(dialogContainer)
+ // 标题容器
+ const titleContainer = document.createElement('div')
+ titleContainer.classList.add('dialog-title')
+ // 标题&关闭按钮
+ const titleSpan = document.createElement('span')
+ titleSpan.append(document.createTextNode(title))
+ const titleClose = document.createElement('i')
+ titleClose.onclick = () => {
+ if (onClose) {
+ onClose()
+ }
+ this._dispose()
+ }
+ titleContainer.append(titleSpan)
+ titleContainer.append(titleClose)
+ dialogContainer.append(titleContainer)
+ // 选项容器
+ const optionContainer = document.createElement('div')
+ optionContainer.classList.add('dialog-option')
+ // 选项
+ for (let i = 0; i < data.length; i++) {
+ const option = data[i]
+ const optionItemContainer = document.createElement('div')
+ optionItemContainer.classList.add('dialog-option__item')
+ // 选项名称
+ if (option.label) {
+ const optionName = document.createElement('span')
+ optionName.append(document.createTextNode(option.label))
+ optionItemContainer.append(optionName)
+ if (option.required) {
+ optionName.classList.add('dialog-option__item--require')
+ }
+ }
+ // 选项输入框
+ let optionInput:
+ | HTMLInputElement
+ | HTMLTextAreaElement
+ | HTMLSelectElement
+ if (option.type === 'select') {
+ optionInput = document.createElement('select')
+ option.options?.forEach(item => {
+ const optionItem = document.createElement('option')
+ optionItem.value = item.value
+ optionItem.label = item.label
+ optionInput.append(optionItem)
+ })
+ } else if (option.type === 'textarea') {
+ optionInput = document.createElement('textarea')
+ } else {
+ optionInput = document.createElement('input')
+ optionInput.type = option.type
+ }
+ if (option.width) {
+ optionInput.style.width = `${option.width}px`
+ }
+ if (option.height) {
+ optionInput.style.height = `${option.height}px`
+ }
+ optionInput.name = option.name
+ optionInput.value = option.value || ''
+ if (!(optionInput instanceof HTMLSelectElement)) {
+ optionInput.placeholder = option.placeholder || ''
+ }
+ optionItemContainer.append(optionInput)
+ optionContainer.append(optionItemContainer)
+ this.inputList.push(optionInput)
+ }
+ dialogContainer.append(optionContainer)
+ // 按钮容器
+ const menuContainer = document.createElement('div')
+ menuContainer.classList.add('dialog-menu')
+ // 取消按钮
+ const cancelBtn = document.createElement('button')
+ cancelBtn.classList.add('dialog-menu__cancel')
+ cancelBtn.append(document.createTextNode('取消'))
+ cancelBtn.type = 'button'
+ cancelBtn.onclick = () => {
+ if (onCancel) {
+ onCancel()
+ }
+ this._dispose()
+ }
+ menuContainer.append(cancelBtn)
+ // 确认按钮
+ const confirmBtn = document.createElement('button')
+ confirmBtn.append(document.createTextNode('确定'))
+ confirmBtn.type = 'submit'
+ confirmBtn.onclick = () => {
+ if (onConfirm) {
+ const payload = this.inputList.map(input => ({
+ name: input.name,
+ value: input.value
+ }))
+ onConfirm(payload)
+ }
+ this._dispose()
+ }
+ menuContainer.append(confirmBtn)
+ dialogContainer.append(menuContainer)
+ // 渲染
+ document.body.append(container)
+ this.container = container
+ this.mask = mask
+ }
+
+ private _dispose() {
+ this.mask?.remove()
+ this.container?.remove()
+ }
+}
diff --git a/src/components/dialog/dialog.css b/src/components/dialog/dialog.css
new file mode 100644
index 0000000..8a58245
--- /dev/null
+++ b/src/components/dialog/dialog.css
@@ -0,0 +1,131 @@
+.dialog-mask {
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ opacity: .5;
+ background: #000000;
+ z-index: 99;
+}
+
+.dialog-container {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ overflow: auto;
+ z-index: 999;
+ margin: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.dialog {
+ position: absolute;
+ padding: 0 30px 30px;
+ background: #ffffff;
+ box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+}
+
+.dialog-title {
+ position: relative;
+ border-bottom: 1px solid #e2e6ed;
+ margin-bottom: 30px;
+ height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.dialog-title i {
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ display: inline-block;
+ background: url(../../assets/images/close.svg);
+}
+
+.dialog-option__item {
+ margin-bottom: 18px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.dialog-option__item span {
+ margin-right: 12px;
+ font-size: 14px;
+ color: #3d4757;
+ position: relative;
+}
+
+.dialog-option__item input,
+.dialog-option__item textarea,
+.dialog-option__item select {
+ width: 276px;
+ height: 30px;
+ border-radius: 2px;
+ border: 1px solid #d3d3d3;
+ min-height: 30px;
+ padding: 5px;
+ box-sizing: border-box;
+ outline: none;
+ appearance: none;
+ user-select: none;
+ font-family: inherit;
+}
+
+.dialog-option__item input:focus,
+.dialog-option__item textarea:focus {
+ border-color: #4991f2;
+}
+
+.dialog-option__item--require::before {
+ content: "*";
+ color: #f56c6c;
+ margin-right: 4px;
+ position: absolute;
+ left: -8px;
+}
+
+.dialog-menu {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+}
+
+.dialog-menu button {
+ position: relative;
+ display: inline-block;
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+ background: #ffffff;
+ line-height: 22px;
+ padding: 0 16px;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.dialog-menu button:hover {
+ background: rgba(25, 55, 88, .04);
+}
+
+.dialog-menu__cancel {
+ margin-right: 16px;
+}
+
+.dialog-menu button[type='submit'] {
+ color: #ffffff;
+ background: #4991f2;
+ border-color: #4991f2;
+}
+
+.dialog-menu button[type='submit']:hover {
+ background: #5b9cf3;
+ border-color: #5b9cf3;
+}
\ No newline at end of file
diff --git a/src/components/icons/IconCommunity.vue b/src/components/icons/IconCommunity.vue
new file mode 100644
index 0000000..2dc8b05
--- /dev/null
+++ b/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/components/icons/IconDocumentation.vue b/src/components/icons/IconDocumentation.vue
new file mode 100644
index 0000000..6d4791c
--- /dev/null
+++ b/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/components/icons/IconEcosystem.vue b/src/components/icons/IconEcosystem.vue
new file mode 100644
index 0000000..c3a4f07
--- /dev/null
+++ b/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/components/icons/IconSupport.vue b/src/components/icons/IconSupport.vue
new file mode 100644
index 0000000..7452834
--- /dev/null
+++ b/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/components/icons/IconTooling.vue b/src/components/icons/IconTooling.vue
new file mode 100644
index 0000000..660598d
--- /dev/null
+++ b/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/src/components/signature/Signature.ts b/src/components/signature/Signature.ts
new file mode 100644
index 0000000..e0927a7
--- /dev/null
+++ b/src/components/signature/Signature.ts
@@ -0,0 +1,309 @@
+import { EditorComponent, EDITOR_COMPONENT } from '@hufe921/canvas-editor'
+import './signature.css'
+
+export interface ISignatureResult {
+ value: string
+ width: number
+ height: number
+}
+
+export interface ISignatureOptions {
+ width?: number
+ height?: number
+ onClose?: () => void
+ onCancel?: () => void
+ onConfirm?: (payload: ISignatureResult | null) => void
+}
+
+export class Signature {
+ private readonly MAX_RECORD_COUNT = 1000
+ private readonly DEFAULT_WIDTH = 390
+ private readonly DEFAULT_HEIGHT = 180
+ private undoStack: Array = []
+ private x = 0
+ private y = 0
+ private isDrawing = false
+ private isDrawn = false
+ private linePoints: [number, number][] = []
+ private canvasWidth: number
+ private canvasHeight: number
+ private options: ISignatureOptions
+ private mask: HTMLDivElement
+ private container: HTMLDivElement
+ private trashContainer: HTMLDivElement
+ private undoContainer: HTMLDivElement
+ private canvas: HTMLCanvasElement
+ private ctx: CanvasRenderingContext2D
+ private preTimeStamp: number
+ private dpr: number
+
+ constructor(options: ISignatureOptions) {
+ this.options = options
+ this.preTimeStamp = 0
+ this.dpr = window.devicePixelRatio
+ this.canvasWidth = (options.width || this.DEFAULT_WIDTH) * this.dpr
+ this.canvasHeight = (options.height || this.DEFAULT_HEIGHT) * this.dpr
+ const { mask, container, trashContainer, undoContainer, canvas } =
+ this._render()
+ this.mask = mask
+ this.container = container
+ this.trashContainer = trashContainer
+ this.undoContainer = undoContainer
+ this.canvas = canvas
+ this.ctx = canvas.getContext('2d')
+ this.ctx.scale(this.dpr, this.dpr)
+ this.ctx.lineCap = 'round'
+ this._bindEvent()
+ this._clearUndoFn()
+ }
+
+ private _render() {
+ const { onClose, onCancel, onConfirm } = this.options
+ // 渲染遮罩层
+ const mask = document.createElement('div')
+ mask.classList.add('signature-mask')
+ mask.setAttribute(EDITOR_COMPONENT, EditorComponent.COMPONENT)
+ document.body.append(mask)
+ // 渲染容器
+ const container = document.createElement('div')
+ container.classList.add('signature-container')
+ container.setAttribute(EDITOR_COMPONENT, EditorComponent.COMPONENT)
+ // 弹窗
+ const signatureContainer = document.createElement('div')
+ signatureContainer.classList.add('signature')
+ container.append(signatureContainer)
+ // 标题容器
+ const titleContainer = document.createElement('div')
+ titleContainer.classList.add('signature-title')
+ // 标题&关闭按钮
+ const titleSpan = document.createElement('span')
+ titleSpan.append(document.createTextNode('插入签名'))
+ const titleClose = document.createElement('i')
+ titleClose.onclick = () => {
+ if (onClose) {
+ onClose()
+ }
+ this._dispose()
+ }
+ titleContainer.append(titleSpan)
+ titleContainer.append(titleClose)
+ signatureContainer.append(titleContainer)
+ // 操作区
+ const operationContainer = document.createElement('div')
+ operationContainer.classList.add('signature-operation')
+ // 撤销
+ const undoContainer = document.createElement('div')
+ undoContainer.classList.add('signature-operation__undo')
+ const undoIcon = document.createElement('i')
+ const undoLabel = document.createElement('span')
+ undoLabel.innerText = '撤销'
+ undoContainer.append(undoIcon)
+ undoContainer.append(undoLabel)
+ operationContainer.append(undoContainer)
+ // 清空画布
+ const trashContainer = document.createElement('div')
+ trashContainer.classList.add('signature-operation__trash')
+ const trashIcon = document.createElement('i')
+ const trashLabel = document.createElement('span')
+ trashLabel.innerText = '清空'
+ trashContainer.append(trashIcon)
+ trashContainer.append(trashLabel)
+ operationContainer.append(trashContainer)
+ signatureContainer.append(operationContainer)
+ // 绘图区
+ const canvasContainer = document.createElement('div')
+ canvasContainer.classList.add('signature-canvas')
+ const canvas = document.createElement('canvas')
+ canvas.width = this.canvasWidth
+ canvas.height = this.canvasHeight
+ canvas.style.width = `${this.canvasWidth / this.dpr}px`
+ canvas.style.height = `${this.canvasHeight / this.dpr}px`
+ canvasContainer.append(canvas)
+ signatureContainer.append(canvasContainer)
+ // 按钮容器
+ const menuContainer = document.createElement('div')
+ menuContainer.classList.add('signature-menu')
+ // 取消按钮
+ const cancelBtn = document.createElement('button')
+ cancelBtn.classList.add('signature-menu__cancel')
+ cancelBtn.append(document.createTextNode('取消'))
+ cancelBtn.type = 'button'
+ cancelBtn.onclick = () => {
+ if (onCancel) {
+ onCancel()
+ }
+ this._dispose()
+ }
+ menuContainer.append(cancelBtn)
+ // 确认按钮
+ const confirmBtn = document.createElement('button')
+ confirmBtn.append(document.createTextNode('确定'))
+ confirmBtn.type = 'submit'
+ confirmBtn.onclick = () => {
+ if (onConfirm) {
+ onConfirm(this._toData())
+ }
+ this._dispose()
+ }
+ menuContainer.append(confirmBtn)
+ signatureContainer.append(menuContainer)
+ // 渲染
+ document.body.append(container)
+ this.container = container
+ this.mask = mask
+ return {
+ mask,
+ canvas,
+ container,
+ trashContainer,
+ undoContainer
+ }
+ }
+
+ private _bindEvent() {
+ this.trashContainer.onclick = this._clearCanvas.bind(this)
+ this.undoContainer.onclick = this._undo.bind(this)
+ this.canvas.onmousedown = this._startDraw.bind(this)
+ this.canvas.onmousemove = this._draw.bind(this)
+ this.container.onmouseup = this._stopDraw.bind(this)
+ }
+
+ private _undo() {
+ if (this.undoStack.length > 1) {
+ this.undoStack.pop()
+ if (this.undoStack.length) {
+ this.undoStack[this.undoStack.length - 1]()
+ }
+ }
+ }
+
+ private _saveUndoFn(fn: Function) {
+ this.undoStack.push(fn)
+ while (this.undoStack.length > this.MAX_RECORD_COUNT) {
+ this.undoStack.shift()
+ }
+ }
+
+ private _clearUndoFn() {
+ const clearFn = () => {
+ this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
+ }
+ this.undoStack = [clearFn]
+ }
+
+ private _clearCanvas() {
+ this._clearUndoFn()
+ this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
+ }
+
+ private _startDraw(evt: MouseEvent) {
+ this.isDrawing = true
+ this.x = evt.offsetX
+ this.y = evt.offsetY
+ this.ctx.lineWidth = 1
+ }
+
+ private _draw(evt: MouseEvent) {
+ if (!this.isDrawing) return
+ // 计算鼠标移动速度
+ const curTimestamp = performance.now()
+ const distance = Math.sqrt(evt.movementX ** 2 + evt.movementY ** 2)
+ const speed = distance / (curTimestamp - this.preTimeStamp)
+ // 目标线宽:最小速度1,最大速度5,系数3
+ const SPEED_FACTOR = 3
+ const targetLineWidth = Math.min(5, Math.max(1, 5 - speed * SPEED_FACTOR))
+ // 平滑过渡算法(20%的变化比例)调整线条粗细:系数0.2
+ const SMOOTH_FACTOR = 0.2
+ this.ctx.lineWidth =
+ this.ctx.lineWidth * (1 - SMOOTH_FACTOR) + targetLineWidth * SMOOTH_FACTOR
+ // 绘制
+ const { offsetX, offsetY } = evt
+ this.ctx.beginPath()
+ this.ctx.moveTo(this.x, this.y)
+ this.ctx.lineTo(offsetX, offsetY)
+ this.ctx.stroke()
+ this.x = offsetX
+ this.y = offsetY
+ this.linePoints.push([offsetX, offsetY])
+ this.isDrawn = true
+ // 缓存之前时间戳
+ this.preTimeStamp = curTimestamp
+ }
+
+ private _stopDraw() {
+ this.isDrawing = false
+ if (this.isDrawn) {
+ const imageData = this.ctx.getImageData(
+ 0,
+ 0,
+ this.canvasWidth,
+ this.canvasHeight
+ )
+ const self = this
+ this._saveUndoFn(function () {
+ self.ctx.clearRect(0, 0, self.canvasWidth, self.canvasHeight)
+ self.ctx.putImageData(imageData, 0, 0)
+ })
+ this.isDrawn = false
+ }
+ }
+
+ private _toData(): ISignatureResult | null {
+ if (!this.linePoints.length) return null
+ // 查找矩形四角坐标
+ const startX = this.linePoints[0][0]
+ const startY = this.linePoints[0][1]
+ let minX = startX
+ let minY = startY
+ let maxX = startX
+ let maxY = startY
+ for (let p = 0; p < this.linePoints.length; p++) {
+ const point = this.linePoints[p]
+ if (minX > point[0]) {
+ minX = point[0]
+ }
+ if (maxX < point[0]) {
+ maxX = point[0]
+ }
+ if (minY > point[1]) {
+ minY = point[1]
+ }
+ if (maxY < point[1]) {
+ maxY = point[1]
+ }
+ }
+ // 增加边框宽度
+ const lineWidth = this.ctx.lineWidth
+ minX = minX < lineWidth ? 0 : minX - lineWidth
+ minY = minY < lineWidth ? 0 : minY - lineWidth
+ maxX = maxX + lineWidth
+ maxY = maxY + lineWidth
+ const sw = maxX - minX
+ const sh = maxY - minY
+ // 裁剪图像
+ const imageData = this.ctx.getImageData(
+ minX * this.dpr,
+ minY * this.dpr,
+ sw * this.dpr,
+ sh * this.dpr
+ )
+ const canvas = document.createElement('canvas')
+ canvas.style.width = `${sw}px`
+ canvas.style.height = `${sh}px`
+ canvas.width = sw * this.dpr
+ canvas.height = sh * this.dpr
+ const ctx = canvas.getContext('2d')!
+ ctx.putImageData(imageData, 0, 0)
+ const value = canvas.toDataURL()
+ return {
+ value,
+ width: sw,
+ height: sh
+ }
+ }
+
+ private _dispose() {
+ this.mask.remove()
+ this.container.remove()
+ }
+}
diff --git a/src/components/signature/signature.css b/src/components/signature/signature.css
new file mode 100644
index 0000000..287944c
--- /dev/null
+++ b/src/components/signature/signature.css
@@ -0,0 +1,128 @@
+.signature-mask {
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ opacity: .5;
+ background: #000000;
+ z-index: 99;
+}
+
+.signature-container {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ overflow: auto;
+ z-index: 999;
+ margin: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.signature {
+ position: absolute;
+ padding: 0 30px 30px;
+ background: #ffffff;
+ box-shadow: 0 2px 12px 0 rgb(56 56 56 / 20%);
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+}
+
+.signature-title {
+ position: relative;
+ border-bottom: 1px solid #e2e6ed;
+ margin-bottom: 15px;
+ height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.signature-title i {
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ display: inline-block;
+ background: url(../../assets/images/close.svg);
+}
+
+.signature-operation>div {
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ color: #3d4757;
+ user-select: none;
+}
+
+.signature-operation>div:hover {
+ color: #6e7175;
+}
+
+.signature-operation>div i {
+ width: 24px;
+ height: 24px;
+ display: inline-block;
+}
+
+.signature-operation__undo {
+ background: url(../../assets/images/signature-undo.svg) no-repeat;
+}
+
+.signature-operation__trash {
+ background: url(../../assets/images/trash.svg) no-repeat;
+}
+
+.signature-operation>div span {
+ font-size: 12px;
+ margin: 0 5px;
+}
+
+.signature-canvas {
+ margin: 15px 0;
+ user-select: none;
+}
+
+.signature-canvas canvas {
+ background: #f3f5f7;
+}
+
+.signature-menu {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+}
+
+.signature-menu button {
+ position: relative;
+ display: inline-block;
+ border: 1px solid #e2e6ed;
+ border-radius: 2px;
+ background: #ffffff;
+ line-height: 22px;
+ padding: 0 16px;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.signature-menu button:hover {
+ background: rgba(25, 55, 88, .04);
+}
+
+.signature-menu__cancel {
+ margin-right: 16px;
+}
+
+.signature-menu button[type='submit'] {
+ color: #ffffff;
+ background: #4991f2;
+ border-color: #4991f2;
+}
+
+.signature-menu button[type='submit']:hover {
+ background: #5b9cf3;
+ border-color: #5b9cf3;
+}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..60429ce
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,24 @@
+//import './assets/main.css'
+import './assets/style.css'
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+import { createRouter, createWebHistory } from 'vue-router'
+import { createApp } from 'vue'
+
+import App from './App.vue'
+import NewPage from './components/HelloWorld.vue'
+const routes = [
+ { path: '/', component: App },
+ { path: '/new-page', component: NewPage }
+]
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes
+})
+const app = createApp(App)
+app.use(ElementPlus)
+//app.provide('$axios',axios)
+app.use(router)
+app.mount('#app')
+//createApp(App).use(ElementPlus,VueAxios, axios).mount('#app')
diff --git a/src/options.js b/src/options.js
new file mode 100644
index 0000000..c2f7c07
--- /dev/null
+++ b/src/options.js
@@ -0,0 +1,106 @@
+interface IEditorOption {
+ mode?: EditorMode // 编辑器模式:编辑、清洁(不显示视觉辅助元素。如:分页符)、只读、表单(仅控件内可编辑)、打印(不显示辅助元素、未书写控件及前后括号)。默认:编辑
+ defaultType?: string // 默认元素类型。默认:TEXT
+ defaultColor?: string // 默认字体颜色。默认:#000000
+ defaultFont?: string // 默认字体。默认:Microsoft YaHei
+ defaultSize?: number // 默认字号。默认:16
+ minSize?: number // 最小字号。默认:5
+ maxSize?: number // 最大字号。默认:72
+ defaultBasicRowMarginHeight?: number // 默认行高。默认:8
+ defaultRowMargin?: number // 默认行间距。默认:1
+ defaultTabWidth?: number // 默认tab宽度。默认:32
+ width?: number // 纸张宽度。默认:794
+ height?: number // 纸张高度。默认:1123
+ scale?: number // 缩放比例。默认:1
+ pageGap?: number // 纸张间隔。默认:20
+ underlineColor?: string // 下划线颜色。默认:#000000
+ strikeoutColor?: string // 删除线颜色。默认:#FF0000
+ rangeColor?: string // 选区颜色。默认:#AECBFA
+ rangeAlpha?: number // 选区透明度。默认:0.6
+ rangeMinWidth?: number // 选区最小宽度。默认:5
+ searchMatchColor?: string // 搜索高亮颜色。默认:#FFFF00
+ searchNavigateMatchColor?: string // 搜索导航高亮颜色。默认:#AAD280
+ searchMatchAlpha?: number // 搜索高亮透明度。默认:0.6
+ highlightAlpha?: number // 高亮元素透明度。默认:0.6
+ resizerColor?: string // 图片尺寸器颜色。默认:#4182D9
+ resizerSize?: number // 图片尺寸器大小。默认:5
+ marginIndicatorSize?: number // 页边距指示器长度。默认:35
+ marginIndicatorColor?: string // 页边距指示器颜色。默认:#BABABA
+ margins?: IMargin // 页面边距。默认:[100, 120, 100, 120]
+ pageMode?: PageMode // 纸张模式:连页、分页。默认:分页
+ defaultHyperlinkColor?: string // 默认超链接颜色。默认:#0000FF
+ table?: ITableOption // 表格配置。{tdPadding?:IPadding; defaultTrMinHeight?:number; defaultColMinWidth?:number}
+ header?: IHeader // 页眉信息。{top?:number; maxHeightRadio?:MaxHeightRatio;}
+ footer?: IFooter // 页脚信息。{bottom?:number; maxHeightRadio?:MaxHeightRatio;}
+ pageNumber?: IPageNumber // 页码信息。{bottom:number; size:number; font:string; color:string; rowFlex:RowFlex; format:string; numberType:NumberType;}
+ paperDirection?: PaperDirection // 纸张方向:纵向、横向
+ inactiveAlpha?: number // 正文内容失焦时透明度。默认值:0.6
+ historyMaxRecordCount?: number // 历史(撤销重做)最大记录次数。默认:100次
+ printPixelRatio?: number // 打印像素比率(值越大越清晰,但尺寸越大)。默认:3
+ maskMargin?: IMargin // 编辑器上的遮盖边距(如悬浮到编辑器上的菜单栏、底部工具栏)。默认:[0, 0, 0, 0]
+ letterClass?: string[] // 排版支持的字母类。默认:a-zA-Z。内置可选择的字母表类:LETTER_CLASS
+ contextMenuDisableKeys?: string[] // 禁用的右键菜单。默认:[]
+ scrollContainerSelector?: string // 滚动区域选择器。默认:document
+ wordBreak?: WordBreak // 单词与标点断行:BREAK_WORD首行不出现标点&单词不拆分、BREAK_ALL按字符宽度撑满后折行。默认:BREAK_WORD
+ watermark?: IWatermark // 水印信息。{data:string; color?:string; opacity?:number; size?:number; font?:string;}
+ control?: IControlOption // 控件信息。 {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string; borderWidth?: number; borderColor?: string;}
+ checkbox?: ICheckboxOption // 复选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string;}
+ radio?: IRadioOption // 单选框信息。{width?:number; height?:number; gap?:number; lineWidth?:number; fillStyle?:string; strokeStyle?: string;}
+ cursor?: ICursorOption // 光标样式。{width?: number; color?: string; dragWidth?: number; dragColor?: string;}
+ title?: ITitleOption // 标题配置。{ defaultFirstSize?: number; defaultSecondSize?: number; defaultThirdSize?: number defaultFourthSize?: number; defaultFifthSize?: number; defaultSixthSize?: number;}
+ placeholder?: IPlaceholder // 编辑器空白占位文本
+ group?: IGroup // 成组配置。{opacity?:number; backgroundColor?:string; activeOpacity?:number; activeBackgroundColor?:string; disabled?:boolean}
+ pageBreak?: IPageBreak // 分页符配置。{font?:string; fontSize?:number; lineDash?:number[];}
+ zone?: IZoneOption // 编辑器区域配置。{tipDisabled?:boolean;}
+ background?: IBackgroundOption // 背景配置。{color?:string; image?:string; size?:BackgroundSize; repeat?:BackgroundRepeat;}。默认:{color: '#FFFFFF'}
+ lineBreak?: ILineBreakOption // 换行符配置。{disabled?:boolean; color?:string; lineWidth?:number;}
+ separator?: ISeparatorOption // 分隔符配置。{lineWidth?:number; strokeStyle?:string;}
+}
+
+interface ITableOption {
+ tdPadding?: IPadding // 单元格内边距。默认:[0, 5, 5, 5]
+ defaultTrMinHeight?: number // 默认表格行最小高度。默认:42
+ defaultColMinWidth?: number // 默认表格列最小宽度(整体宽度足够时应用,否则会按比例缩小)。默认:40
+}
+
+interface IHeader {
+ top?: number // 距离页面顶部大小。默认:30
+ maxHeightRadio?: MaxHeightRatio // 占页面最大高度比。默认:HALF
+ disabled?: boolean // 是否禁用
+}
+
+interface IFooter {
+ bottom?: number // 距离页面底部大小。默认:30
+ maxHeightRadio?: MaxHeightRatio // 占页面最大高度比。默认:HALF
+ disabled?: boolean // 是否禁用
+}
+
+interface IPageNumber {
+ bottom?: number // 距离页面底部大小。默认:60
+ size?: number // 字体大小。默认:12
+ font?: string // 字体。默认:Microsoft YaHei
+ color?: string // 字体颜色。默认:#000000
+ rowFlex?: RowFlex // 行对齐方式。默认:CENTER
+ format?: string // 页码格式。默认:{pageNo}。示例:第{pageNo}页/共{pageCount}页
+ numberType?: NumberType // 数字类型。默认:ARABIC
+ disabled?: boolean // 是否禁用
+ startPageNo?: number // 起始页码。默认:1
+ fromPageNo?: number // 从第几页开始出现页码。默认:0
+ maxPageNo?: number | null // 最大页码(从0开始)。默认:null
+}
+
+interface IWatermark {
+ data: string // 文本。
+ color?: string // 颜色。默认:#AEB5C0
+ opacity?: number // 透明度。默认:0.3
+ size?: number // 字体大小。默认:200
+ font?: string // 字体。默认:Microsoft YaHei
+}
+
+interface IPlaceholder {
+ data: string // 文本。
+ color?: string // 颜色。默认:#DCDFE6
+ opacity?: number // 透明度。默认:1
+ size?: number // 字体大小。默认:16
+ font?: string // 字体。默认:Microsoft YaHei
+}
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..065dd2c
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,30 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ },
+ server: {
+ proxy: {
+ // 在此处编写代理规则
+ '/api': {
+ secure: false,
+ //target: 'https://192.168.3.198',
+ target: 'https://c.apxly.com',
+ changeOrigin: true,
+ rewrite: (path) => {
+ return path.replace(/\/api/, '')
+ }
+ }
+ }
+ }
+})
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..e69de29