diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f7785bd
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = tab
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..873c9d8
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,3 @@
+VITE_APP_TITLE=Gao Customer H5
+VITE_USE_LOCAL_TIMI_WEB=true
+VITE_API_BASE_URL=http://localhost:8091
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..dd8bb80
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,2 @@
+VITE_APP_TITLE=Gao Customer H5
+VITE_API_BASE_URL=https://api.imyeyu.com
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000..ae13a7c
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,44 @@
+module.exports = {
+ root: true,
+ env: {
+ browser: true,
+ es2022: true,
+ node: true
+ },
+ extends: [
+ "eslint:recommended",
+ "plugin:vue/vue3-essential",
+ "plugin:@typescript-eslint/recommended",
+ "./.eslintrc-auto-import.json"
+ ],
+ parser: "vue-eslint-parser",
+ parserOptions: {
+ parser: "@typescript-eslint/parser",
+ ecmaVersion: "latest",
+ sourceType: "module",
+ extraFileExtensions: [".vue"]
+ },
+ plugins: ["vue", "@typescript-eslint"],
+ rules: {
+ "camelcase": "error",
+ "comma-dangle": ["error", "never"],
+ "eqeqeq": ["error", "always"],
+ "max-len": ["error", { code: 220 }],
+ "no-console": ["warn", { allow: ["warn", "error"] }],
+ "no-debugger": "warn",
+ "no-tabs": ["error", { allowIndentationTabs: true }],
+ "quotes": ["error", "double"],
+ "semi": ["error", "always"],
+ "space-before-function-paren": [
+ "error",
+ {
+ "anonymous": "always",
+ "named": "never",
+ "asyncArrow": "always"
+ }
+ ],
+ "vue/multi-word-component-names": "off",
+ "vue/no-v-html": "off",
+ "@typescript-eslint/no-explicit-any": "off"
+ }
+};
diff --git a/.gitignore b/.gitignore
index 7f7e9bb..6fd4a3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
+/AGENTS.md
+/.npmrc
+/.env.production
+
# ---> Maven
target/
pom.xml.tag
@@ -122,3 +126,13 @@ fabric.properties
hs_err_pid*
replay_pid*
+# ---> Node / Vite
+node_modules
+dist
+dist-ssr
+coverage
+*.local
+auto-imports.d.ts
+components.d.ts
+.eslintrc-auto-import.json
+
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..30cf57e
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Ignored default folder with query files
+/queries/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gao-customer-h5.iml b/.idea/gao-customer-h5.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/gao-customer-h5.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..9f87cb1
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..9c28189
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.serena/.gitignore b/.serena/.gitignore
new file mode 100644
index 0000000..2e510af
--- /dev/null
+++ b/.serena/.gitignore
@@ -0,0 +1,2 @@
+/cache
+/project.local.yml
diff --git a/.serena/memories/project_overview.md b/.serena/memories/project_overview.md
new file mode 100644
index 0000000..5ff99e2
--- /dev/null
+++ b/.serena/memories/project_overview.md
@@ -0,0 +1,4 @@
+- 项目用途:基于 Vue 3 + Vite + TypeScript + TDesign 的移动端 NAS 管理项目,包含文件管理、服务器状态、文件读取等功能。
+- 前端栈:Vue 3 Composition API(setup 语法糖)、Vite、TypeScript、Pinia、Vue Router、Axios、Less、TDesign。
+- 后端接口上下文:对接后端源码位于 E:\IDEAProject\TimiServerAPI\src\main\java\com\imyeyu\api\modules\system\controller。
+- 代码结构:主要业务页面位于 src/pages,下分 customer、management 等目录;入口与路由位于 src/main.ts、src/router/index.ts;存在 Pinia store。
\ No newline at end of file
diff --git a/.serena/memories/style_conventions.md b/.serena/memories/style_conventions.md
new file mode 100644
index 0000000..dae71a6
--- /dev/null
+++ b/.serena/memories/style_conventions.md
@@ -0,0 +1,6 @@
+- 所有沟通、文案、注释使用中文;文件编码使用 UTF-8。
+- 前端使用 Vue 3 Composition API + setup,代码按功能分块组织,公共变量/函数在前。
+- Vue 自定义组件标签使用全小写;模板中动态文本优先使用 v-text。
+- Less 必须使用层级写法,属性尽量缩写,单位优先 rem,小数写法如 .5。
+- 尽量定义 TypeScript 类型和必要的 JSDoc;Promise 写法优先 async/await。
+- 不轻易引入外部依赖,优先官方 API;需要兼容深色模式。
\ No newline at end of file
diff --git a/.serena/memories/suggested_commands.md b/.serena/memories/suggested_commands.md
new file mode 100644
index 0000000..d4b5c6e
--- /dev/null
+++ b/.serena/memories/suggested_commands.md
@@ -0,0 +1,7 @@
+- 安装依赖:npm install
+- 本地开发:npm run dev
+- 生产构建:npm run build
+- 预览构建:npm run preview
+- ESLint 检查:npm run lint
+- TypeScript 检查:npm run type-check
+- Windows 常用命令:Get-ChildItem、Get-Content、rg、git status、git diff
\ No newline at end of file
diff --git a/.serena/memories/task_completion.md b/.serena/memories/task_completion.md
new file mode 100644
index 0000000..80ed1c5
--- /dev/null
+++ b/.serena/memories/task_completion.md
@@ -0,0 +1,3 @@
+- 完成前端改动后,至少执行 npm run build 或 npm run type-check 验证没有明显编译错误。
+- 如涉及样式和交互,检查深色模式与移动端布局,避免固定底部按钮遮挡内容。
+- 不主动添加测试;若无法运行验证命令,需要在最终说明中明确指出。
\ No newline at end of file
diff --git a/.serena/project.yml b/.serena/project.yml
new file mode 100644
index 0000000..08e55a8
--- /dev/null
+++ b/.serena/project.yml
@@ -0,0 +1,153 @@
+# the name by which the project can be referenced within Serena
+project_name: "gao-customer-h5"
+
+
+# list of languages for which language servers are started; choose from:
+# al bash clojure cpp csharp
+# csharp_omnisharp dart elixir elm erlang
+# fortran fsharp go groovy haskell
+# haxe java julia kotlin lua
+# markdown
+# matlab nix pascal perl php
+# php_phpactor powershell python python_jedi r
+# rego ruby ruby_solargraph rust scala
+# swift terraform toml typescript typescript_vts
+# vue yaml zig
+# (This list may be outdated. For the current list, see values of Language enum here:
+# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
+# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
+# Note:
+# - For C, use cpp
+# - For JavaScript, use typescript
+# - For Free Pascal/Lazarus, use pascal
+# Special requirements:
+# Some languages require additional setup/installations.
+# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
+# When using multiple languages, the first language server that supports a given file will be used for that file.
+# The first language is the default language and the respective language server will be used as a fallback.
+# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
+languages: []
+
+# the encoding used by text files in the project
+# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
+encoding: "utf-8"
+
+# line ending convention to use when writing source files.
+# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
+# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
+line_ending:
+
+# The language backend to use for this project.
+# If not set, the global setting from serena_config.yml is used.
+# Valid values: LSP, JetBrains
+# Note: the backend is fixed at startup. If a project with a different backend
+# is activated post-init, an error will be returned.
+language_backend:
+
+# whether to use project's .gitignore files to ignore files
+ignore_all_files_in_gitignore: true
+
+# advanced configuration option allowing to configure language server-specific options.
+# Maps the language key to the options.
+# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available.
+# No documentation on options means no options are available.
+ls_specific_settings: {}
+
+# list of additional paths to ignore in this project.
+# Same syntax as gitignore, so you can use * and **.
+# Note: global ignored_paths from serena_config.yml are also applied additively.
+ignored_paths: []
+
+# whether the project is in read-only mode
+# If set to true, all editing tools will be disabled and attempts to use them will result in an error
+# Added on 2025-04-18
+read_only: false
+
+# list of tool names to exclude.
+# This extends the existing exclusions (e.g. from the global configuration)
+#
+# Below is the complete list of tools for convenience.
+# To make sure you have the latest list of tools, and to view their descriptions,
+# execute `uv run scripts/print_tool_overview.py`.
+#
+# * `activate_project`: Activates a project based on the project name or path.
+# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
+# * `create_text_file`: Creates/overwrites a file in the project directory.
+# * `delete_memory`: Delete a memory file. Should only happen if a user asks for it explicitly,
+# for example by saying that the information retrieved from a memory file is no longer correct
+# or no longer relevant for the project.
+# * `edit_memory`: Replaces content matching a regular expression in a memory.
+# * `execute_shell_command`: Executes a shell command.
+# * `find_file`: Finds files in the given relative paths
+# * `find_referencing_symbols`: Finds symbols that reference the given symbol using the language server backend
+# * `find_symbol`: Performs a global (or local) search using the language server backend.
+# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
+# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
+# * `initial_instructions`: Provides instructions Serena usage (i.e. the 'Serena Instructions Manual')
+# for clients that do not read the initial instructions when the MCP server is connected.
+# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
+# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
+# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
+# * `list_memories`: List available memories. Any memory can be read using the `read_memory` tool.
+# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
+# * `read_file`: Reads a file within the project directory.
+# * `read_memory`: Read the content of a memory file. This tool should only be used if the information
+# is relevant to the current task. You can infer whether the information
+# is relevant from the memory file name.
+# You should not read the same memory file multiple times in the same conversation.
+# * `rename_memory`: Renames or moves a memory. Moving between project and global scope is supported
+# (e.g., renaming "global/foo" to "bar" moves it from global to project scope).
+# * `rename_symbol`: Renames a symbol throughout the codebase using language server refactoring capabilities.
+# For JB, we use a separate tool.
+# * `replace_content`: Replaces content in a file (optionally using regular expressions).
+# * `replace_symbol_body`: Replaces the full definition of a symbol using the language server backend.
+# * `safe_delete_symbol`:
+# * `search_for_pattern`: Performs a search for a pattern in the project.
+# * `write_memory`: Write some information (utf-8-encoded) about this project that can be useful for future tasks to a memory in md format.
+# The memory name should be meaningful.
+excluded_tools: []
+
+# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
+# This extends the existing inclusions (e.g. from the global configuration).
+included_optional_tools: []
+
+# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
+# This cannot be combined with non-empty excluded_tools or included_optional_tools.
+fixed_tools: []
+
+# list of mode names to that are always to be included in the set of active modes
+# The full set of modes to be activated is base_modes + default_modes.
+# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
+# Otherwise, this setting overrides the global configuration.
+# Set this to [] to disable base modes for this project.
+# Set this to a list of mode names to always include the respective modes for this project.
+base_modes:
+
+# list of mode names that are to be activated by default.
+# The full set of modes to be activated is base_modes + default_modes.
+# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
+# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
+# This setting can, in turn, be overridden by CLI parameters (--mode).
+default_modes:
+
+# initial prompt for the project. It will always be given to the LLM upon activating the project
+# (contrary to the memories, which are loaded on demand).
+initial_prompt: ""
+
+# time budget (seconds) per tool call for the retrieval of additional symbol information
+# such as docstrings or parameter information.
+# This overrides the corresponding setting in the global configuration; see the documentation there.
+# If null or missing, use the setting from the global configuration.
+symbol_info_budget:
+
+# list of regex patterns which, when matched, mark a memory entry as read‑only.
+# Extends the list from the global configuration, merging the two lists.
+read_only_memory_patterns: []
+
+# list of regex patterns for memories to completely ignore.
+# Matching memories will not appear in list_memories or activate_project output
+# and cannot be accessed via read_memory or write_memory.
+# To access ignored memory files, use the read_file tool on the raw file path.
+# Extends the list from the global configuration, merging the two lists.
+# Example: ["_archive/.*", "_episodes/.*"]
+ignored_memory_patterns: []
diff --git a/README.md b/README.md
index d9d6670..2291917 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
-# dtgao-customer-h5
+# gao-customer-h5
+
+基于 Vue 3、Vite、TypeScript、Pinia、Vue Router、TDesign Mobile Vue 的移动端项目初始化骨架。
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 0000000..7f0be18
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,79 @@
+import tsParser from "@typescript-eslint/parser";
+import tsPlugin from "@typescript-eslint/eslint-plugin";
+import vuePlugin from "eslint-plugin-vue";
+import vueParser from "vue-eslint-parser";
+import autoImportConfig from "./.eslintrc-auto-import.json" with { type: "json" };
+
+const browserGlobals = {
+ document: "readonly",
+ File: "readonly",
+ HTMLCanvasElement: "readonly",
+ HTMLInputElement: "readonly",
+ HTMLElement: "readonly",
+ localStorage: "readonly",
+ MouseEvent: "readonly",
+ Touch: "readonly",
+ TouchEvent: "readonly",
+ URL: "readonly",
+ window: "readonly"
+};
+
+const nodeGlobals = {
+ console: "readonly",
+ process: "readonly"
+};
+
+export default [
+ {
+ ignores: [
+ "dist/**",
+ "node_modules/**",
+ "auto-imports.d.ts",
+ "components.d.ts"
+ ]
+ },
+ ...vuePlugin.configs["flat/essential"],
+ {
+ files: ["**/*.ts", "**/*.vue"],
+ languageOptions: {
+ parser: vueParser,
+ parserOptions: {
+ parser: tsParser,
+ ecmaVersion: "latest",
+ sourceType: "module",
+ extraFileExtensions: [".vue"]
+ },
+ globals: {
+ ...browserGlobals,
+ ...nodeGlobals,
+ ...autoImportConfig.globals
+ }
+ },
+ plugins: {
+ "@typescript-eslint": tsPlugin
+ },
+ rules: {
+ ...tsPlugin.configs.recommended.rules,
+ camelcase: "error",
+ "comma-dangle": ["error", "never"],
+ eqeqeq: ["error", "always"],
+ "max-len": ["error", { code: 220 }],
+ "no-console": ["warn", { allow: ["warn", "error"] }],
+ "no-debugger": "warn",
+ "no-tabs": ["error", { allowIndentationTabs: true }],
+ quotes: ["error", "double"],
+ semi: ["error", "always"],
+ "space-before-function-paren": [
+ "error",
+ {
+ anonymous: "always",
+ named: "never",
+ asyncArrow: "always"
+ }
+ ],
+ "vue/multi-word-component-names": "off",
+ "vue/no-v-html": "off",
+ "@typescript-eslint/no-explicit-any": "off"
+ }
+ }
+];
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..4bb048e
--- /dev/null
+++ b/index.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gao Customer H5
+
+
+
+
+
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..7272345
--- /dev/null
+++ b/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "gao-customer-h5",
+ "private": true,
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite --host",
+ "build": "pnpm run type-check:publish && vite build",
+ "preview": "vite preview",
+ "lint": "eslint . --ext .ts,.vue",
+ "type-check": "vue-tsc -p tsconfig.app.json --noEmit",
+ "type-check:publish": "vue-tsc -p tsconfig.publish.json --noEmit"
+ },
+ "dependencies": {
+ "@zxing/browser": "^0.1.5",
+ "@zxing/library": "^0.21.3",
+ "echarts": "^6.0.0",
+ "vue-echarts": "^8.0.1",
+ "axios": "1.15.0",
+ "less": "^4.3.0",
+ "pinia": "^3.0.2",
+ "tdesign-mobile-vue": "^1.16.0",
+ "timi-tdesign-mobile": "0.0.10",
+ "browser-image-compression": "^2.0.2",
+ "timi-web": "0.0.24",
+ "ts-node": "^10.9.2",
+ "vue": "^3.5.16",
+ "vue-router": "4.5.1",
+ "vue-virtual-scroller": "2.0.0-beta.8"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.4",
+ "@types/node": "^24.2.0",
+ "@typescript-eslint/eslint-plugin": "^8.29.0",
+ "@typescript-eslint/parser": "^8.29.0",
+ "@vitejs/plugin-vue": "^5.2.4",
+ "@vue/compiler-sfc": "^3.5.16",
+ "@vue/eslint-config-typescript": "^14.5.0",
+ "@vue/tsconfig": "^0.7.0",
+ "eslint": "9.26.0",
+ "eslint-plugin-vue": "^9.33.0",
+ "typescript": "~5.8.3",
+ "unplugin-auto-import": "^19.1.1",
+ "unplugin-vue-components": "^28.4.1",
+ "vite": "^6.3.5",
+ "vue-eslint-parser": "^9.4.3",
+ "vue-tsc": "^2.2.12"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..05ff868
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,4181 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@zxing/browser':
+ specifier: ^0.1.5
+ version: 0.1.5(@zxing/library@0.21.3)
+ '@zxing/library':
+ specifier: ^0.21.3
+ version: 0.21.3
+ axios:
+ specifier: 1.15.0
+ version: 1.15.0
+ browser-image-compression:
+ specifier: ^2.0.2
+ version: 2.0.2
+ echarts:
+ specifier: ^6.0.0
+ version: 6.1.0
+ less:
+ specifier: ^4.3.0
+ version: 4.8.0
+ pinia:
+ specifier: ^3.0.2
+ version: 3.0.4(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3))
+ tdesign-mobile-vue:
+ specifier: ^1.16.0
+ version: 1.16.0(vue@3.5.40(typescript@5.8.3))
+ timi-tdesign-mobile:
+ specifier: 0.0.10
+ version: 0.0.10(typescript@5.8.3)
+ timi-web:
+ specifier: 0.0.24
+ version: 0.0.24(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3))
+ ts-node:
+ specifier: ^10.9.2
+ version: 10.9.2(@types/node@24.13.3)(typescript@5.8.3)
+ vue:
+ specifier: ^3.5.16
+ version: 3.5.40(typescript@5.8.3)
+ vue-echarts:
+ specifier: ^8.0.1
+ version: 8.0.1(echarts@6.1.0)(vue@3.5.40(typescript@5.8.3))
+ vue-router:
+ specifier: 4.5.1
+ version: 4.5.1(vue@3.5.40(typescript@5.8.3))
+ vue-virtual-scroller:
+ specifier: 2.0.0-beta.8
+ version: 2.0.0-beta.8(vue@3.5.40(typescript@5.8.3))
+ devDependencies:
+ '@tsconfig/node20':
+ specifier: ^20.1.4
+ version: 20.1.9
+ '@types/node':
+ specifier: ^24.2.0
+ version: 24.13.3
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^8.29.0
+ version: 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.26.0)(typescript@5.8.3))(eslint@9.26.0)(typescript@5.8.3)
+ '@typescript-eslint/parser':
+ specifier: ^8.29.0
+ version: 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ '@vitejs/plugin-vue':
+ specifier: ^5.2.4
+ version: 5.2.4(vite@6.4.3(@types/node@24.13.3)(less@4.8.0)(terser@5.49.0))(vue@3.5.40(typescript@5.8.3))
+ '@vue/compiler-sfc':
+ specifier: ^3.5.16
+ version: 3.5.40
+ '@vue/eslint-config-typescript':
+ specifier: ^14.5.0
+ version: 14.9.0(eslint-plugin-vue@9.33.0(eslint@9.26.0))(eslint@9.26.0)(typescript@5.8.3)
+ '@vue/tsconfig':
+ specifier: ^0.7.0
+ version: 0.7.0(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3))
+ eslint:
+ specifier: 9.26.0
+ version: 9.26.0
+ eslint-plugin-vue:
+ specifier: ^9.33.0
+ version: 9.33.0(eslint@9.26.0)
+ typescript:
+ specifier: ~5.8.3
+ version: 5.8.3
+ unplugin-auto-import:
+ specifier: ^19.1.1
+ version: 19.3.0(@vueuse/core@10.7.0(vue@3.5.40(typescript@5.8.3)))
+ unplugin-vue-components:
+ specifier: ^28.4.1
+ version: 28.8.0(@babel/parser@7.29.7)(vue@3.5.40(typescript@5.8.3))
+ vite:
+ specifier: ^6.3.5
+ version: 6.4.3(@types/node@24.13.3)(less@4.8.0)(terser@5.49.0)
+ vue-eslint-parser:
+ specifier: ^9.4.3
+ version: 9.4.3(eslint@9.26.0)
+ vue-tsc:
+ specifier: ^2.2.12
+ version: 2.2.12(typescript@5.8.3)
+
+packages:
+
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.7':
+ resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/runtime@7.29.7':
+ resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.29.7':
+ resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
+ engines: {node: '>=6.9.0'}
+
+ '@cspotcode/source-map-support@0.8.1':
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+
+ '@esbuild/aix-ppc64@0.25.12':
+ resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.25.12':
+ resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.25.12':
+ resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.25.12':
+ resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.25.12':
+ resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.25.12':
+ resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.25.12':
+ resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.25.12':
+ resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.25.12':
+ resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.25.12':
+ resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.25.12':
+ resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.25.12':
+ resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.25.12':
+ resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.25.12':
+ resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.25.12':
+ resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.25.12':
+ resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.25.12':
+ resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.25.12':
+ resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.25.12':
+ resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.25.12':
+ resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.12':
+ resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.12':
+ resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.10.1':
+ resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.12.2':
+ resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/config-array@0.20.1':
+ resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/config-helpers@0.2.3':
+ resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/core@0.13.0':
+ resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/eslintrc@3.3.6':
+ resolution: {integrity: sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/js@9.26.0':
+ resolution: {integrity: sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/object-schema@2.1.7':
+ resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/plugin-kit@0.2.8':
+ resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@hono/node-server@1.19.15':
+ resolution: {integrity: sha512-Za2ai6TLdKjUvnur+eenO6nuYYipVAEhyCAdaV8IRvmU9kK8crOZUSYvIXn72E4f8fJqyAbpcJuTsYYmZp9Deg==}
+ engines: {node: '>=18.14.1'}
+ peerDependencies:
+ hono: ^4
+
+ '@humanfs/core@0.19.2':
+ resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/node@0.16.8':
+ resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/types@0.15.0':
+ resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/retry@0.4.3':
+ resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
+ engines: {node: '>=18.18'}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/source-map@0.3.11':
+ resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+
+ '@modelcontextprotocol/sdk@1.29.0':
+ resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@cfworker/json-schema': ^4.1.1
+ zod: ^3.25 || ^4.0
+ peerDependenciesMeta:
+ '@cfworker/json-schema':
+ optional: true
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@rollup/rollup-android-arm-eabi@4.62.3':
+ resolution: {integrity: sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.62.3':
+ resolution: {integrity: sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.62.3':
+ resolution: {integrity: sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.62.3':
+ resolution: {integrity: sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.62.3':
+ resolution: {integrity: sha512-zvBUvsQUpOWALdDsk6qbS8bXf2VxmPisuudNDrY7x0p0jBdsoZl8HsHczIOgkQiZldmcacMKtBzpoGVNeIe2bQ==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.62.3':
+ resolution: {integrity: sha512-C2KmNrcSem/AMg984H/dev+si0lieQGdXdR/lYGJnuumXnFb9Y7QdiI62obFdLlxRYLBv4P0eUVIDbD4c1vVvw==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.3':
+ resolution: {integrity: sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.62.3':
+ resolution: {integrity: sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-arm64-gnu@4.62.3':
+ resolution: {integrity: sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm64-musl@4.62.3':
+ resolution: {integrity: sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-loong64-gnu@4.62.3':
+ resolution: {integrity: sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-loong64-musl@4.62.3':
+ resolution: {integrity: sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.62.3':
+ resolution: {integrity: sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-ppc64-musl@4.62.3':
+ resolution: {integrity: sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.3':
+ resolution: {integrity: sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.3':
+ resolution: {integrity: sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.3':
+ resolution: {integrity: sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-gnu@4.62.3':
+ resolution: {integrity: sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-musl@4.62.3':
+ resolution: {integrity: sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-openbsd-x64@4.62.3':
+ resolution: {integrity: sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.62.3':
+ resolution: {integrity: sha512-+2Cy/ldweGBLlPIKsQLF8U5N44a0KDdbrk1rAjHOM9M2K+kGdIVjHLmmrZIcx+9Ny3ke/1JomCsDI1ocb11+sg==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.3':
+ resolution: {integrity: sha512-dtZvzc8BedpSaFNy75x6uiWwAGTH+aZHDtdrqP6qk+WcLJrfti6sGje1ZJ9UxyzDLF23d/mV+PaMwuC0hL7UVA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.3':
+ resolution: {integrity: sha512-Rj8Ra4noo+aYy7sKBggCx0407mws34kAb1ySyWuq5DAtFBQdkSwnsjCgPrhPe9cvgBKZIukpE+CVHvORCS93kQ==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.62.3':
+ resolution: {integrity: sha512-vp7N084ew/odXn2gi/mzm9mUkQu9l6AiN6dt4IeUM2Uvm9o+cVmP+YkqbMOteLbiGgqBBlJZjIMYVCfOOIVbVQ==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.62.3':
+ resolution: {integrity: sha512-MOG/3gTOn4Fwf574RVOaY61I5o6P90legkFADiTyn1hyjNydT+cerU2rLUwPdZkKKyJ+iT+K9p7WXK4LM1Ka6g==}
+ cpu: [x64]
+ os: [win32]
+
+ '@tsconfig/node10@1.0.12':
+ resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==}
+
+ '@tsconfig/node12@1.0.11':
+ resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
+
+ '@tsconfig/node14@1.0.3':
+ resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
+
+ '@tsconfig/node16@1.0.4':
+ resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+
+ '@tsconfig/node20@20.1.9':
+ resolution: {integrity: sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==}
+
+ '@types/esrecurse@4.3.1':
+ resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/node@24.13.3':
+ resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@typescript-eslint/eslint-plugin@8.65.0':
+ resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^8.65.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/parser@8.65.0':
+ resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/project-service@8.65.0':
+ resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/scope-manager@8.65.0':
+ resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/tsconfig-utils@8.65.0':
+ resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/type-utils@8.65.0':
+ resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/types@8.65.0':
+ resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/typescript-estree@8.65.0':
+ resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/utils@8.65.0':
+ resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/visitor-keys@8.65.0':
+ resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@use-gesture/core@10.3.1':
+ resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==}
+
+ '@use-gesture/vanilla@10.3.1':
+ resolution: {integrity: sha512-lT4scGLu59ovA3zmtUonukAGcA0AdOOh+iwNDS05Bsu7Lq9aZToDHhI6D8Q2qvsVraovtsLLYwPrWdG/noMAKw==}
+
+ '@vitejs/plugin-vue@5.2.4':
+ resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0
+ vue: ^3.2.25
+
+ '@volar/language-core@2.4.15':
+ resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==}
+
+ '@volar/source-map@2.4.15':
+ resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==}
+
+ '@volar/typescript@2.4.15':
+ resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==}
+
+ '@vue/compiler-core@3.5.40':
+ resolution: {integrity: sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==}
+
+ '@vue/compiler-dom@3.5.40':
+ resolution: {integrity: sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==}
+
+ '@vue/compiler-sfc@3.5.40':
+ resolution: {integrity: sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==}
+
+ '@vue/compiler-ssr@3.5.40':
+ resolution: {integrity: sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==}
+
+ '@vue/compiler-vue2@2.7.16':
+ resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
+
+ '@vue/devtools-api@6.6.4':
+ resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
+
+ '@vue/devtools-api@7.7.10':
+ resolution: {integrity: sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==}
+
+ '@vue/devtools-kit@7.7.10':
+ resolution: {integrity: sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==}
+
+ '@vue/devtools-shared@7.7.10':
+ resolution: {integrity: sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==}
+
+ '@vue/eslint-config-typescript@14.9.0':
+ resolution: {integrity: sha512-E3j9hDlfVf10F30MRcLTPY2IIhWIx1nsvkVukk14kTcuA+oBVot9zsP1hzsO+PAMDxV3Fd9FimBJtUBNBL5KFA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+ peerDependencies:
+ eslint: ^9.10.0 || ^10.0.0
+ eslint-plugin-vue: ^9.28.0 || ^10.0.0
+ typescript: '>=4.8.4'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@vue/language-core@2.2.12':
+ resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@vue/reactivity@3.5.40':
+ resolution: {integrity: sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==}
+
+ '@vue/runtime-core@3.5.40':
+ resolution: {integrity: sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==}
+
+ '@vue/runtime-dom@3.5.40':
+ resolution: {integrity: sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==}
+
+ '@vue/server-renderer@3.5.40':
+ resolution: {integrity: sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==}
+
+ '@vue/shared@3.5.40':
+ resolution: {integrity: sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==}
+
+ '@vue/tsconfig@0.7.0':
+ resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==}
+ peerDependencies:
+ typescript: 5.x
+ vue: ^3.4.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ vue:
+ optional: true
+
+ '@vueuse/core@10.7.0':
+ resolution: {integrity: sha512-4EUDESCHtwu44ZWK3Gc/hZUVhVo/ysvdtwocB5vcauSV4B7NiGY5972WnsojB3vRNdxvAt7kzJWE2h9h7C9d5w==}
+
+ '@vueuse/metadata@10.7.0':
+ resolution: {integrity: sha512-GlaH7tKP2iBCZ3bHNZ6b0cl9g0CJK8lttkBNUX156gWvNYhTKEtbweWLm9rxCPIiwzYcr/5xML6T8ZUEt+DkvA==}
+
+ '@vueuse/shared@10.7.0':
+ resolution: {integrity: sha512-kc00uV6CiaTdc3i1CDC4a3lBxzaBE9AgYNtFN87B5OOscqeWElj/uza8qVDmk7/U8JbqoONLbtqiLJ5LGRuqlw==}
+
+ '@zxing/browser@0.1.5':
+ resolution: {integrity: sha512-4Lmrn/il4+UNb87Gk8h1iWnhj39TASEHpd91CwwSJtY5u+wa0iH9qS0wNLAWbNVYXR66WmT5uiMhZ7oVTrKfxw==}
+ peerDependencies:
+ '@zxing/library': ^0.21.0
+
+ '@zxing/library@0.21.3':
+ resolution: {integrity: sha512-hZHqFe2JyH/ZxviJZosZjV+2s6EDSY0O24R+FQmlWZBZXP9IqMo7S3nb3+2LBWxodJQkSurdQGnqE7KXqrYgow==}
+ engines: {node: '>= 10.4.0'}
+
+ '@zxing/text-encoding@0.9.0':
+ resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==}
+
+ accepts@2.0.0:
+ resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
+ engines: {node: '>= 0.6'}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn-walk@8.3.5:
+ resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==}
+ engines: {node: '>=0.4.0'}
+
+ acorn@8.17.0:
+ resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ agent-base@6.0.2:
+ resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
+ engines: {node: '>= 6.0.0'}
+
+ ajv-formats@3.0.1:
+ resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv@6.15.0:
+ resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
+ alien-signals@1.0.13:
+ resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@4.1.3:
+ resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ axios@1.15.0:
+ resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==}
+
+ axios@1.18.0:
+ resolution: {integrity: sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ birpc@2.9.0:
+ resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==}
+
+ body-parser@2.3.0:
+ resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==}
+ engines: {node: '>=18'}
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ brace-expansion@1.1.16:
+ resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==}
+
+ brace-expansion@2.1.2:
+ resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==}
+
+ brace-expansion@5.0.8:
+ resolution: {integrity: sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==}
+ engines: {node: 20 || >=22}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browser-image-compression@2.0.2:
+ resolution: {integrity: sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw==}
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ bytes@3.1.2:
+ resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
+ engines: {node: '>= 0.8'}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.4:
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ confbox@0.2.4:
+ resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
+
+ content-disposition@1.1.0:
+ resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==}
+ engines: {node: '>=18'}
+
+ content-type@1.0.5:
+ resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
+ engines: {node: '>= 0.6'}
+
+ content-type@2.0.0:
+ resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==}
+ engines: {node: '>=18'}
+
+ cookie-signature@1.2.2:
+ resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
+ engines: {node: '>=6.6.0'}
+
+ cookie@0.7.2:
+ resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
+ engines: {node: '>= 0.6'}
+
+ copy-anything@2.0.6:
+ resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
+
+ copy-anything@3.0.5:
+ resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
+ engines: {node: '>=12.13'}
+
+ copy-anything@4.0.5:
+ resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
+ engines: {node: '>=18'}
+
+ cors@2.8.6:
+ resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
+ engines: {node: '>= 0.10'}
+
+ create-require@1.1.1:
+ resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ dayjs@1.11.21:
+ resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==}
+
+ de-indent@1.0.2:
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+
+ debug@2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ depd@2.0.0:
+ resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
+ engines: {node: '>= 0.8'}
+
+ diff@4.0.4:
+ resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==}
+ engines: {node: '>=0.3.1'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ echarts@6.1.0:
+ resolution: {integrity: sha512-q0yaFPggC9FUdsWH4blavRWFmxdrIodbkoKNAjJudAI6CA9gNPxHtV2RcZNEepZVlk4yvBYkOkbk6HIVpIyHZA==}
+
+ ee-first@1.1.1:
+ resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ errno@0.1.8:
+ resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+ hasBin: true
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.2:
+ resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.25.12:
+ resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escape-html@1.0.3:
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ eslint-plugin-vue@9.33.0:
+ resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==}
+ engines: {node: ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
+
+ eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-scope@8.4.0:
+ resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-scope@9.1.2:
+ resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@4.2.1:
+ resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@5.0.1:
+ resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint@9.26.0:
+ resolution: {integrity: sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+
+ espree@10.4.0:
+ resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ espree@11.2.0:
+ resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ esquery@1.7.0:
+ resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ etag@1.8.1:
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+ engines: {node: '>= 0.6'}
+
+ eventsource-parser@3.1.0:
+ resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==}
+ engines: {node: '>=18.0.0'}
+
+ eventsource@3.0.7:
+ resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
+ engines: {node: '>=18.0.0'}
+
+ express-rate-limit@8.6.0:
+ resolution: {integrity: sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA==}
+ engines: {node: '>= 16'}
+ peerDependencies:
+ express: '>= 4.11'
+
+ express@5.2.1:
+ resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
+ engines: {node: '>= 18'}
+
+ exsolve@1.1.0:
+ resolution: {integrity: sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fast-uri@3.1.4:
+ resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==}
+
+ fastq@1.20.1:
+ resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ file-entry-cache@8.0.0:
+ resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+ engines: {node: '>=16.0.0'}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ finalhandler@2.1.1:
+ resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
+ engines: {node: '>= 18.0.0'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat-cache@4.0.1:
+ resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+ engines: {node: '>=16'}
+
+ flatted@3.4.3:
+ resolution: {integrity: sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==}
+
+ follow-redirects@1.16.0:
+ resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ form-data@4.0.6:
+ resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==}
+ engines: {node: '>= 6'}
+
+ forwarded@0.2.0:
+ resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+ engines: {node: '>= 0.6'}
+
+ fresh@2.0.0:
+ resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
+ engines: {node: '>= 0.8'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ globals@13.24.0:
+ resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
+ engines: {node: '>=8'}
+
+ globals@14.0.0:
+ resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+ engines: {node: '>=18'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ hono@4.12.32:
+ resolution: {integrity: sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==}
+ engines: {node: '>=16.9.0'}
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
+ http-errors@2.0.1:
+ resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
+ engines: {node: '>= 0.8'}
+
+ https-proxy-agent@5.0.1:
+ resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
+ engines: {node: '>= 6'}
+
+ iconv-lite@0.4.24:
+ resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
+ engines: {node: '>=0.10.0'}
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
+ iconv-lite@0.7.3:
+ resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==}
+ engines: {node: '>=0.10.0'}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ ignore@7.0.6:
+ resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==}
+ engines: {node: '>= 4'}
+
+ image-size@0.5.5:
+ resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
+ engines: {node: '>=0.10.0'}
+ hasBin: true
+
+ import-fresh@3.3.1:
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
+ engines: {node: '>=6'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ip-address@10.3.1:
+ resolution: {integrity: sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==}
+ engines: {node: '>= 12'}
+
+ ipaddr.js@1.9.1:
+ resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+ engines: {node: '>= 0.10'}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-promise@4.0.0:
+ resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
+
+ is-what@3.14.1:
+ resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
+
+ is-what@4.1.16:
+ resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
+ engines: {node: '>=12.13'}
+
+ is-what@5.5.0:
+ resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
+ engines: {node: '>=18'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jose@6.2.4:
+ resolution: {integrity: sha512-N8acGzVsQy6M/fjFcxtysNc4Q379TcM5dM/qKkNtsHFji88yANnXTr7BLeP75iPnFwBfQzM/jg2BZ9+HZrHCZA==}
+
+ js-tokens@9.0.1:
+ resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+
+ js-yaml@4.3.0:
+ resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==}
+ hasBin: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json-schema-typed@8.0.2:
+ resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ less@4.5.1:
+ resolution: {integrity: sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ less@4.8.0:
+ resolution: {integrity: sha512-7Y7DJBMbsW29UGjOG6NGvxQEx71AaDcrryBwYCMaFwn0kj8FkSueKN9r9WexVOetKEhXh38kL++WJncfkEpS+g==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ local-pkg@1.2.1:
+ resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==}
+ engines: {node: '>=14'}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash-es@4.18.1:
+ resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ lodash@4.18.1:
+ resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ make-dir@2.1.0:
+ resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
+ engines: {node: '>=6'}
+
+ make-dir@5.1.0:
+ resolution: {integrity: sha512-IfpFq6UM39dUNiphpA6uDezNx/AvWyhwfICWPR3t1VspkgkMZrL+Rk1RbN1bx+aeNYwOrqGJgEgV3yotk+ZUVw==}
+ engines: {node: '>=18'}
+
+ make-error@1.3.6:
+ resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
+
+ marked-gfm-heading-id@4.1.4:
+ resolution: {integrity: sha512-CspnvVfHSkb/znqdPS4jUR8HtCjq3M/DnrsJCrfLBLvdrgbemmoINKpeWKQYkBiXAoBGejw0cV7xzqrPdup3WA==}
+ peerDependencies:
+ marked: '>=13 <19'
+
+ marked-highlight@2.2.4:
+ resolution: {integrity: sha512-PZxisNMJDduSjc0q6uvjsnqqHCXc9s0eyzxDO9sB1eNGJnd/H1/Fu+z6g/liC1dfJdFW4SftMwMlLvsBhUPrqQ==}
+ peerDependencies:
+ marked: '>=4 <19'
+
+ marked-mangle@1.1.13:
+ resolution: {integrity: sha512-phz1W/nYMr1T08Q7wqH2aj+PPiK85E69WQGfId+prvryfgjY/Idibx4YUvKaYMDV9rK1qo+/yC+Quu/3gdaBeA==}
+ peerDependencies:
+ marked: '>=4 <19'
+
+ marked@17.0.6:
+ resolution: {integrity: sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA==}
+ engines: {node: '>= 20'}
+ hasBin: true
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ media-typer@1.1.1:
+ resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==}
+ engines: {node: '>= 0.8'}
+
+ merge-descriptors@2.0.0:
+ resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
+ engines: {node: '>=18'}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-db@1.54.0:
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@3.0.2:
+ resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
+ engines: {node: '>=18'}
+
+ mime@1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimatch@3.1.5:
+ resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+
+ minimatch@9.0.9:
+ resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ mitt@2.1.0:
+ resolution: {integrity: sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==}
+
+ mitt@3.0.1:
+ resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+
+ mlly@1.8.2:
+ resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+
+ ms@2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.16:
+ resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ needle@2.9.1:
+ resolution: {integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==}
+ engines: {node: '>= 4.4.x'}
+ hasBin: true
+
+ needle@3.5.0:
+ resolution: {integrity: sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==}
+ engines: {node: '>= 4.4.x'}
+ hasBin: true
+
+ negotiator@1.0.0:
+ resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
+ engines: {node: '>= 0.6'}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-inspect@1.13.4:
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
+ engines: {node: '>= 0.4'}
+
+ on-finished@2.4.1:
+ resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
+ engines: {node: '>= 0.8'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ parse-node-version@1.0.1:
+ resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
+ engines: {node: '>= 0.10'}
+
+ parseurl@1.3.3:
+ resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
+ engines: {node: '>= 0.8'}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-to-regexp@8.4.2:
+ resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.5:
+ resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
+ engines: {node: '>=12'}
+
+ pify@4.0.1:
+ resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
+ engines: {node: '>=6'}
+
+ pinia@3.0.4:
+ resolution: {integrity: sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==}
+ peerDependencies:
+ typescript: '>=4.5.0'
+ vue: ^3.5.11
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ pkce-challenge@5.0.1:
+ resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
+ engines: {node: '>=16.20.0'}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ pkg-types@2.3.1:
+ resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==}
+
+ postcss-selector-parser@6.1.4:
+ resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==}
+ engines: {node: '>=4'}
+
+ postcss@8.5.23:
+ resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prismjs@1.30.0:
+ resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
+ engines: {node: '>=6'}
+
+ probe-image-size@7.3.0:
+ resolution: {integrity: sha512-7CaDeBwiAbh6ohXsvLbAZhO7wzsZAmaevfxe39qvCwRh8LyaZfDlBGGLU1CCTgrTLtCOdwBBhjOrIHaIIimHfQ==}
+
+ proxy-addr@2.0.7:
+ resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
+ engines: {node: '>= 0.10'}
+
+ proxy-from-env@2.1.0:
+ resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
+ engines: {node: '>=10'}
+
+ prr@1.0.1:
+ resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ qs@6.15.3:
+ resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==}
+ engines: {node: '>=0.6'}
+
+ quansync@0.2.11:
+ resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ range-parser@1.3.0:
+ resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==}
+ engines: {node: '>= 0.6'}
+
+ raw-body@3.0.2:
+ resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
+ engines: {node: '>= 0.10'}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rollup@4.62.3:
+ resolution: {integrity: sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ router@2.2.0:
+ resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
+ engines: {node: '>= 18'}
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ sax@1.6.1:
+ resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==}
+ engines: {node: '>=11.0.0'}
+
+ scule@1.3.0:
+ resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
+
+ semver@5.7.2:
+ resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
+ hasBin: true
+
+ semver@7.8.5:
+ resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ send@1.2.1:
+ resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
+ engines: {node: '>= 18'}
+
+ serve-static@2.2.1:
+ resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
+ engines: {node: '>= 18'}
+
+ setprototypeof@1.2.0:
+ resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ side-channel-list@1.0.1:
+ resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-map@1.0.1:
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-weakmap@1.0.2:
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
+ engines: {node: '>= 0.4'}
+
+ side-channel@1.1.1:
+ resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
+ engines: {node: '>= 0.4'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ speakingurl@14.0.1:
+ resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
+ engines: {node: '>=0.10.0'}
+
+ statuses@2.0.2:
+ resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
+ engines: {node: '>= 0.8'}
+
+ stream-parser@0.3.1:
+ resolution: {integrity: sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ strip-literal@3.1.0:
+ resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
+
+ superjson@2.2.6:
+ resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==}
+ engines: {node: '>=16'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ tdesign-icons-vue-next@0.4.7:
+ resolution: {integrity: sha512-0TRVH0L9O7vAMQ7j2vU/VYBMzS5FI+OVf7bWjwAVMmWXArsAyJI8mzpNWThZok96B6hsRY+2hK/NSOFZy8hMqA==}
+ peerDependencies:
+ vue: ^3.0.0
+
+ tdesign-mobile-vue@1.16.0:
+ resolution: {integrity: sha512-Msn9PRrOkJD22hGFqSS3l0gvoaXTB2a5CTyvzazzPTITJmkY4CnC7ySbOsGxlA2qT/HyL44v+JJYauzUycQ1Fg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ vue: ^3.2.6
+
+ terser@5.49.0:
+ resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ timi-tdesign-mobile@0.0.10:
+ resolution: {integrity: sha512-fv83++YkMkeKTkReR/2+RoaSacj6fv5JHJfJ1P3C4p/KmLn9XTe+3jHYlFEWjQdxbehz9BifX1L8rVHmgScP5g==}
+ engines: {node: '>=16.0.0'}
+
+ timi-web@0.0.24:
+ resolution: {integrity: sha512-qzcm72W9EE3BrYiUzc8a20J8xqxH17moEm/ovdijhRbIJtJUr81sslXFe2+OjNtx14meEIPJm3IfRooFzRswLg==}
+ engines: {node: '>=16.0.0'}
+
+ tinycolor2@1.6.0:
+ resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ toidentifier@1.0.1:
+ resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
+ engines: {node: '>=0.6'}
+
+ ts-api-utils@2.5.0:
+ resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
+ ts-custom-error@3.3.1:
+ resolution: {integrity: sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==}
+ engines: {node: '>=14.0.0'}
+
+ ts-node@10.9.2:
+ resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
+ hasBin: true
+ peerDependencies:
+ '@swc/core': '>=1.2.50'
+ '@swc/wasm': '>=1.2.50'
+ '@types/node': '*'
+ typescript: '>=2.7'
+ peerDependenciesMeta:
+ '@swc/core':
+ optional: true
+ '@swc/wasm':
+ optional: true
+
+ tslib@2.3.0:
+ resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+
+ type-is@2.1.0:
+ resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==}
+ engines: {node: '>= 18'}
+
+ typescript-eslint@8.65.0:
+ resolution: {integrity: sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ typescript@5.8.3:
+ resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ ufo@1.6.4:
+ resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
+
+ undici-types@7.18.2:
+ resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
+
+ unimport@4.2.0:
+ resolution: {integrity: sha512-mYVtA0nmzrysnYnyb3ALMbByJ+Maosee2+WyE0puXl+Xm2bUwPorPaaeZt0ETfuroPOtG8jj1g/qeFZ6buFnag==}
+ engines: {node: '>=18.12.0'}
+
+ unpipe@1.0.0:
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
+ engines: {node: '>= 0.8'}
+
+ unplugin-auto-import@19.3.0:
+ resolution: {integrity: sha512-iIi0u4Gq2uGkAOGqlPJOAMI8vocvjh1clGTfSK4SOrJKrt+tirrixo/FjgBwXQNNdS7ofcr7OxzmOb/RjWxeEQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@nuxt/kit': ^3.2.2
+ '@vueuse/core': '*'
+ peerDependenciesMeta:
+ '@nuxt/kit':
+ optional: true
+ '@vueuse/core':
+ optional: true
+
+ unplugin-utils@0.2.5:
+ resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==}
+ engines: {node: '>=18.12.0'}
+
+ unplugin-vue-components@28.8.0:
+ resolution: {integrity: sha512-2Q6ZongpoQzuXDK0ZsVzMoshH0MWZQ1pzVL538G7oIDKRTVzHjppBDS8aB99SADGHN3lpGU7frraCG6yWNoL5Q==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/parser': ^7.15.8
+ '@nuxt/kit': ^3.2.2 || ^4.0.0
+ vue: 2 || 3
+ peerDependenciesMeta:
+ '@babel/parser':
+ optional: true
+ '@nuxt/kit':
+ optional: true
+
+ unplugin@2.3.11:
+ resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==}
+ engines: {node: '>=18.12.0'}
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ uzip@0.20201231.0:
+ resolution: {integrity: sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==}
+
+ v8-compile-cache-lib@3.0.1:
+ resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+
+ validator@13.15.35:
+ resolution: {integrity: sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==}
+ engines: {node: '>= 0.10'}
+
+ vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+
+ vite@6.4.3:
+ resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vscode-uri@3.1.0:
+ resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-echarts@8.0.1:
+ resolution: {integrity: sha512-23rJTFLu1OUEGRWjJGmdGt8fP+8+ja1gVgzMYPIPaHWpXegcO1viIAaeu2H4QHESlVeHzUAHIxKXGrwjsyXAaA==}
+ peerDependencies:
+ echarts: ^6.0.0
+ vue: ^3.3.0
+
+ vue-eslint-parser@10.4.1:
+ resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+
+ vue-eslint-parser@9.4.3:
+ resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==}
+ engines: {node: ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '>=6.0.0'
+
+ vue-observe-visibility@2.0.0-alpha.1:
+ resolution: {integrity: sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==}
+ peerDependencies:
+ vue: ^3.0.0
+
+ vue-resize@2.0.0-alpha.1:
+ resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==}
+ peerDependencies:
+ vue: ^3.0.0
+
+ vue-router@4.5.0:
+ resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==}
+ peerDependencies:
+ vue: ^3.2.0
+
+ vue-router@4.5.1:
+ resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==}
+ peerDependencies:
+ vue: ^3.2.0
+
+ vue-tsc@2.2.12:
+ resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.0.0'
+
+ vue-virtual-scroller@2.0.0-beta.8:
+ resolution: {integrity: sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==}
+ peerDependencies:
+ vue: ^3.2.0
+
+ vue@3.5.40:
+ resolution: {integrity: sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ webpack-virtual-modules@0.6.2:
+ resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ xml-name-validator@4.0.0:
+ resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
+ engines: {node: '>=12'}
+
+ yn@3.1.1:
+ resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
+ engines: {node: '>=6'}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ zod-to-json-schema@3.25.2:
+ resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==}
+ peerDependencies:
+ zod: ^3.25.28 || ^4
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+ zrender@6.1.0:
+ resolution: {integrity: sha512-oEGMDB6pOP2S6OwRR4PdVv610zrjnA3Bh+JnSG12fYJlBKjtNAoEb5fSUoCOOINlH96I2fU38/A2UpRKs67xYQ==}
+
+snapshots:
+
+ '@babel/helper-string-parser@7.29.7': {}
+
+ '@babel/helper-validator-identifier@7.29.7': {}
+
+ '@babel/parser@7.29.7':
+ dependencies:
+ '@babel/types': 7.29.7
+
+ '@babel/runtime@7.29.7': {}
+
+ '@babel/types@7.29.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+
+ '@cspotcode/source-map-support@0.8.1':
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.9
+
+ '@esbuild/aix-ppc64@0.25.12':
+ optional: true
+
+ '@esbuild/android-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/android-arm@0.25.12':
+ optional: true
+
+ '@esbuild/android-x64@0.25.12':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/darwin-x64@0.25.12':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-arm@0.25.12':
+ optional: true
+
+ '@esbuild/linux-ia32@0.25.12':
+ optional: true
+
+ '@esbuild/linux-loong64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.25.12':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-s390x@0.25.12':
+ optional: true
+
+ '@esbuild/linux-x64@0.25.12':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/sunos-x64@0.25.12':
+ optional: true
+
+ '@esbuild/win32-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/win32-ia32@0.25.12':
+ optional: true
+
+ '@esbuild/win32-x64@0.25.12':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.10.1(eslint@9.26.0)':
+ dependencies:
+ eslint: 9.26.0
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.12.2': {}
+
+ '@eslint/config-array@0.20.1':
+ dependencies:
+ '@eslint/object-schema': 2.1.7
+ debug: 4.4.3
+ minimatch: 3.1.5
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/config-helpers@0.2.3': {}
+
+ '@eslint/core@0.13.0':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
+ '@eslint/eslintrc@3.3.6':
+ dependencies:
+ ajv: 6.15.0
+ debug: 4.4.3
+ espree: 10.4.0
+ globals: 14.0.0
+ ignore: 5.3.2
+ import-fresh: 3.3.1
+ js-yaml: 4.3.0
+ minimatch: 3.1.5
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/js@9.26.0': {}
+
+ '@eslint/object-schema@2.1.7': {}
+
+ '@eslint/plugin-kit@0.2.8':
+ dependencies:
+ '@eslint/core': 0.13.0
+ levn: 0.4.1
+
+ '@hono/node-server@1.19.15(hono@4.12.32)':
+ dependencies:
+ hono: 4.12.32
+
+ '@humanfs/core@0.19.2':
+ dependencies:
+ '@humanfs/types': 0.15.0
+
+ '@humanfs/node@0.16.8':
+ dependencies:
+ '@humanfs/core': 0.19.2
+ '@humanfs/types': 0.15.0
+ '@humanwhocodes/retry': 0.4.3
+
+ '@humanfs/types@0.15.0': {}
+
+ '@humanwhocodes/module-importer@1.0.1': {}
+
+ '@humanwhocodes/retry@0.4.3': {}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/source-map@0.3.11':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@jridgewell/trace-mapping@0.3.9':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)':
+ dependencies:
+ '@hono/node-server': 1.19.15(hono@4.12.32)
+ ajv: 8.20.0
+ ajv-formats: 3.0.1(ajv@8.20.0)
+ content-type: 1.0.5
+ cors: 2.8.6
+ cross-spawn: 7.0.6
+ eventsource: 3.0.7
+ eventsource-parser: 3.1.0
+ express: 5.2.1
+ express-rate-limit: 8.6.0(express@5.2.1)
+ hono: 4.12.32
+ jose: 6.2.4
+ json-schema-typed: 8.0.2
+ pkce-challenge: 5.0.1
+ raw-body: 3.0.2
+ zod: 3.25.76
+ zod-to-json-schema: 3.25.2(zod@3.25.76)
+ transitivePeerDependencies:
+ - supports-color
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.20.1
+
+ '@rollup/rollup-android-arm-eabi@4.62.3':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.62.3':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.62.3':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.3':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.3':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.62.3':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.62.3':
+ optional: true
+
+ '@tsconfig/node10@1.0.12': {}
+
+ '@tsconfig/node12@1.0.11': {}
+
+ '@tsconfig/node14@1.0.3': {}
+
+ '@tsconfig/node16@1.0.4': {}
+
+ '@tsconfig/node20@20.1.9': {}
+
+ '@types/esrecurse@4.3.1': {}
+
+ '@types/estree@1.0.9': {}
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/node@24.13.3':
+ dependencies:
+ undici-types: 7.18.2
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.26.0)(typescript@5.8.3))(eslint@9.26.0)(typescript@5.8.3)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.2
+ '@typescript-eslint/parser': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ '@typescript-eslint/scope-manager': 8.65.0
+ '@typescript-eslint/type-utils': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ '@typescript-eslint/utils': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ '@typescript-eslint/visitor-keys': 8.65.0
+ eslint: 9.26.0
+ ignore: 7.0.6
+ natural-compare: 1.4.0
+ ts-api-utils: 2.5.0(typescript@5.8.3)
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@8.65.0(eslint@9.26.0)(typescript@5.8.3)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.65.0
+ '@typescript-eslint/types': 8.65.0
+ '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.8.3)
+ '@typescript-eslint/visitor-keys': 8.65.0
+ debug: 4.4.3
+ eslint: 9.26.0
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/project-service@8.65.0(typescript@5.8.3)':
+ dependencies:
+ '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.8.3)
+ '@typescript-eslint/types': 8.65.0
+ debug: 4.4.3
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.65.0':
+ dependencies:
+ '@typescript-eslint/types': 8.65.0
+ '@typescript-eslint/visitor-keys': 8.65.0
+
+ '@typescript-eslint/tsconfig-utils@8.65.0(typescript@5.8.3)':
+ dependencies:
+ typescript: 5.8.3
+
+ '@typescript-eslint/type-utils@8.65.0(eslint@9.26.0)(typescript@5.8.3)':
+ dependencies:
+ '@typescript-eslint/types': 8.65.0
+ '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.8.3)
+ '@typescript-eslint/utils': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ debug: 4.4.3
+ eslint: 9.26.0
+ ts-api-utils: 2.5.0(typescript@5.8.3)
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@8.65.0': {}
+
+ '@typescript-eslint/typescript-estree@8.65.0(typescript@5.8.3)':
+ dependencies:
+ '@typescript-eslint/project-service': 8.65.0(typescript@5.8.3)
+ '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.8.3)
+ '@typescript-eslint/types': 8.65.0
+ '@typescript-eslint/visitor-keys': 8.65.0
+ debug: 4.4.3
+ minimatch: 10.2.5
+ semver: 7.8.5
+ tinyglobby: 0.2.17
+ ts-api-utils: 2.5.0(typescript@5.8.3)
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.65.0(eslint@9.26.0)(typescript@5.8.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.10.1(eslint@9.26.0)
+ '@typescript-eslint/scope-manager': 8.65.0
+ '@typescript-eslint/types': 8.65.0
+ '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.8.3)
+ eslint: 9.26.0
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/visitor-keys@8.65.0':
+ dependencies:
+ '@typescript-eslint/types': 8.65.0
+ eslint-visitor-keys: 5.0.1
+
+ '@use-gesture/core@10.3.1': {}
+
+ '@use-gesture/vanilla@10.3.1':
+ dependencies:
+ '@use-gesture/core': 10.3.1
+
+ '@vitejs/plugin-vue@5.2.4(vite@6.4.3(@types/node@24.13.3)(less@4.8.0)(terser@5.49.0))(vue@3.5.40(typescript@5.8.3))':
+ dependencies:
+ vite: 6.4.3(@types/node@24.13.3)(less@4.8.0)(terser@5.49.0)
+ vue: 3.5.40(typescript@5.8.3)
+
+ '@volar/language-core@2.4.15':
+ dependencies:
+ '@volar/source-map': 2.4.15
+
+ '@volar/source-map@2.4.15': {}
+
+ '@volar/typescript@2.4.15':
+ dependencies:
+ '@volar/language-core': 2.4.15
+ path-browserify: 1.0.1
+ vscode-uri: 3.1.0
+
+ '@vue/compiler-core@3.5.40':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@vue/shared': 3.5.40
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.40':
+ dependencies:
+ '@vue/compiler-core': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/compiler-sfc@3.5.40':
+ dependencies:
+ '@babel/parser': 7.29.7
+ '@vue/compiler-core': 3.5.40
+ '@vue/compiler-dom': 3.5.40
+ '@vue/compiler-ssr': 3.5.40
+ '@vue/shared': 3.5.40
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.23
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.40':
+ dependencies:
+ '@vue/compiler-dom': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/compiler-vue2@2.7.16':
+ dependencies:
+ de-indent: 1.0.2
+ he: 1.2.0
+
+ '@vue/devtools-api@6.6.4': {}
+
+ '@vue/devtools-api@7.7.10':
+ dependencies:
+ '@vue/devtools-kit': 7.7.10
+
+ '@vue/devtools-kit@7.7.10':
+ dependencies:
+ '@vue/devtools-shared': 7.7.10
+ birpc: 2.9.0
+ hookable: 5.5.3
+ mitt: 3.0.1
+ perfect-debounce: 1.0.0
+ speakingurl: 14.0.1
+ superjson: 2.2.6
+
+ '@vue/devtools-shared@7.7.10':
+ dependencies:
+ rfdc: 1.4.1
+
+ '@vue/eslint-config-typescript@14.9.0(eslint-plugin-vue@9.33.0(eslint@9.26.0))(eslint@9.26.0)(typescript@5.8.3)':
+ dependencies:
+ '@typescript-eslint/utils': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ eslint: 9.26.0
+ eslint-plugin-vue: 9.33.0(eslint@9.26.0)
+ fast-glob: 3.3.3
+ typescript-eslint: 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ vue-eslint-parser: 10.4.1(eslint@9.26.0)
+ optionalDependencies:
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@vue/language-core@2.2.12(typescript@5.8.3)':
+ dependencies:
+ '@volar/language-core': 2.4.15
+ '@vue/compiler-dom': 3.5.40
+ '@vue/compiler-vue2': 2.7.16
+ '@vue/shared': 3.5.40
+ alien-signals: 1.0.13
+ minimatch: 9.0.9
+ muggle-string: 0.4.1
+ path-browserify: 1.0.1
+ optionalDependencies:
+ typescript: 5.8.3
+
+ '@vue/reactivity@3.5.40':
+ dependencies:
+ '@vue/shared': 3.5.40
+
+ '@vue/runtime-core@3.5.40':
+ dependencies:
+ '@vue/reactivity': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/runtime-dom@3.5.40':
+ dependencies:
+ '@vue/reactivity': 3.5.40
+ '@vue/runtime-core': 3.5.40
+ '@vue/shared': 3.5.40
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.40':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.40
+ '@vue/runtime-dom': 3.5.40
+ '@vue/shared': 3.5.40
+
+ '@vue/shared@3.5.40': {}
+
+ '@vue/tsconfig@0.7.0(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3))':
+ optionalDependencies:
+ typescript: 5.8.3
+ vue: 3.5.40(typescript@5.8.3)
+
+ '@vueuse/core@10.7.0(vue@3.5.40(typescript@5.8.3))':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 10.7.0
+ '@vueuse/shared': 10.7.0(vue@3.5.40(typescript@5.8.3))
+ vue-demi: 0.14.10(vue@3.5.40(typescript@5.8.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/metadata@10.7.0': {}
+
+ '@vueuse/shared@10.7.0(vue@3.5.40(typescript@5.8.3))':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.40(typescript@5.8.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@zxing/browser@0.1.5(@zxing/library@0.21.3)':
+ dependencies:
+ '@zxing/library': 0.21.3
+ optionalDependencies:
+ '@zxing/text-encoding': 0.9.0
+
+ '@zxing/library@0.21.3':
+ dependencies:
+ ts-custom-error: 3.3.1
+ optionalDependencies:
+ '@zxing/text-encoding': 0.9.0
+
+ '@zxing/text-encoding@0.9.0':
+ optional: true
+
+ accepts@2.0.0:
+ dependencies:
+ mime-types: 3.0.2
+ negotiator: 1.0.0
+
+ acorn-jsx@5.3.2(acorn@8.17.0):
+ dependencies:
+ acorn: 8.17.0
+
+ acorn-walk@8.3.5:
+ dependencies:
+ acorn: 8.17.0
+
+ acorn@8.17.0: {}
+
+ agent-base@6.0.2:
+ dependencies:
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ ajv-formats@3.0.1(ajv@8.20.0):
+ optionalDependencies:
+ ajv: 8.20.0
+
+ ajv@6.15.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ajv@8.20.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.4
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ alien-signals@1.0.13: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.2
+
+ arg@4.1.3: {}
+
+ argparse@2.0.1: {}
+
+ asynckit@0.4.0: {}
+
+ axios@1.15.0:
+ dependencies:
+ follow-redirects: 1.16.0
+ form-data: 4.0.6
+ proxy-from-env: 2.1.0
+ transitivePeerDependencies:
+ - debug
+
+ axios@1.18.0:
+ dependencies:
+ follow-redirects: 1.16.0
+ form-data: 4.0.6
+ https-proxy-agent: 5.0.1
+ proxy-from-env: 2.1.0
+ transitivePeerDependencies:
+ - debug
+ - supports-color
+
+ balanced-match@1.0.2: {}
+
+ balanced-match@4.0.4: {}
+
+ binary-extensions@2.3.0: {}
+
+ birpc@2.9.0: {}
+
+ body-parser@2.3.0:
+ dependencies:
+ bytes: 3.1.2
+ content-type: 2.0.0
+ debug: 4.4.3
+ http-errors: 2.0.1
+ iconv-lite: 0.7.3
+ on-finished: 2.4.1
+ qs: 6.15.3
+ raw-body: 3.0.2
+ type-is: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ boolbase@1.0.0: {}
+
+ brace-expansion@1.1.16:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ brace-expansion@2.1.2:
+ dependencies:
+ balanced-match: 1.0.2
+
+ brace-expansion@5.0.8:
+ dependencies:
+ balanced-match: 4.0.4
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browser-image-compression@2.0.2:
+ dependencies:
+ uzip: 0.20201231.0
+
+ buffer-from@1.1.2: {}
+
+ bytes@3.1.2: {}
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bound@1.0.4:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ get-intrinsic: 1.3.0
+
+ callsites@3.1.0: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ commander@2.20.3: {}
+
+ concat-map@0.0.1: {}
+
+ confbox@0.1.8: {}
+
+ confbox@0.2.4: {}
+
+ content-disposition@1.1.0: {}
+
+ content-type@1.0.5: {}
+
+ content-type@2.0.0: {}
+
+ cookie-signature@1.2.2: {}
+
+ cookie@0.7.2: {}
+
+ copy-anything@2.0.6:
+ dependencies:
+ is-what: 3.14.1
+
+ copy-anything@3.0.5:
+ dependencies:
+ is-what: 4.1.16
+
+ copy-anything@4.0.5:
+ dependencies:
+ is-what: 5.5.0
+
+ cors@2.8.6:
+ dependencies:
+ object-assign: 4.1.1
+ vary: 1.1.2
+
+ create-require@1.1.1: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ cssesc@3.0.0: {}
+
+ csstype@3.2.3: {}
+
+ dayjs@1.11.21: {}
+
+ de-indent@1.0.2: {}
+
+ debug@2.6.9:
+ dependencies:
+ ms: 2.0.0
+ optional: true
+
+ debug@3.2.7:
+ dependencies:
+ ms: 2.1.3
+ optional: true
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ deep-is@0.1.4: {}
+
+ delayed-stream@1.0.0: {}
+
+ depd@2.0.0: {}
+
+ diff@4.0.4: {}
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ echarts@6.1.0:
+ dependencies:
+ tslib: 2.3.0
+ zrender: 6.1.0
+
+ ee-first@1.1.1: {}
+
+ encodeurl@2.0.0: {}
+
+ entities@7.0.1: {}
+
+ errno@0.1.8:
+ dependencies:
+ prr: 1.0.1
+ optional: true
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-object-atoms@1.1.2:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.4
+
+ esbuild@0.25.12:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.12
+ '@esbuild/android-arm': 0.25.12
+ '@esbuild/android-arm64': 0.25.12
+ '@esbuild/android-x64': 0.25.12
+ '@esbuild/darwin-arm64': 0.25.12
+ '@esbuild/darwin-x64': 0.25.12
+ '@esbuild/freebsd-arm64': 0.25.12
+ '@esbuild/freebsd-x64': 0.25.12
+ '@esbuild/linux-arm': 0.25.12
+ '@esbuild/linux-arm64': 0.25.12
+ '@esbuild/linux-ia32': 0.25.12
+ '@esbuild/linux-loong64': 0.25.12
+ '@esbuild/linux-mips64el': 0.25.12
+ '@esbuild/linux-ppc64': 0.25.12
+ '@esbuild/linux-riscv64': 0.25.12
+ '@esbuild/linux-s390x': 0.25.12
+ '@esbuild/linux-x64': 0.25.12
+ '@esbuild/netbsd-arm64': 0.25.12
+ '@esbuild/netbsd-x64': 0.25.12
+ '@esbuild/openbsd-arm64': 0.25.12
+ '@esbuild/openbsd-x64': 0.25.12
+ '@esbuild/openharmony-arm64': 0.25.12
+ '@esbuild/sunos-x64': 0.25.12
+ '@esbuild/win32-arm64': 0.25.12
+ '@esbuild/win32-ia32': 0.25.12
+ '@esbuild/win32-x64': 0.25.12
+
+ escape-html@1.0.3: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ eslint-plugin-vue@9.33.0(eslint@9.26.0):
+ dependencies:
+ '@eslint-community/eslint-utils': 4.10.1(eslint@9.26.0)
+ eslint: 9.26.0
+ globals: 13.24.0
+ natural-compare: 1.4.0
+ nth-check: 2.1.1
+ postcss-selector-parser: 6.1.4
+ semver: 7.8.5
+ vue-eslint-parser: 9.4.3(eslint@9.26.0)
+ xml-name-validator: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-scope@7.2.2:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-scope@8.4.0:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-scope@9.1.2:
+ dependencies:
+ '@types/esrecurse': 4.3.1
+ '@types/estree': 1.0.9
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint-visitor-keys@4.2.1: {}
+
+ eslint-visitor-keys@5.0.1: {}
+
+ eslint@9.26.0:
+ dependencies:
+ '@eslint-community/eslint-utils': 4.10.1(eslint@9.26.0)
+ '@eslint-community/regexpp': 4.12.2
+ '@eslint/config-array': 0.20.1
+ '@eslint/config-helpers': 0.2.3
+ '@eslint/core': 0.13.0
+ '@eslint/eslintrc': 3.3.6
+ '@eslint/js': 9.26.0
+ '@eslint/plugin-kit': 0.2.8
+ '@humanfs/node': 0.16.8
+ '@humanwhocodes/module-importer': 1.0.1
+ '@humanwhocodes/retry': 0.4.3
+ '@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76)
+ '@types/estree': 1.0.9
+ '@types/json-schema': 7.0.15
+ ajv: 6.15.0
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.3
+ escape-string-regexp: 4.0.0
+ eslint-scope: 8.4.0
+ eslint-visitor-keys: 4.2.1
+ espree: 10.4.0
+ esquery: 1.7.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 8.0.0
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ json-stable-stringify-without-jsonify: 1.0.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.5
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ zod: 3.25.76
+ transitivePeerDependencies:
+ - '@cfworker/json-schema'
+ - supports-color
+
+ espree@10.4.0:
+ dependencies:
+ acorn: 8.17.0
+ acorn-jsx: 5.3.2(acorn@8.17.0)
+ eslint-visitor-keys: 4.2.1
+
+ espree@11.2.0:
+ dependencies:
+ acorn: 8.17.0
+ acorn-jsx: 5.3.2(acorn@8.17.0)
+ eslint-visitor-keys: 5.0.1
+
+ espree@9.6.1:
+ dependencies:
+ acorn: 8.17.0
+ acorn-jsx: 5.3.2(acorn@8.17.0)
+ eslint-visitor-keys: 3.4.3
+
+ esquery@1.7.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@5.3.0: {}
+
+ estree-walker@2.0.2: {}
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+
+ esutils@2.0.3: {}
+
+ etag@1.8.1: {}
+
+ eventsource-parser@3.1.0: {}
+
+ eventsource@3.0.7:
+ dependencies:
+ eventsource-parser: 3.1.0
+
+ express-rate-limit@8.6.0(express@5.2.1):
+ dependencies:
+ debug: 4.4.3
+ express: 5.2.1
+ ip-address: 10.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ express@5.2.1:
+ dependencies:
+ accepts: 2.0.0
+ body-parser: 2.3.0
+ content-disposition: 1.1.0
+ content-type: 1.0.5
+ cookie: 0.7.2
+ cookie-signature: 1.2.2
+ debug: 4.4.3
+ depd: 2.0.0
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ finalhandler: 2.1.1
+ fresh: 2.0.0
+ http-errors: 2.0.1
+ merge-descriptors: 2.0.0
+ mime-types: 3.0.2
+ on-finished: 2.4.1
+ once: 1.4.0
+ parseurl: 1.3.3
+ proxy-addr: 2.0.7
+ qs: 6.15.3
+ range-parser: 1.3.0
+ router: 2.2.0
+ send: 1.2.1
+ serve-static: 2.2.1
+ statuses: 2.0.2
+ type-is: 2.1.0
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ exsolve@1.1.0: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fast-uri@3.1.4: {}
+
+ fastq@1.20.1:
+ dependencies:
+ reusify: 1.1.0
+
+ fdir@6.5.0(picomatch@4.0.5):
+ optionalDependencies:
+ picomatch: 4.0.5
+
+ file-entry-cache@8.0.0:
+ dependencies:
+ flat-cache: 4.0.1
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ finalhandler@2.1.1:
+ dependencies:
+ debug: 4.4.3
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ statuses: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ flat-cache@4.0.1:
+ dependencies:
+ flatted: 3.4.3
+ keyv: 4.5.4
+
+ flatted@3.4.3: {}
+
+ follow-redirects@1.16.0: {}
+
+ form-data@4.0.6:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.4
+ mime-types: 2.1.35
+
+ forwarded@0.2.0: {}
+
+ fresh@2.0.0: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.4
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.2
+
+ github-slugger@2.0.0: {}
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ globals@13.24.0:
+ dependencies:
+ type-fest: 0.20.2
+
+ globals@14.0.0: {}
+
+ gopd@1.2.0: {}
+
+ graceful-fs@4.2.11:
+ optional: true
+
+ has-flag@4.0.0: {}
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
+ he@1.2.0: {}
+
+ hono@4.12.32: {}
+
+ hookable@5.5.3: {}
+
+ http-errors@2.0.1:
+ dependencies:
+ depd: 2.0.0
+ inherits: 2.0.4
+ setprototypeof: 1.2.0
+ statuses: 2.0.2
+ toidentifier: 1.0.1
+
+ https-proxy-agent@5.0.1:
+ dependencies:
+ agent-base: 6.0.2
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ iconv-lite@0.4.24:
+ dependencies:
+ safer-buffer: 2.1.2
+ optional: true
+
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+ optional: true
+
+ iconv-lite@0.7.3:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ ignore@5.3.2: {}
+
+ ignore@7.0.6: {}
+
+ image-size@0.5.5:
+ optional: true
+
+ import-fresh@3.3.1:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ imurmurhash@0.1.4: {}
+
+ inherits@2.0.4: {}
+
+ ip-address@10.3.1: {}
+
+ ipaddr.js@1.9.1: {}
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-extglob@2.1.1: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ is-promise@4.0.0: {}
+
+ is-what@3.14.1: {}
+
+ is-what@4.1.16: {}
+
+ is-what@5.5.0: {}
+
+ isexe@2.0.0: {}
+
+ jose@6.2.4: {}
+
+ js-tokens@9.0.1: {}
+
+ js-yaml@4.3.0:
+ dependencies:
+ argparse: 2.0.1
+
+ json-buffer@3.0.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ json-schema-typed@8.0.2: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ keyv@4.5.4:
+ dependencies:
+ json-buffer: 3.0.1
+
+ less@4.5.1:
+ dependencies:
+ copy-anything: 2.0.6
+ parse-node-version: 1.0.1
+ tslib: 2.8.1
+ optionalDependencies:
+ errno: 0.1.8
+ graceful-fs: 4.2.11
+ image-size: 0.5.5
+ make-dir: 2.1.0
+ mime: 1.6.0
+ needle: 3.5.0
+ source-map: 0.6.1
+
+ less@4.8.0:
+ dependencies:
+ copy-anything: 3.0.5
+ parse-node-version: 1.0.1
+ optionalDependencies:
+ errno: 0.1.8
+ graceful-fs: 4.2.11
+ make-dir: 5.1.0
+ mime: 1.6.0
+ needle: 3.5.0
+ probe-image-size: 7.3.0
+ source-map: 0.6.1
+ transitivePeerDependencies:
+ - supports-color
+
+ levn@0.4.1:
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ local-pkg@1.2.1:
+ dependencies:
+ mlly: 1.8.2
+ pkg-types: 2.3.1
+ quansync: 0.2.11
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ lodash-es@4.18.1: {}
+
+ lodash.merge@4.6.2: {}
+
+ lodash@4.18.1: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ make-dir@2.1.0:
+ dependencies:
+ pify: 4.0.1
+ semver: 5.7.2
+ optional: true
+
+ make-dir@5.1.0:
+ optional: true
+
+ make-error@1.3.6: {}
+
+ marked-gfm-heading-id@4.1.4(marked@17.0.6):
+ dependencies:
+ github-slugger: 2.0.0
+ marked: 17.0.6
+
+ marked-highlight@2.2.4(marked@17.0.6):
+ dependencies:
+ marked: 17.0.6
+
+ marked-mangle@1.1.13(marked@17.0.6):
+ dependencies:
+ marked: 17.0.6
+
+ marked@17.0.6: {}
+
+ math-intrinsics@1.1.0: {}
+
+ media-typer@1.1.1: {}
+
+ merge-descriptors@2.0.0: {}
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.2
+
+ mime-db@1.52.0: {}
+
+ mime-db@1.54.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ mime-types@3.0.2:
+ dependencies:
+ mime-db: 1.54.0
+
+ mime@1.6.0:
+ optional: true
+
+ minimatch@10.2.5:
+ dependencies:
+ brace-expansion: 5.0.8
+
+ minimatch@3.1.5:
+ dependencies:
+ brace-expansion: 1.1.16
+
+ minimatch@9.0.9:
+ dependencies:
+ brace-expansion: 2.1.2
+
+ mitt@2.1.0: {}
+
+ mitt@3.0.1: {}
+
+ mlly@1.8.2:
+ dependencies:
+ acorn: 8.17.0
+ pathe: 2.0.3
+ pkg-types: 1.3.1
+ ufo: 1.6.4
+
+ ms@2.0.0:
+ optional: true
+
+ ms@2.1.3: {}
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.16: {}
+
+ natural-compare@1.4.0: {}
+
+ needle@2.9.1:
+ dependencies:
+ debug: 3.2.7
+ iconv-lite: 0.4.24
+ sax: 1.6.1
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ needle@3.5.0:
+ dependencies:
+ iconv-lite: 0.6.3
+ sax: 1.6.1
+ optional: true
+
+ negotiator@1.0.0: {}
+
+ normalize-path@3.0.0: {}
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ object-assign@4.1.1: {}
+
+ object-inspect@1.13.4: {}
+
+ on-finished@2.4.1:
+ dependencies:
+ ee-first: 1.1.1
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ optionator@0.9.4:
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ parse-node-version@1.0.1: {}
+
+ parseurl@1.3.3: {}
+
+ path-browserify@1.0.1: {}
+
+ path-exists@4.0.0: {}
+
+ path-key@3.1.1: {}
+
+ path-to-regexp@8.4.2: {}
+
+ pathe@2.0.3: {}
+
+ perfect-debounce@1.0.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.2: {}
+
+ picomatch@4.0.5: {}
+
+ pify@4.0.1:
+ optional: true
+
+ pinia@3.0.4(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ '@vue/devtools-api': 7.7.10
+ vue: 3.5.40(typescript@5.8.3)
+ optionalDependencies:
+ typescript: 5.8.3
+
+ pkce-challenge@5.0.1: {}
+
+ pkg-types@1.3.1:
+ dependencies:
+ confbox: 0.1.8
+ mlly: 1.8.2
+ pathe: 2.0.3
+
+ pkg-types@2.3.1:
+ dependencies:
+ confbox: 0.2.4
+ exsolve: 1.1.0
+ pathe: 2.0.3
+
+ postcss-selector-parser@6.1.4:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss@8.5.23:
+ dependencies:
+ nanoid: 3.3.16
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prelude-ls@1.2.1: {}
+
+ prismjs@1.30.0: {}
+
+ probe-image-size@7.3.0:
+ dependencies:
+ lodash.merge: 4.6.2
+ needle: 2.9.1
+ stream-parser: 0.3.1
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ proxy-addr@2.0.7:
+ dependencies:
+ forwarded: 0.2.0
+ ipaddr.js: 1.9.1
+
+ proxy-from-env@2.1.0: {}
+
+ prr@1.0.1:
+ optional: true
+
+ punycode@2.3.1: {}
+
+ qs@6.15.3:
+ dependencies:
+ es-define-property: 1.0.1
+ side-channel: 1.1.1
+
+ quansync@0.2.11: {}
+
+ queue-microtask@1.2.3: {}
+
+ range-parser@1.3.0: {}
+
+ raw-body@3.0.2:
+ dependencies:
+ bytes: 3.1.2
+ http-errors: 2.0.1
+ iconv-lite: 0.7.3
+ unpipe: 1.0.0
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.2
+
+ require-from-string@2.0.2: {}
+
+ resolve-from@4.0.0: {}
+
+ reusify@1.1.0: {}
+
+ rfdc@1.4.1: {}
+
+ rollup@4.62.3:
+ dependencies:
+ '@types/estree': 1.0.9
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.62.3
+ '@rollup/rollup-android-arm64': 4.62.3
+ '@rollup/rollup-darwin-arm64': 4.62.3
+ '@rollup/rollup-darwin-x64': 4.62.3
+ '@rollup/rollup-freebsd-arm64': 4.62.3
+ '@rollup/rollup-freebsd-x64': 4.62.3
+ '@rollup/rollup-linux-arm-gnueabihf': 4.62.3
+ '@rollup/rollup-linux-arm-musleabihf': 4.62.3
+ '@rollup/rollup-linux-arm64-gnu': 4.62.3
+ '@rollup/rollup-linux-arm64-musl': 4.62.3
+ '@rollup/rollup-linux-loong64-gnu': 4.62.3
+ '@rollup/rollup-linux-loong64-musl': 4.62.3
+ '@rollup/rollup-linux-ppc64-gnu': 4.62.3
+ '@rollup/rollup-linux-ppc64-musl': 4.62.3
+ '@rollup/rollup-linux-riscv64-gnu': 4.62.3
+ '@rollup/rollup-linux-riscv64-musl': 4.62.3
+ '@rollup/rollup-linux-s390x-gnu': 4.62.3
+ '@rollup/rollup-linux-x64-gnu': 4.62.3
+ '@rollup/rollup-linux-x64-musl': 4.62.3
+ '@rollup/rollup-openbsd-x64': 4.62.3
+ '@rollup/rollup-openharmony-arm64': 4.62.3
+ '@rollup/rollup-win32-arm64-msvc': 4.62.3
+ '@rollup/rollup-win32-ia32-msvc': 4.62.3
+ '@rollup/rollup-win32-x64-gnu': 4.62.3
+ '@rollup/rollup-win32-x64-msvc': 4.62.3
+ fsevents: 2.3.3
+
+ router@2.2.0:
+ dependencies:
+ debug: 4.4.3
+ depd: 2.0.0
+ is-promise: 4.0.0
+ parseurl: 1.3.3
+ path-to-regexp: 8.4.2
+ transitivePeerDependencies:
+ - supports-color
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ safer-buffer@2.1.2: {}
+
+ sax@1.6.1:
+ optional: true
+
+ scule@1.3.0: {}
+
+ semver@5.7.2:
+ optional: true
+
+ semver@7.8.5: {}
+
+ send@1.2.1:
+ dependencies:
+ debug: 4.4.3
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ fresh: 2.0.0
+ http-errors: 2.0.1
+ mime-types: 3.0.2
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: 1.3.0
+ statuses: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ serve-static@2.2.1:
+ dependencies:
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 1.2.1
+ transitivePeerDependencies:
+ - supports-color
+
+ setprototypeof@1.2.0: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ side-channel-list@1.0.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-map@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-weakmap@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-map: 1.0.1
+
+ side-channel@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-list: 1.0.1
+ side-channel-map: 1.0.1
+ side-channel-weakmap: 1.0.2
+
+ source-map-js@1.2.1: {}
+
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.6.1: {}
+
+ speakingurl@14.0.1: {}
+
+ statuses@2.0.2: {}
+
+ stream-parser@0.3.1:
+ dependencies:
+ debug: 2.6.9
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ strip-json-comments@3.1.1: {}
+
+ strip-literal@3.1.0:
+ dependencies:
+ js-tokens: 9.0.1
+
+ superjson@2.2.6:
+ dependencies:
+ copy-anything: 4.0.5
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ tdesign-icons-vue-next@0.4.7(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ '@babel/runtime': 7.29.7
+ vue: 3.5.40(typescript@5.8.3)
+
+ tdesign-mobile-vue@1.16.0(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ '@babel/runtime': 7.29.7
+ '@use-gesture/vanilla': 10.3.1
+ '@vueuse/core': 10.7.0(vue@3.5.40(typescript@5.8.3))
+ dayjs: 1.11.21
+ lodash-es: 4.18.1
+ tdesign-icons-vue-next: 0.4.7(vue@3.5.40(typescript@5.8.3))
+ tinycolor2: 1.6.0
+ validator: 13.15.35
+ vue: 3.5.40(typescript@5.8.3)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+
+ terser@5.49.0:
+ dependencies:
+ '@jridgewell/source-map': 0.3.11
+ acorn: 8.17.0
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
+ timi-tdesign-mobile@0.0.10(typescript@5.8.3):
+ dependencies:
+ vue: 3.5.40(typescript@5.8.3)
+ vue-router: 4.5.0(vue@3.5.40(typescript@5.8.3))
+ transitivePeerDependencies:
+ - typescript
+
+ timi-web@0.0.24(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ axios: 1.18.0
+ less: 4.5.1
+ marked: 17.0.6
+ marked-gfm-heading-id: 4.1.4(marked@17.0.6)
+ marked-highlight: 2.2.4(marked@17.0.6)
+ marked-mangle: 1.1.13(marked@17.0.6)
+ pinia: 3.0.4(typescript@5.8.3)(vue@3.5.40(typescript@5.8.3))
+ prismjs: 1.30.0
+ terser: 5.49.0
+ transitivePeerDependencies:
+ - debug
+ - supports-color
+ - typescript
+ - vue
+
+ tinycolor2@1.6.0: {}
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.5)
+ picomatch: 4.0.5
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ toidentifier@1.0.1: {}
+
+ ts-api-utils@2.5.0(typescript@5.8.3):
+ dependencies:
+ typescript: 5.8.3
+
+ ts-custom-error@3.3.1: {}
+
+ ts-node@10.9.2(@types/node@24.13.3)(typescript@5.8.3):
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ '@tsconfig/node10': 1.0.12
+ '@tsconfig/node12': 1.0.11
+ '@tsconfig/node14': 1.0.3
+ '@tsconfig/node16': 1.0.4
+ '@types/node': 24.13.3
+ acorn: 8.17.0
+ acorn-walk: 8.3.5
+ arg: 4.1.3
+ create-require: 1.1.1
+ diff: 4.0.4
+ make-error: 1.3.6
+ typescript: 5.8.3
+ v8-compile-cache-lib: 3.0.1
+ yn: 3.1.1
+
+ tslib@2.3.0: {}
+
+ tslib@2.8.1: {}
+
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
+
+ type-fest@0.20.2: {}
+
+ type-is@2.1.0:
+ dependencies:
+ content-type: 2.0.0
+ media-typer: 1.1.1
+ mime-types: 3.0.2
+
+ typescript-eslint@8.65.0(eslint@9.26.0)(typescript@5.8.3):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.26.0)(typescript@5.8.3))(eslint@9.26.0)(typescript@5.8.3)
+ '@typescript-eslint/parser': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.8.3)
+ '@typescript-eslint/utils': 8.65.0(eslint@9.26.0)(typescript@5.8.3)
+ eslint: 9.26.0
+ typescript: 5.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ typescript@5.8.3: {}
+
+ ufo@1.6.4: {}
+
+ undici-types@7.18.2: {}
+
+ unimport@4.2.0:
+ dependencies:
+ acorn: 8.17.0
+ escape-string-regexp: 5.0.0
+ estree-walker: 3.0.3
+ local-pkg: 1.2.1
+ magic-string: 0.30.21
+ mlly: 1.8.2
+ pathe: 2.0.3
+ picomatch: 4.0.5
+ pkg-types: 2.3.1
+ scule: 1.3.0
+ strip-literal: 3.1.0
+ tinyglobby: 0.2.17
+ unplugin: 2.3.11
+ unplugin-utils: 0.2.5
+
+ unpipe@1.0.0: {}
+
+ unplugin-auto-import@19.3.0(@vueuse/core@10.7.0(vue@3.5.40(typescript@5.8.3))):
+ dependencies:
+ local-pkg: 1.2.1
+ magic-string: 0.30.21
+ picomatch: 4.0.5
+ unimport: 4.2.0
+ unplugin: 2.3.11
+ unplugin-utils: 0.2.5
+ optionalDependencies:
+ '@vueuse/core': 10.7.0(vue@3.5.40(typescript@5.8.3))
+
+ unplugin-utils@0.2.5:
+ dependencies:
+ pathe: 2.0.3
+ picomatch: 4.0.5
+
+ unplugin-vue-components@28.8.0(@babel/parser@7.29.7)(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ chokidar: 3.6.0
+ debug: 4.4.3
+ local-pkg: 1.2.1
+ magic-string: 0.30.21
+ mlly: 1.8.2
+ tinyglobby: 0.2.17
+ unplugin: 2.3.11
+ unplugin-utils: 0.2.5
+ vue: 3.5.40(typescript@5.8.3)
+ optionalDependencies:
+ '@babel/parser': 7.29.7
+ transitivePeerDependencies:
+ - supports-color
+
+ unplugin@2.3.11:
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ acorn: 8.17.0
+ picomatch: 4.0.5
+ webpack-virtual-modules: 0.6.2
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ util-deprecate@1.0.2: {}
+
+ uzip@0.20201231.0: {}
+
+ v8-compile-cache-lib@3.0.1: {}
+
+ validator@13.15.35: {}
+
+ vary@1.1.2: {}
+
+ vite@6.4.3(@types/node@24.13.3)(less@4.8.0)(terser@5.49.0):
+ dependencies:
+ esbuild: 0.25.12
+ fdir: 6.5.0(picomatch@4.0.5)
+ picomatch: 4.0.5
+ postcss: 8.5.23
+ rollup: 4.62.3
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 24.13.3
+ fsevents: 2.3.3
+ less: 4.8.0
+ terser: 5.49.0
+
+ vscode-uri@3.1.0: {}
+
+ vue-demi@0.14.10(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ vue: 3.5.40(typescript@5.8.3)
+
+ vue-echarts@8.0.1(echarts@6.1.0)(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ echarts: 6.1.0
+ vue: 3.5.40(typescript@5.8.3)
+
+ vue-eslint-parser@10.4.1(eslint@9.26.0):
+ dependencies:
+ debug: 4.4.3
+ eslint: 9.26.0
+ eslint-scope: 9.1.2
+ eslint-visitor-keys: 5.0.1
+ espree: 11.2.0
+ esquery: 1.7.0
+ semver: 7.8.5
+ transitivePeerDependencies:
+ - supports-color
+
+ vue-eslint-parser@9.4.3(eslint@9.26.0):
+ dependencies:
+ debug: 4.4.3
+ eslint: 9.26.0
+ eslint-scope: 7.2.2
+ eslint-visitor-keys: 3.4.3
+ espree: 9.6.1
+ esquery: 1.7.0
+ lodash: 4.18.1
+ semver: 7.8.5
+ transitivePeerDependencies:
+ - supports-color
+
+ vue-observe-visibility@2.0.0-alpha.1(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ vue: 3.5.40(typescript@5.8.3)
+
+ vue-resize@2.0.0-alpha.1(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ vue: 3.5.40(typescript@5.8.3)
+
+ vue-router@4.5.0(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.40(typescript@5.8.3)
+
+ vue-router@4.5.1(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.40(typescript@5.8.3)
+
+ vue-tsc@2.2.12(typescript@5.8.3):
+ dependencies:
+ '@volar/typescript': 2.4.15
+ '@vue/language-core': 2.2.12(typescript@5.8.3)
+ typescript: 5.8.3
+
+ vue-virtual-scroller@2.0.0-beta.8(vue@3.5.40(typescript@5.8.3)):
+ dependencies:
+ mitt: 2.1.0
+ vue: 3.5.40(typescript@5.8.3)
+ vue-observe-visibility: 2.0.0-alpha.1(vue@3.5.40(typescript@5.8.3))
+ vue-resize: 2.0.0-alpha.1(vue@3.5.40(typescript@5.8.3))
+
+ vue@3.5.40(typescript@5.8.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.40
+ '@vue/compiler-sfc': 3.5.40
+ '@vue/runtime-dom': 3.5.40
+ '@vue/server-renderer': 3.5.40
+ '@vue/shared': 3.5.40
+ optionalDependencies:
+ typescript: 5.8.3
+
+ webpack-virtual-modules@0.6.2: {}
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ word-wrap@1.2.5: {}
+
+ wrappy@1.0.2: {}
+
+ xml-name-validator@4.0.0: {}
+
+ yn@3.1.1: {}
+
+ yocto-queue@0.1.0: {}
+
+ zod-to-json-schema@3.25.2(zod@3.25.76):
+ dependencies:
+ zod: 3.25.76
+
+ zod@3.25.76: {}
+
+ zrender@6.1.0:
+ dependencies:
+ tslib: 2.3.0
diff --git a/public/icons/icon-192.png b/public/icons/icon-192.png
new file mode 100644
index 0000000..76ecc99
Binary files /dev/null and b/public/icons/icon-192.png differ
diff --git a/public/icons/icon-512.png b/public/icons/icon-512.png
new file mode 100644
index 0000000..0ee7cce
Binary files /dev/null and b/public/icons/icon-512.png differ
diff --git a/public/icons/icon-maskable-512.png b/public/icons/icon-maskable-512.png
new file mode 100644
index 0000000..ed07f1c
Binary files /dev/null and b/public/icons/icon-maskable-512.png differ
diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest
new file mode 100644
index 0000000..16cdf94
--- /dev/null
+++ b/public/manifest.webmanifest
@@ -0,0 +1,27 @@
+{
+ "name": "Gao Customer H5",
+ "short_name": "Gao H5",
+ "display": "standalone",
+ "background_color": "#ffffff",
+ "theme_color": "#ffffff",
+ "start_url": "/",
+ "scope": "/",
+ "icons": [
+ {
+ "src": "/icons/icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "/icons/icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ },
+ {
+ "src": "/icons/icon-maskable-512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ]
+}
diff --git a/src/Root.vue b/src/Root.vue
new file mode 100644
index 0000000..92f3bdf
--- /dev/null
+++ b/src/Root.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/src/api/CustomerAPI.ts b/src/api/CustomerAPI.ts
new file mode 100644
index 0000000..88b77d8
--- /dev/null
+++ b/src/api/CustomerAPI.ts
@@ -0,0 +1,107 @@
+import { axios, type Page, type PageResult } from "timi-web";
+import type { Customer, CustomerDailyStatView, CustomerGenderStatView, CustomerInviteUpdateReq, CustomerSearchReq, CustomerTrendStatReq, QuickRegisterReq } from "@/types/Customer";
+import type { RegistrationEventRecord } from "@/types/RegistrationEventRecord";
+
+const BASE_URI = "/gao/customer";
+
+async function list(req: Page): Promise> {
+ return await axios.post(`${BASE_URI}/list`, req);
+}
+
+async function search(req: CustomerSearchReq): Promise {
+ return await axios.post(`${BASE_URI}/search`, req);
+}
+
+async function searchPage(req: Page): Promise> {
+ return await axios.post(`${BASE_URI}/search/page`, req);
+}
+
+async function exportExcel(req: CustomerSearchReq): Promise {
+ return await axios.post(`${BASE_URI}/export`, req, {
+ responseType: "blob"
+ });
+}
+
+async function detail(id: string): Promise {
+ return await axios.post(`${BASE_URI}/detail`, undefined, {
+ params: { id }
+ });
+}
+
+async function detailByCode(code: string): Promise {
+ return await axios.post(`${BASE_URI}/detail/code`, undefined, {
+ params: { code }
+ });
+}
+
+async function nullableDetailByCode(code: string): Promise {
+ return await axios.post(`${BASE_URI}/detail/code/nullable`, undefined, {
+ params: { code }
+ });
+}
+
+async function invitedList(introducerCustomerId: string): Promise {
+ return await axios.post(`${BASE_URI}/invited/list`, undefined, {
+ params: { introducerCustomerId }
+ });
+}
+
+async function create(req: Customer): Promise {
+ return await axios.post(`${BASE_URI}/create`, req);
+}
+
+async function quickRegister(req: QuickRegisterReq): Promise {
+ return await axios.post(`${BASE_URI}/quick/register`, req);
+}
+
+async function update(req: Customer): Promise {
+ return await axios.post(`${BASE_URI}/update`, req);
+}
+
+async function remove(id: string): Promise {
+ return await axios.post(`${BASE_URI}/delete`, undefined, {
+ params: { id }
+ });
+}
+
+async function createInvite(req: CustomerInviteUpdateReq): Promise {
+ return await axios.post(`${BASE_URI}/invite/create`, req);
+}
+
+async function updateInvite(req: CustomerInviteUpdateReq): Promise {
+ return await axios.post(`${BASE_URI}/invite/update`, req);
+}
+
+async function deleteInvite(customerId: string): Promise {
+ return await axios.post(`${BASE_URI}/invite/delete`, undefined, {
+ params: { customerId }
+ });
+}
+
+async function dailyStat(req: CustomerTrendStatReq): Promise {
+ return await axios.post(`${BASE_URI}/stat/daily`, req);
+}
+
+async function genderStat(): Promise {
+ return await axios.post(`${BASE_URI}/stat/gender`);
+}
+
+export default {
+ list,
+ search,
+ searchPage,
+ exportExcel,
+ detail,
+ detailByCode,
+ nullableDetailByCode,
+ invitedList,
+ create,
+ quickRegister,
+ update,
+ remove,
+ createInvite,
+ updateInvite,
+ deleteInvite,
+ dailyStat,
+ genderStat
+};
diff --git a/src/api/GaoUserAPI.ts b/src/api/GaoUserAPI.ts
new file mode 100644
index 0000000..21733bc
--- /dev/null
+++ b/src/api/GaoUserAPI.ts
@@ -0,0 +1,41 @@
+import { axios, type Page, type PageResult, type Role } from "timi-web";
+import type { GaoUser } from "@/types/GaoUser";
+
+const BASE_URI = "/gao/user";
+
+async function list(req: Page): Promise> {
+ return await axios.post(`${BASE_URI}/list`, req);
+}
+
+async function detail(id: string): Promise {
+ return await axios.post(`${BASE_URI}/detail`, undefined, {
+ params: { id }
+ });
+}
+
+async function create(req: GaoUser): Promise {
+ return await axios.post(`${BASE_URI}/create`, req);
+}
+
+async function update(req: GaoUser): Promise {
+ return await axios.post(`${BASE_URI}/update`, req);
+}
+
+async function remove(id: string): Promise {
+ return await axios.post(`${BASE_URI}/delete`, undefined, {
+ params: { id }
+ });
+}
+
+async function roleList(): Promise {
+ return await axios.post(`${BASE_URI}/role/list`);
+}
+
+export default {
+ list,
+ detail,
+ create,
+ update,
+ remove,
+ roleList
+};
diff --git a/src/api/RegistrationEventAPI.ts b/src/api/RegistrationEventAPI.ts
new file mode 100644
index 0000000..c75f2ad
--- /dev/null
+++ b/src/api/RegistrationEventAPI.ts
@@ -0,0 +1,41 @@
+import { axios, type Page, type PageResult } from "timi-web";
+import type { RegistrationEvent } from "@/types/RegistrationEvent";
+
+const BASE_URI = "/gao/registration-event";
+
+async function list(req: Page): Promise> {
+ return await axios.post(`${BASE_URI}/list`, req);
+}
+
+async function enabledList(): Promise {
+ return await axios.post(`${BASE_URI}/enabled/list`);
+}
+
+async function detail(id: string): Promise {
+ return await axios.post(`${BASE_URI}/detail`, undefined, {
+ params: { id }
+ });
+}
+
+async function create(req: RegistrationEvent): Promise {
+ return await axios.post(`${BASE_URI}/create`, req);
+}
+
+async function update(req: RegistrationEvent): Promise {
+ return await axios.post(`${BASE_URI}/update`, req);
+}
+
+async function remove(id: string): Promise {
+ return await axios.post(`${BASE_URI}/delete`, undefined, {
+ params: { id }
+ });
+}
+
+export default {
+ list,
+ enabledList,
+ detail,
+ create,
+ update,
+ remove
+};
diff --git a/src/api/RegistrationEventRecordAPI.ts b/src/api/RegistrationEventRecordAPI.ts
new file mode 100644
index 0000000..190d4a9
--- /dev/null
+++ b/src/api/RegistrationEventRecordAPI.ts
@@ -0,0 +1,88 @@
+import { axios, type Page, type PageResult } from "timi-web";
+import type {
+ CustomerRegisterStatView,
+ RegistrationEventRecordCalendarView,
+ RegistrationEventRecord,
+ RegistrationEventRecordCreateReq,
+ RegistrationEventRecordDailyStatView,
+ RegistrationEventRecordListItemView,
+ RegistrationEventRecordRangeReq,
+ RegistrationEventRecordStatReq,
+ RegistrationEventRecordTrendStatReq
+} from "@/types/RegistrationEventRecord";
+
+const BASE_URI = "/gao/registration-event-record";
+
+async function list(req: Page): Promise> {
+ return await axios.post(`${BASE_URI}/list`, req);
+}
+
+async function detail(id: string): Promise {
+ return await axios.post(`${BASE_URI}/detail`, undefined, {
+ params: { id }
+ });
+}
+
+async function rangeList(req: RegistrationEventRecordRangeReq): Promise {
+ return await axios.post(`${BASE_URI}/range/list`, req);
+}
+
+async function calendarRangeList(req: RegistrationEventRecordRangeReq): Promise {
+ return await axios.post(`${BASE_URI}/range/calendar/list`, req);
+}
+
+async function rangePage(req: Page): Promise> {
+ return await axios.post(`${BASE_URI}/range/page`, req);
+}
+
+async function rangeExport(req: RegistrationEventRecordRangeReq): Promise {
+ return await axios.post(`${BASE_URI}/range/export`, req, {
+ responseType: "blob"
+ });
+}
+
+async function create(req: RegistrationEventRecordCreateReq): Promise {
+ return await axios.post(`${BASE_URI}/create`, req);
+}
+
+async function update(req: RegistrationEventRecord): Promise {
+ await axios.post(`${BASE_URI}/update`, req);
+}
+
+async function remove(id: string): Promise {
+ await axios.post(`${BASE_URI}/delete`, undefined, {
+ params: { id }
+ });
+}
+
+async function customerRangeStat(req: RegistrationEventRecordStatReq): Promise {
+ return await axios.post(`${BASE_URI}/customer/range/stat`, req);
+}
+
+async function allCustomerRangeStat(req: RegistrationEventRecordStatReq): Promise {
+ return await axios.post(`${BASE_URI}/all-customer/range/stat`, req);
+}
+
+async function customerRegistrationEventDailyStat(req: RegistrationEventRecordTrendStatReq): Promise {
+ return await axios.post(`${BASE_URI}/customer/registration-event/daily/stat`, req);
+}
+
+async function allCustomerRegistrationEventDailyStat(req: RegistrationEventRecordTrendStatReq): Promise {
+ return await axios.post(`${BASE_URI}/all-customer/registration-event/daily/stat`, req);
+}
+
+export default {
+ list,
+ detail,
+ rangeList,
+ calendarRangeList,
+ rangePage,
+ rangeExport,
+ create,
+ update,
+ remove,
+ customerRangeStat,
+ allCustomerRangeStat,
+ customerRegistrationEventDailyStat,
+ allCustomerRegistrationEventDailyStat
+};
diff --git a/src/assets/sound/registration-success.mp3 b/src/assets/sound/registration-success.mp3
new file mode 100644
index 0000000..1d8167c
Binary files /dev/null and b/src/assets/sound/registration-success.mp3 differ
diff --git a/src/assets/sound/scan-success.mp3 b/src/assets/sound/scan-success.mp3
new file mode 100644
index 0000000..6aaf001
Binary files /dev/null and b/src/assets/sound/scan-success.mp3 differ
diff --git a/src/components/BodyAreaSelector.vue b/src/components/BodyAreaSelector.vue
new file mode 100644
index 0000000..f1224ab
--- /dev/null
+++ b/src/components/BodyAreaSelector.vue
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CodeScanner.vue b/src/components/CodeScanner.vue
new file mode 100644
index 0000000..b7063e1
--- /dev/null
+++ b/src/components/CodeScanner.vue
@@ -0,0 +1,529 @@
+
+
+
+
+
+
+
diff --git a/src/components/CustomerProfileCard.vue b/src/components/CustomerProfileCard.vue
new file mode 100644
index 0000000..ec729fd
--- /dev/null
+++ b/src/components/CustomerProfileCard.vue
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
diff --git a/src/components/CustomerSelector.vue b/src/components/CustomerSelector.vue
new file mode 100644
index 0000000..165f008
--- /dev/null
+++ b/src/components/CustomerSelector.vue
@@ -0,0 +1,288 @@
+
+
+
+
选择客户
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/GenderIcon.vue b/src/components/GenderIcon.vue
new file mode 100644
index 0000000..5f3f213
--- /dev/null
+++ b/src/components/GenderIcon.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
diff --git a/src/components/PageTransition.vue b/src/components/PageTransition.vue
new file mode 100644
index 0000000..2a5d93b
--- /dev/null
+++ b/src/components/PageTransition.vue
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
diff --git a/src/components/PhotoField.vue b/src/components/PhotoField.vue
new file mode 100644
index 0000000..af7a6fe
--- /dev/null
+++ b/src/components/PhotoField.vue
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/PhotoScroller.vue b/src/components/PhotoScroller.vue
new file mode 100644
index 0000000..fabe38a
--- /dev/null
+++ b/src/components/PhotoScroller.vue
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
diff --git a/src/components/RegistrationEventRecordCalendar.vue b/src/components/RegistrationEventRecordCalendar.vue
new file mode 100644
index 0000000..9af4e88
--- /dev/null
+++ b/src/components/RegistrationEventRecordCalendar.vue
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 正在加载登记日历
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/RegistrationEventSelector.vue b/src/components/RegistrationEventSelector.vue
new file mode 100644
index 0000000..13d6aaf
--- /dev/null
+++ b/src/components/RegistrationEventSelector.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
diff --git a/src/components/SegmentedSlider.vue b/src/components/SegmentedSlider.vue
new file mode 100644
index 0000000..e8701ca
--- /dev/null
+++ b/src/components/SegmentedSlider.vue
@@ -0,0 +1,186 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/MainLayout.vue b/src/layout/MainLayout.vue
new file mode 100644
index 0000000..2a67630
--- /dev/null
+++ b/src/layout/MainLayout.vue
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/RootLayout.vue b/src/layout/RootLayout.vue
new file mode 100644
index 0000000..dd020cb
--- /dev/null
+++ b/src/layout/RootLayout.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..eb7ba86
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,77 @@
+import {createApp} from "vue";
+import {createPinia} from "pinia";
+import router from "@/router";
+import Root from "@/Root.vue";
+
+import "tdesign-mobile-vue/es/style/index.css";
+import "timi-web/style.css";
+import "timi-tdesign-mobile/style.css";
+import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
+import "@/styles/tdesign-custom.css";
+import "@/styles/global.less";
+import {configureUserStore, type ApiResponse, Network, useUserStore, VCan, VRole} from "timi-web";
+import {Toast} from "tdesign-mobile-vue";
+
+export const pinia = createPinia();
+const apiBaseURL = import.meta.env.VITE_API_BASE_URL as string | undefined;
+
+if (apiBaseURL) {
+ Network.axios.defaults.baseURL = apiBaseURL;
+}
+
+configureUserStore({
+ storageKey: "gao-customer-h5:user"
+});
+
+Network.setGlobalRequestInterceptor((config: any) => {
+ const userStore = useUserStore(pinia);
+ if (apiBaseURL && !config.baseURL) {
+ config.baseURL = apiBaseURL;
+ }
+
+ config.headers.set({
+ "Accept-Language": "zh-CN"
+ });
+
+ if (userStore.token) {
+ config.headers.set({
+ "Token": userStore.token
+ });
+ }
+ return config;
+});
+async function bootstrap(): Promise {
+ const app = createApp(Root);
+ app.use(pinia);
+ app.directive("can", VCan);
+ app.directive("role", VRole);
+
+ const userStore = useUserStore(pinia);
+ await userStore.loginByStorage();
+
+ Network.setGlobalErrorCallback((resp: ApiResponse) => {
+ Toast({
+ theme: "error",
+ direction: "row",
+ message: resp.message
+ });
+ });
+
+ app.use(router);
+ app.mount("#root");
+}
+
+async function start(): Promise {
+ try {
+ await bootstrap();
+ } catch (error) {
+ console.error(error);
+ Toast({
+ theme: "error",
+ direction: "row",
+ message: "应用启动失败"
+ });
+ }
+}
+
+void start();
diff --git a/src/pages/Login.vue b/src/pages/Login.vue
new file mode 100644
index 0000000..653d66a
--- /dev/null
+++ b/src/pages/Login.vue
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+
+
diff --git a/src/pages/customer/QuickEntryPage.vue b/src/pages/customer/QuickEntryPage.vue
new file mode 100644
index 0000000..8127b0a
--- /dev/null
+++ b/src/pages/customer/QuickEntryPage.vue
@@ -0,0 +1,576 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
提交
+
+
+
+
+
+
+
diff --git a/src/pages/customer/QuickSignInPage.vue b/src/pages/customer/QuickSignInPage.vue
new file mode 100644
index 0000000..7c38886
--- /dev/null
+++ b/src/pages/customer/QuickSignInPage.vue
@@ -0,0 +1,445 @@
+
+
+
+ 登记事件
+
+
+
+
+
+ 扫出编码
+
+
+
+
+
+
+
+
+
+
+
登记
+
+
+
+
登记事件
+
+
+
+
暂无可用登记事件
+
+
+
+
+
+
+
diff --git a/src/pages/management/CustomerDataCharts.vue b/src/pages/management/CustomerDataCharts.vue
new file mode 100644
index 0000000..94ac4bf
--- /dev/null
+++ b/src/pages/management/CustomerDataCharts.vue
@@ -0,0 +1,670 @@
+
+
+
+
+
+
+
请选择客户后查看专属图表
+
+
+
+
+
+
+
diff --git a/src/pages/management/CustomerDetail.vue b/src/pages/management/CustomerDetail.vue
new file mode 100644
index 0000000..d3f643d
--- /dev/null
+++ b/src/pages/management/CustomerDetail.vue
@@ -0,0 +1,564 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 调理部位
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+ 暂无邀请客户
+
+
+
+
+ 删除客户
+
+ 编辑客户
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/CustomerEdit.vue b/src/pages/management/CustomerEdit.vue
new file mode 100644
index 0000000..7789398
--- /dev/null
+++ b/src/pages/management/CustomerEdit.vue
@@ -0,0 +1,541 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 男
+ 女
+ 未知
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 调理部位
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/CustomerList.vue b/src/pages/management/CustomerList.vue
new file mode 100644
index 0000000..e6b12b1
--- /dev/null
+++ b/src/pages/management/CustomerList.vue
@@ -0,0 +1,374 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 导出
+
+
+
+
+
+ 添加
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/ManagementDataCharts.vue b/src/pages/management/ManagementDataCharts.vue
new file mode 100644
index 0000000..1d6d006
--- /dev/null
+++ b/src/pages/management/ManagementDataCharts.vue
@@ -0,0 +1,521 @@
+
+
+
+
+
+
+
diff --git a/src/pages/management/ManagementPassword.vue b/src/pages/management/ManagementPassword.vue
new file mode 100644
index 0000000..a004f49
--- /dev/null
+++ b/src/pages/management/ManagementPassword.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
+
+
+
diff --git a/src/pages/management/ManagementProfile.vue b/src/pages/management/ManagementProfile.vue
new file mode 100644
index 0000000..25112a1
--- /dev/null
+++ b/src/pages/management/ManagementProfile.vue
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 男
+ 女
+ 未知
+
+
+
+
+
+
+
+
+
+
+
保存
+
退出登录
+
+
+
+
+
+
diff --git a/src/pages/management/ManagementQrCode.vue b/src/pages/management/ManagementQrCode.vue
new file mode 100644
index 0000000..a492ca8
--- /dev/null
+++ b/src/pages/management/ManagementQrCode.vue
@@ -0,0 +1,360 @@
+
+
+
+
+
+
+
+ handleNumberChange('start', value)"
+ />
+
+
+
+
+
+ handleNumberChange('quantity', value)"
+ />
+
+
+
+
+
+
+
+
+
+ 打印
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/ManagementSettings.vue b/src/pages/management/ManagementSettings.vue
new file mode 100644
index 0000000..668e651
--- /dev/null
+++ b/src/pages/management/ManagementSettings.vue
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ handleScanSuccessChange(value === true)" />
+
+
+
+
+ handleRegisterSuccessChange(value === true)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/PermissionEdit.vue b/src/pages/management/PermissionEdit.vue
new file mode 100644
index 0000000..3d1cece
--- /dev/null
+++ b/src/pages/management/PermissionEdit.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
+
+
+
diff --git a/src/pages/management/PermissionList.vue b/src/pages/management/PermissionList.vue
new file mode 100644
index 0000000..7154015
--- /dev/null
+++ b/src/pages/management/PermissionList.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+ 新增权限
+
+
+
+
+
+
+
diff --git a/src/pages/management/PermissionSettings.vue b/src/pages/management/PermissionSettings.vue
new file mode 100644
index 0000000..386a0d6
--- /dev/null
+++ b/src/pages/management/PermissionSettings.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/RegistrationEventEdit.vue b/src/pages/management/RegistrationEventEdit.vue
new file mode 100644
index 0000000..c434964
--- /dev/null
+++ b/src/pages/management/RegistrationEventEdit.vue
@@ -0,0 +1,314 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 有效
+ 无效
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 可登记角色
+ 未选择角色时不限制角色
+
+
+
+
+
+
+
+
保存
+
+
+
+
+
+
diff --git a/src/pages/management/RegistrationEventList.vue b/src/pages/management/RegistrationEventList.vue
new file mode 100644
index 0000000..4cce3fd
--- /dev/null
+++ b/src/pages/management/RegistrationEventList.vue
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 需拍照
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
暂无登记事件
+
+
+
+
+ 新增登记事件
+
+
+
+
+
+
+
diff --git a/src/pages/management/RegistrationEventRecordDetail.vue b/src/pages/management/RegistrationEventRecordDetail.vue
new file mode 100644
index 0000000..98dac8a
--- /dev/null
+++ b/src/pages/management/RegistrationEventRecordDetail.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/src/pages/management/RegistrationEventRecordEdit.vue b/src/pages/management/RegistrationEventRecordEdit.vue
new file mode 100644
index 0000000..459a796
--- /dev/null
+++ b/src/pages/management/RegistrationEventRecordEdit.vue
@@ -0,0 +1,630 @@
+
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
当前客户暂无事件记录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/RegistrationEventRecordList.vue b/src/pages/management/RegistrationEventRecordList.vue
new file mode 100644
index 0000000..3d8eff9
--- /dev/null
+++ b/src/pages/management/RegistrationEventRecordList.vue
@@ -0,0 +1,629 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+ 导出 Excel
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/management/RoleEdit.vue b/src/pages/management/RoleEdit.vue
new file mode 100644
index 0000000..ba12d44
--- /dev/null
+++ b/src/pages/management/RoleEdit.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 子角色
+ 父角色会继承子角色权限
+
+
+
+
+
+
保存
+
+
+
+
+
+
diff --git a/src/pages/management/RoleList.vue b/src/pages/management/RoleList.vue
new file mode 100644
index 0000000..f554e64
--- /dev/null
+++ b/src/pages/management/RoleList.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+ 新增角色
+
+
+
+
+
+
+
diff --git a/src/pages/management/RolePermissionAssign.vue b/src/pages/management/RolePermissionAssign.vue
new file mode 100644
index 0000000..ddffb83
--- /dev/null
+++ b/src/pages/management/RolePermissionAssign.vue
@@ -0,0 +1,290 @@
+
+
+
+
+
+
+
+
+
+ setPermissionChecked(item.id, value === true)"
+ />
+
+
+
+
+
+ 保存授权
+
+
+
+
+
+
+
diff --git a/src/pages/management/UserDetail.vue b/src/pages/management/UserDetail.vue
new file mode 100644
index 0000000..0bb6395
--- /dev/null
+++ b/src/pages/management/UserDetail.vue
@@ -0,0 +1,240 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
编辑用户
+
+
+
+
+
+
diff --git a/src/pages/management/UserEdit.vue b/src/pages/management/UserEdit.vue
new file mode 100644
index 0000000..13e3443
--- /dev/null
+++ b/src/pages/management/UserEdit.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
+
+
+
diff --git a/src/pages/management/UserList.vue b/src/pages/management/UserList.vue
new file mode 100644
index 0000000..b2fab42
--- /dev/null
+++ b/src/pages/management/UserList.vue
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
diff --git a/src/pages/management/UserRoleAssign.vue b/src/pages/management/UserRoleAssign.vue
new file mode 100644
index 0000000..c8b4dc4
--- /dev/null
+++ b/src/pages/management/UserRoleAssign.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+ setRoleChecked(item.id, value === true)"
+ />
+
+
+
+
+
+ 保存授权
+
+
+
+
+
+
+
diff --git a/src/pages/tabs/CustomerTab.vue b/src/pages/tabs/CustomerTab.vue
new file mode 100644
index 0000000..d172a39
--- /dev/null
+++ b/src/pages/tabs/CustomerTab.vue
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
diff --git a/src/pages/tabs/ManagementTab.vue b/src/pages/tabs/ManagementTab.vue
new file mode 100644
index 0000000..f6e123d
--- /dev/null
+++ b/src/pages/tabs/ManagementTab.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/router/index.ts b/src/router/index.ts
new file mode 100644
index 0000000..356b533
--- /dev/null
+++ b/src/router/index.ts
@@ -0,0 +1,108 @@
+import { createRouter, createWebHistory } from "vue-router";
+import RootLayout from "@/layout/RootLayout.vue";
+import MainLayout from "@/layout/MainLayout.vue";
+import Login from "@/pages/Login.vue";
+import chartRoutes from "@/router/routes/chartRoutes";
+import customerRoutes from "@/router/routes/customerRoutes";
+import { managementAccountRoutes, managementSettingRoutes } from "@/router/routes/managementRoutes";
+import permissionRoutes from "@/router/routes/permissionRoutes";
+import registrationRoutes from "@/router/routes/registrationRoutes";
+import tabRoutes from "@/router/routes/tabRoutes";
+import userRoutes from "@/router/routes/userRoutes";
+import { useGlobalUIStore } from "@/store/globalUI";
+import { useUserStore } from "timi-web";
+
+const detailRoutes = [
+ ...customerRoutes,
+ ...userRoutes,
+ ...registrationRoutes,
+ ...managementSettingRoutes,
+ ...permissionRoutes,
+ ...chartRoutes,
+ ...managementAccountRoutes
+];
+
+const router = createRouter({
+ history: createWebHistory("/"),
+ scrollBehavior(_to, _from, savedPosition) {
+ if (savedPosition) {
+ return savedPosition;
+ }
+
+ return {
+ left: 0,
+ top: 0
+ };
+ },
+ routes: [
+ {
+ path: "/",
+ component: RootLayout,
+ children: [
+ {
+ path: "",
+ redirect: "/customers"
+ },
+ {
+ path: "login",
+ name: "Login",
+ component: Login,
+ meta: {
+ depth: 1,
+ navBarVisible: false,
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "",
+ component: MainLayout,
+ meta: {
+ depth: 1,
+ navBarVisible: false,
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ },
+ children: [
+ ...tabRoutes,
+ ...detailRoutes
+ ]
+ }
+ ]
+ },
+ {
+ path: "/:pathMatch(.*)*",
+ redirect: "/customers"
+ }
+ ]
+});
+
+router.beforeEach((to) => {
+ const userStore = useUserStore();
+ if (to.path === "/login") {
+ return userStore.isLogged() ? "/management" : true;
+ }
+
+ if (!userStore.isLogged()) {
+ return {
+ path: "/login",
+ query: {
+ redirect: to.fullPath
+ }
+ };
+ }
+
+ return true;
+});
+
+router.afterEach((to) => {
+ const globalUIStore = useGlobalUIStore();
+ const isDarkMode = globalUIStore.themeMode === "dark";
+ const fallbackBackground = isDarkMode ? "#10161f" : "#F5F5F8";
+ const targetBackground = isDarkMode ? to.meta.darkBodyBackground : to.meta.bodyBackground;
+ globalUIStore.setBodyBackground(typeof targetBackground === "string" ? targetBackground : fallbackBackground);
+});
+
+export default router;
diff --git a/src/router/routes/chartRoutes.ts b/src/router/routes/chartRoutes.ts
new file mode 100644
index 0000000..2c4ee56
--- /dev/null
+++ b/src/router/routes/chartRoutes.ts
@@ -0,0 +1,48 @@
+import type { RouteRecordRaw } from "vue-router";
+
+const chartRoutes: RouteRecordRaw[] = [
+ {
+ path: "/management/data-charts",
+ name: "ManagementDataCharts",
+ component: () => import("@/pages/management/ManagementDataCharts.vue"),
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "全局数据图表",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/customer-data-charts",
+ name: "CustomerDataCharts",
+ component: () => import("@/pages/management/CustomerDataCharts.vue"),
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "客户数据图表",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/customers/:id/data-charts",
+ name: "CustomerDataChartsFromCustomer",
+ component: () => import("@/pages/management/CustomerDataCharts.vue"),
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "客户数据图表",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export default chartRoutes;
diff --git a/src/router/routes/customerRoutes.ts b/src/router/routes/customerRoutes.ts
new file mode 100644
index 0000000..e5313fb
--- /dev/null
+++ b/src/router/routes/customerRoutes.ts
@@ -0,0 +1,110 @@
+import type { RouteRecordRaw } from "vue-router";
+import QuickEntryPage from "@/pages/customer/QuickEntryPage.vue";
+import QuickSignInPage from "@/pages/customer/QuickSignInPage.vue";
+import RegistrationEventRecordEdit from "@/pages/management/RegistrationEventRecordEdit.vue";
+import CustomerList from "@/pages/management/CustomerList.vue";
+import CustomerDetail from "@/pages/management/CustomerDetail.vue";
+import CustomerEdit from "@/pages/management/CustomerEdit.vue";
+
+const customerRoutes: RouteRecordRaw[] = [
+ {
+ path: "/customer/quick-entry",
+ name: "QuickEntryPage",
+ component: QuickEntryPage,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "快速补录登记",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/customer/quick-sign-in",
+ name: "QuickSignInPage",
+ component: QuickSignInPage,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "快速扫码登记",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/customer/registration",
+ name: "CustomerRegistrationEventRecordCreate",
+ component: RegistrationEventRecordEdit,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "登记",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/customers",
+ name: "CustomerList",
+ component: CustomerList,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "客户管理",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/customers/create",
+ name: "CustomerCreate",
+ component: CustomerEdit,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "新增客户",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/customers/:id",
+ name: "CustomerDetail",
+ component: CustomerDetail,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "客户详情",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/customers/:id/edit",
+ name: "CustomerEdit",
+ component: CustomerEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "编辑客户",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export default customerRoutes;
diff --git a/src/router/routes/managementRoutes.ts b/src/router/routes/managementRoutes.ts
new file mode 100644
index 0000000..56cd7f9
--- /dev/null
+++ b/src/router/routes/managementRoutes.ts
@@ -0,0 +1,74 @@
+import type { RouteRecordRaw } from "vue-router";
+import ManagementSettings from "@/pages/management/ManagementSettings.vue";
+import ManagementProfile from "@/pages/management/ManagementProfile.vue";
+import ManagementPassword from "@/pages/management/ManagementPassword.vue";
+import ManagementQrCode from "@/pages/management/ManagementQrCode.vue";
+
+export const managementSettingRoutes: RouteRecordRaw[] = [
+ {
+ path: "/management/settings",
+ name: "ManagementSettings",
+ component: ManagementSettings,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "应用设置",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export const managementAccountRoutes: RouteRecordRaw[] = [
+ {
+ path: "/management/profile",
+ name: "ManagementProfile",
+ component: ManagementProfile,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "当前用户",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/profile/password",
+ name: "ManagementPassword",
+ component: ManagementPassword,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "修改密码",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/qr-code",
+ name: "ManagementQrCode",
+ component: ManagementQrCode,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "生成二维码",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+const managementRoutes: RouteRecordRaw[] = [
+ ...managementSettingRoutes,
+ ...managementAccountRoutes
+];
+
+export default managementRoutes;
diff --git a/src/router/routes/permissionRoutes.ts b/src/router/routes/permissionRoutes.ts
new file mode 100644
index 0000000..78c9aed
--- /dev/null
+++ b/src/router/routes/permissionRoutes.ts
@@ -0,0 +1,139 @@
+import type { RouteRecordRaw } from "vue-router";
+import PermissionSettings from "@/pages/management/PermissionSettings.vue";
+import RoleList from "@/pages/management/RoleList.vue";
+import RoleEdit from "@/pages/management/RoleEdit.vue";
+import PermissionList from "@/pages/management/PermissionList.vue";
+import PermissionEdit from "@/pages/management/PermissionEdit.vue";
+import RolePermissionAssign from "@/pages/management/RolePermissionAssign.vue";
+import UserRoleAssign from "@/pages/management/UserRoleAssign.vue";
+
+const permissionRoutes: RouteRecordRaw[] = [
+ {
+ path: "/management/permissions",
+ name: "PermissionSettings",
+ component: PermissionSettings,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "权限设置",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/roles",
+ name: "RoleList",
+ component: RoleList,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "角色管理",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/roles/create",
+ name: "RoleCreate",
+ component: RoleEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "新增角色",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/roles/:id",
+ name: "RoleEdit",
+ component: RoleEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "编辑角色",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/items",
+ name: "PermissionList",
+ component: PermissionList,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "权限管理",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/items/create",
+ name: "PermissionCreate",
+ component: PermissionEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "新增权限",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/items/:id",
+ name: "PermissionEdit",
+ component: PermissionEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "编辑权限",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/assign",
+ name: "RolePermissionAssign",
+ component: RolePermissionAssign,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "角色授权权限",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/permissions/user-roles",
+ name: "UserRoleAssign",
+ component: UserRoleAssign,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "用户授权角色",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export default permissionRoutes;
diff --git a/src/router/routes/registrationRoutes.ts b/src/router/routes/registrationRoutes.ts
new file mode 100644
index 0000000..94bd9c1
--- /dev/null
+++ b/src/router/routes/registrationRoutes.ts
@@ -0,0 +1,109 @@
+import type { RouteRecordRaw } from "vue-router";
+import RegistrationEventEdit from "@/pages/management/RegistrationEventEdit.vue";
+import RegistrationEventList from "@/pages/management/RegistrationEventList.vue";
+import RegistrationEventRecordDetail from "@/pages/management/RegistrationEventRecordDetail.vue";
+import RegistrationEventRecordEdit from "@/pages/management/RegistrationEventRecordEdit.vue";
+import RegistrationEventRecordList from "@/pages/management/RegistrationEventRecordList.vue";
+
+const registrationRoutes: RouteRecordRaw[] = [
+ {
+ path: "/management/registration-events",
+ name: "RegistrationEventList",
+ component: RegistrationEventList,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "登记事件管理",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/registration-events/create",
+ name: "RegistrationEventCreate",
+ component: RegistrationEventEdit,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "新增登记事件",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/registration-events/:id/edit",
+ name: "RegistrationEventEdit",
+ component: RegistrationEventEdit,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "编辑登记事件",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/registration-event-records",
+ name: "RegistrationEventRecordList",
+ component: RegistrationEventRecordList,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "登记事件记录管理",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/registration-event-records/create",
+ name: "RegistrationEventRecordCreate",
+ component: RegistrationEventRecordEdit,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "新增登记事件记录",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/registration-event-records/:id",
+ name: "RegistrationEventRecordDetail",
+ component: RegistrationEventRecordDetail,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "登记事件记录详情",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/registration-event-records/:id/edit",
+ name: "RegistrationEventRecordEdit",
+ component: RegistrationEventRecordEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "编辑登记事件记录",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export default registrationRoutes;
diff --git a/src/router/routes/tabRoutes.ts b/src/router/routes/tabRoutes.ts
new file mode 100644
index 0000000..7981e89
--- /dev/null
+++ b/src/router/routes/tabRoutes.ts
@@ -0,0 +1,36 @@
+import type { RouteRecordRaw } from "vue-router";
+import CustomerTab from "@/pages/tabs/CustomerTab.vue";
+import ManagementTab from "@/pages/tabs/ManagementTab.vue";
+
+const tabRoutes: RouteRecordRaw[] = [
+ {
+ path: "/customers",
+ name: "CustomerTab",
+ component: CustomerTab,
+ meta: {
+ depth: 2,
+ navBarVisible: true,
+ navBarCanBack: false,
+ navBarTitle: "客户",
+ tabBarVisible: true,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management",
+ name: "ManagementTab",
+ component: ManagementTab,
+ meta: {
+ depth: 2,
+ navBarVisible: true,
+ navBarCanBack: false,
+ navBarTitle: "管理",
+ tabBarVisible: true,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export default tabRoutes;
diff --git a/src/router/routes/userRoutes.ts b/src/router/routes/userRoutes.ts
new file mode 100644
index 0000000..ac2c916
--- /dev/null
+++ b/src/router/routes/userRoutes.ts
@@ -0,0 +1,80 @@
+import type { RouteRecordRaw } from "vue-router";
+import UserList from "@/pages/management/UserList.vue";
+import UserDetail from "@/pages/management/UserDetail.vue";
+import UserEdit from "@/pages/management/UserEdit.vue";
+import UserRoleAssign from "@/pages/management/UserRoleAssign.vue";
+
+const userRoutes: RouteRecordRaw[] = [
+ {
+ path: "/management/users",
+ name: "UserList",
+ component: UserList,
+ meta: {
+ depth: 3,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "用户管理",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/users/create",
+ name: "UserCreatePage",
+ component: UserEdit,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "新增用户",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/users/:id",
+ name: "UserDetail",
+ component: UserDetail,
+ meta: {
+ depth: 4,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "用户详情",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/users/:id/edit",
+ name: "UserEdit",
+ component: UserEdit,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "编辑用户",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ },
+ {
+ path: "/management/users/:id/roles",
+ name: "UserRoleAssignFromUser",
+ component: UserRoleAssign,
+ meta: {
+ depth: 5,
+ navBarVisible: true,
+ navBarCanBack: true,
+ navBarTitle: "配置角色",
+ tabBarVisible: false,
+ bodyBackground: "#F5F5F8",
+ darkBodyBackground: "#10161f"
+ }
+ }
+];
+
+export default userRoutes;
diff --git a/src/store/globalUI.ts b/src/store/globalUI.ts
new file mode 100644
index 0000000..3867558
--- /dev/null
+++ b/src/store/globalUI.ts
@@ -0,0 +1,41 @@
+import type { Pinia } from "pinia";
+import { defineStore } from "pinia";
+
+export const DEFAULT_BODY_BACKGROUND = "#FFF";
+const THEME_STORAGE_KEY = "gao-customer-h5:theme-mode";
+
+export type ThemeMode = "light" | "dark" | "system";
+
+function readStoredThemeMode(): ThemeMode {
+ const rawValue = localStorage.getItem(THEME_STORAGE_KEY);
+ if (rawValue === "light" || rawValue === "dark" || rawValue === "system") {
+ return rawValue;
+ }
+
+ return "system";
+}
+
+const store = defineStore("globalUI", () => {
+ const bodyBackground = ref(DEFAULT_BODY_BACKGROUND);
+ const themeMode = ref(readStoredThemeMode());
+
+ function setBodyBackground(color?: string): void {
+ bodyBackground.value = color || DEFAULT_BODY_BACKGROUND;
+ }
+
+ function setThemeMode(mode: ThemeMode): void {
+ themeMode.value = mode;
+ localStorage.setItem(THEME_STORAGE_KEY, mode);
+ }
+
+ return {
+ bodyBackground,
+ themeMode,
+ setBodyBackground,
+ setThemeMode
+ };
+});
+
+export function useGlobalUIStore(pinia?: Pinia) {
+ return store(pinia);
+}
diff --git a/src/store/navBarStore.ts b/src/store/navBarStore.ts
new file mode 100644
index 0000000..2047c8d
--- /dev/null
+++ b/src/store/navBarStore.ts
@@ -0,0 +1,96 @@
+export const useNavBarStore = defineStore("nav-bar", () => {
+ const route = useRoute();
+ const router = useRouter();
+
+ const height = ref(0);
+ const title = ref("");
+ const backTo = ref();
+ const rightIcon = ref("");
+ const rightText = ref("");
+ const rightTextColor = ref("");
+ const rightAction = shallowRef<(() => void | Promise) | undefined>();
+ const customTitleVisible = ref(false);
+ const customRightVisible = ref(false);
+
+ const isShowing = computed(() => !!router.currentRoute.value.meta.navBarVisible);
+ const canBack = computed(() => !!router.currentRoute.value.meta.navBarCanBack);
+
+ watch(
+ () => route.meta.navBarTitle,
+ (value) => {
+ title.value = typeof value === "string" ? value : "";
+ },
+ { immediate: true }
+ );
+
+ function setHeight(value: number): void {
+ height.value = value;
+ }
+
+ function setBackTo(value?: string): void {
+ backTo.value = value;
+ }
+
+ function setRightIcon(value?: string, action?: () => void | Promise): void {
+ rightIcon.value = value || "";
+ rightAction.value = action;
+ if (value) {
+ rightText.value = "";
+ rightTextColor.value = "";
+ customRightVisible.value = false;
+ }
+ }
+
+ function setRightText(value?: string, color?: string, action?: () => void | Promise): void {
+ rightText.value = value || "";
+ rightTextColor.value = color || "";
+ rightAction.value = action;
+ if (value) {
+ rightIcon.value = "";
+ customRightVisible.value = false;
+ }
+ }
+
+ function setCustomTitleVisible(value: boolean): void {
+ customTitleVisible.value = value;
+ }
+
+ function setCustomRightVisible(value: boolean): void {
+ customRightVisible.value = value;
+ if (value) {
+ rightIcon.value = "";
+ rightText.value = "";
+ rightTextColor.value = "";
+ rightAction.value = undefined;
+ }
+ }
+
+ function clearRight(): void {
+ rightIcon.value = "";
+ rightText.value = "";
+ rightTextColor.value = "";
+ rightAction.value = undefined;
+ customRightVisible.value = false;
+ }
+
+ return {
+ height,
+ title,
+ backTo,
+ rightIcon,
+ rightText,
+ rightTextColor,
+ rightAction,
+ customTitleVisible,
+ customRightVisible,
+ isShowing,
+ canBack,
+ setHeight,
+ setBackTo,
+ setRightIcon,
+ setRightText,
+ setCustomTitleVisible,
+ setCustomRightVisible,
+ clearRight
+ };
+});
diff --git a/src/store/permissionSettingsStore.ts b/src/store/permissionSettingsStore.ts
new file mode 100644
index 0000000..5c625d4
--- /dev/null
+++ b/src/store/permissionSettingsStore.ts
@@ -0,0 +1,339 @@
+import { defineStore } from "pinia";
+import {
+ OrderType,
+ PermissionAPI,
+ RoleAPI,
+ type ModuleCode,
+ type Permission as UserPermission,
+ type PermissionPayload,
+ type Role as UserRole,
+ type RolePayload
+} from "timi-web";
+
+export const gaoModuleCode: ModuleCode = "GAO";
+const pageSize = 1000;
+
+export type Permission = UserPermission;
+export type Role = UserRole & {
+ permissionIdList: string[];
+ childRoleIdList: string[];
+};
+
+export type RoleDraft = {
+ id?: string;
+ code: string;
+ name: string;
+ description: string;
+ nameLangId?: string;
+ moduleCode?: ModuleCode;
+ permissionIdList: string[];
+ childRoleIdList: string[];
+};
+export type PermissionDraft = {
+ id?: string;
+ code: string;
+ name: string;
+ description: string;
+ nameLangId?: string;
+ moduleCode?: ModuleCode;
+};
+
+function normalizeRole(role: UserRole): Role {
+ return {
+ ...role,
+ moduleCode: role.moduleCode || gaoModuleCode,
+ description: role.description || "",
+ permissionIdList: role.permissionIdList || role.permissionList?.map(item => item.id) || [],
+ childRoleIdList: role.childRoleIdList || role.childRoleList?.map(item => item.id) || []
+ };
+}
+
+function createEmptyRole(): Role {
+ return {
+ id: "",
+ moduleCode: gaoModuleCode,
+ code: "",
+ name: "",
+ description: "",
+ permissionIdList: [],
+ childRoleIdList: []
+ };
+}
+
+function createEmptyPermission(): Permission {
+ return {
+ id: "",
+ moduleCode: gaoModuleCode,
+ code: "",
+ name: "",
+ description: ""
+ };
+}
+
+export const usePermissionSettingsStore = defineStore("permission-settings", () => {
+ const roleList = ref([]);
+ const permissionList = ref([]);
+ const loading = ref(false);
+ const loaded = ref(false);
+ let loadTask: Promise | null = null;
+
+ const roleTree = computed>(() => {
+ const childIdSet = new Set(roleList.value.flatMap(item => item.childRoleIdList));
+ const roots = roleList.value.filter(item => !childIdSet.has(item.id));
+ return roots.flatMap(item => buildRoleTree(item.id, 0, new Set()));
+ });
+
+ // ---------- 基础数据 ----------
+
+ async function loadAll(force = false): Promise {
+ if (loaded.value && !force) {
+ return;
+ }
+
+ if (loadTask && !force) {
+ await loadTask;
+ return;
+ }
+
+ loading.value = true;
+ loadTask = (async () => {
+ const [roleResult, permissionResult] = await Promise.all([
+ RoleAPI.list({
+ index: 0,
+ size: pageSize,
+ equalsExample: {
+ moduleCode: gaoModuleCode
+ },
+ orderMap: {
+ code: OrderType.ASC
+ }
+ }),
+ PermissionAPI.list({
+ index: 0,
+ size: pageSize,
+ equalsExample: {
+ moduleCode: gaoModuleCode
+ },
+ orderMap: {
+ code: OrderType.ASC
+ }
+ })
+ ]);
+ roleList.value = roleResult.list.map(normalizeRole);
+ permissionList.value = permissionResult.list;
+ loaded.value = true;
+ })();
+
+ try {
+ await loadTask;
+ } finally {
+ loadTask = null;
+ loading.value = false;
+ }
+ }
+
+ async function loadRoleDetail(id: string): Promise {
+ if (!id) {
+ return createEmptyRole();
+ }
+
+ const role = normalizeRole(await RoleAPI.detail(id));
+ upsertLocalRole(role);
+ return role;
+ }
+
+ async function loadPermissionDetail(id: string): Promise {
+ if (!id) {
+ return createEmptyPermission();
+ }
+
+ const permission = permissionList.value.find(item => item.id === id);
+ if (!permission) {
+ throw new Error("权限不存在");
+ }
+ upsertLocalPermission(permission);
+ return permission;
+ }
+
+ function upsertLocalRole(role: Role): void {
+ const index = roleList.value.findIndex(item => item.id === role.id);
+ if (-1 < index) {
+ roleList.value.splice(index, 1, role);
+ return;
+ }
+ roleList.value.unshift(role);
+ }
+
+ function upsertLocalPermission(permission: Permission): void {
+ const index = permissionList.value.findIndex(item => item.id === permission.id);
+ if (-1 < index) {
+ permissionList.value.splice(index, 1, permission);
+ return;
+ }
+ permissionList.value.unshift(permission);
+ }
+
+ // ---------- 查询 ----------
+
+ function buildRoleTree(roleId: string, level: number, visitedRoleIds: Set): Array {
+ const current = getRoleById(roleId);
+ if (!current || visitedRoleIds.has(roleId)) {
+ return [];
+ }
+
+ const nextVisitedRoleIds = new Set(visitedRoleIds);
+ nextVisitedRoleIds.add(roleId);
+
+ return [{
+ ...current,
+ level
+ }, ...current.childRoleIdList.flatMap(childRoleId => buildRoleTree(childRoleId, level + 1, nextVisitedRoleIds))];
+ }
+
+ function getRoleById(id: string): Role | undefined {
+ return roleList.value.find(item => item.id === id);
+ }
+
+ function getPermissionById(id: string): Permission | undefined {
+ return permissionList.value.find(item => item.id === id);
+ }
+
+ function getChildRoles(role: Role): Role[] {
+ return role.childRoleIdList.map(getRoleById).filter(Boolean) as Role[];
+ }
+
+ function getRolePermissionList(role: Role): Permission[] {
+ return role.permissionIdList.map(getPermissionById).filter(Boolean) as Permission[];
+ }
+
+ function getInheritedPermissionList(role: Role): Permission[] {
+ const permissionMap = new Map();
+ const allPermissionList = role.allPermissionList || [];
+ for (const permission of [...getRolePermissionList(role), ...allPermissionList]) {
+ permissionMap.set(permission.id, permission);
+ }
+
+ for (const childRole of getChildRoles(role)) {
+ for (const permission of getRolePermissionList(childRole)) {
+ permissionMap.set(permission.id, permission);
+ }
+ }
+
+ return Array.from(permissionMap.values());
+ }
+
+ // ---------- 写入 ----------
+
+ async function upsertRole(draft: RoleDraft, createMode: boolean): Promise {
+ const current = getRoleById(draft.id || "");
+ const payload: RolePayload = {
+ ...draft,
+ moduleCode: gaoModuleCode,
+ code: draft.code.trim(),
+ nameLangId: current?.nameLangId,
+ name: draft.name.trim(),
+ description: draft.description.trim(),
+ permissionIdList: [...draft.permissionIdList],
+ childRoleIdList: [...draft.childRoleIdList]
+ };
+
+ if (createMode) {
+ await RoleAPI.create({
+ moduleCode: payload.moduleCode,
+ code: payload.code,
+ name: payload.name,
+ description: payload.description,
+ permissionIdList: payload.permissionIdList,
+ childRoleIdList: payload.childRoleIdList
+ });
+ await loadAll(true);
+ return undefined;
+ }
+
+ await RoleAPI.update(payload);
+ const role = await loadRoleDetail(payload.id || "");
+ await loadAll(true);
+ return role;
+ }
+
+ async function removeRole(id: string): Promise {
+ await RoleAPI.remove(id);
+ roleList.value = roleList.value
+ .filter(item => item.id !== id)
+ .map(item => ({
+ ...item,
+ childRoleIdList: item.childRoleIdList.filter(childId => childId !== id)
+ }));
+ }
+
+ async function upsertPermission(draft: PermissionDraft, createMode: boolean): Promise {
+ const current = getPermissionById(draft.id || "");
+ const payload: PermissionPayload = {
+ ...draft,
+ moduleCode: gaoModuleCode,
+ code: draft.code.trim(),
+ nameLangId: current?.nameLangId,
+ name: draft.name.trim(),
+ description: draft.description.trim()
+ };
+
+ if (createMode) {
+ await PermissionAPI.create({
+ moduleCode: payload.moduleCode,
+ code: payload.code,
+ name: payload.name,
+ description: payload.description
+ });
+ await loadAll(true);
+ return undefined;
+ }
+
+ await PermissionAPI.update(payload);
+ const permission = await loadPermissionDetail(payload.id || "");
+ await loadAll(true);
+ return permission;
+ }
+
+ async function removePermission(id: string): Promise {
+ await PermissionAPI.remove(id);
+ permissionList.value = permissionList.value.filter(item => item.id !== id);
+ roleList.value = roleList.value.map(item => ({
+ ...item,
+ permissionIdList: item.permissionIdList.filter(permissionId => permissionId !== id)
+ }));
+ }
+
+ async function setRolePermissionList(roleId: string, permissionIds: string[]): Promise {
+ const role = await loadRoleDetail(roleId);
+ await upsertRole({
+ id: role.id,
+ moduleCode: gaoModuleCode,
+ code: role.code,
+ name: role.name || "",
+ description: role.description || "",
+ permissionIdList: [...permissionIds],
+ childRoleIdList: [...role.childRoleIdList]
+ }, false);
+ }
+
+ return {
+ roleList,
+ permissionList,
+ roleTree,
+ loading,
+ loaded,
+ loadAll,
+ loadRoleDetail,
+ loadPermissionDetail,
+ getRoleById,
+ getPermissionById,
+ getChildRoles,
+ getRolePermissionList,
+ getInheritedPermissionList,
+ upsertRole,
+ removeRole,
+ upsertPermission,
+ removePermission,
+ setRolePermissionList
+ };
+});
diff --git a/src/store/settingStore.ts b/src/store/settingStore.ts
new file mode 100644
index 0000000..3a060cb
--- /dev/null
+++ b/src/store/settingStore.ts
@@ -0,0 +1,232 @@
+import scanSuccessSoundUrl from "@/assets/sound/scan-success.mp3";
+import registrationSuccessSoundUrl from "@/assets/sound/registration-success.mp3";
+
+export interface SoundSetting {
+ scanSuccess: boolean;
+ registerSuccess: boolean;
+ volume: number;
+}
+
+type SoundType = "scanSuccess" | "registerSuccess";
+
+const SOUND_STORAGE_KEY = "gao-customer-h5:sound";
+const soundUrlMap: Record = {
+ scanSuccess: scanSuccessSoundUrl,
+ registerSuccess: registrationSuccessSoundUrl
+};
+// Windows 某些设备链路对极短提示音的起音处理不稳定,直接播放会偏小。
+// 这里先补一段极低音量的预热头,把输出链路“叫醒”后再接原音效。
+const SCAN_SUCCESS_WARMUP_HEAD_MS = 120;
+const SCAN_SUCCESS_WARMUP_GAIN = .08;
+
+function createDefaultSoundSetting(): SoundSetting {
+ return {
+ scanSuccess: true,
+ registerSuccess: true,
+ volume: 70
+ };
+}
+
+function readStoredSoundSetting(): SoundSetting {
+ const rawValue = localStorage.getItem(SOUND_STORAGE_KEY);
+ if (!rawValue) {
+ return createDefaultSoundSetting();
+ }
+
+ try {
+ const parsedValue = JSON.parse(rawValue) as Partial;
+ const volume = Number(parsedValue.volume);
+ return {
+ scanSuccess: parsedValue.scanSuccess !== false,
+ registerSuccess: parsedValue.registerSuccess !== false,
+ volume: Number.isFinite(volume) ? Math.min(100, Math.max(0, volume)) : 70
+ };
+ } catch {
+ return createDefaultSoundSetting();
+ }
+}
+
+export const useSettingStore = defineStore("setting", () => {
+ const sound = ref(readStoredSoundSetting());
+ const soundPlayerMap = shallowRef | null>(null);
+ const audioContext = shallowRef(null);
+ const scanSuccessBuffer = shallowRef(null);
+ const activeScanSuccessSource = shallowRef(null);
+ const soundUnlocked = ref(false);
+
+ function setSound(value: Partial): void {
+ sound.value = {
+ scanSuccess: value.scanSuccess ?? sound.value.scanSuccess,
+ registerSuccess: value.registerSuccess ?? sound.value.registerSuccess,
+ volume: Math.min(100, Math.max(0, value.volume ?? sound.value.volume))
+ };
+ localStorage.setItem(SOUND_STORAGE_KEY, JSON.stringify(sound.value));
+ applySoundVolume();
+ }
+
+ function loadSoundPlayers(): void {
+ if (soundPlayerMap.value) {
+ return;
+ }
+
+ soundPlayerMap.value = {
+ scanSuccess: createSoundPlayer(soundUrlMap.scanSuccess),
+ registerSuccess: createSoundPlayer(soundUrlMap.registerSuccess)
+ };
+ applySoundVolume();
+ }
+
+ function getAudioContext(): AudioContext {
+ if (audioContext.value) {
+ return audioContext.value;
+ }
+
+ audioContext.value = new window.AudioContext();
+ return audioContext.value;
+ }
+
+ function createSoundPlayer(url: string): HTMLAudioElement {
+ const player = new Audio(url);
+ player.preload = "auto";
+ player.load();
+ return player;
+ }
+
+ function applySoundVolume(): void {
+ if (!soundPlayerMap.value) {
+ return;
+ }
+
+ const volume = sound.value.volume / 100;
+ Object.values(soundPlayerMap.value).forEach((player) => {
+ player.volume = volume;
+ });
+ }
+
+ async function unlockSoundPlayers(): Promise {
+ loadSoundPlayers();
+ if (soundUnlocked.value || !soundPlayerMap.value) {
+ return soundUnlocked.value;
+ }
+
+ try {
+ await getAudioContext().resume();
+ for (const player of Object.values(soundPlayerMap.value)) {
+ player.muted = true;
+ player.volume = 0;
+ player.currentTime = 0;
+ await player.play();
+ player.pause();
+ player.currentTime = 0;
+ player.muted = false;
+ }
+ applySoundVolume();
+ soundUnlocked.value = true;
+ return true;
+ } catch {
+ Object.values(soundPlayerMap.value).forEach((player) => {
+ player.muted = false;
+ });
+ applySoundVolume();
+ return false;
+ }
+ }
+
+ async function loadScanSuccessBuffer(): Promise {
+ if (scanSuccessBuffer.value) {
+ return scanSuccessBuffer.value;
+ }
+
+ const response = await fetch(soundUrlMap.scanSuccess);
+ const arrayBuffer = await response.arrayBuffer();
+ scanSuccessBuffer.value = await getAudioContext().decodeAudioData(arrayBuffer.slice(0));
+ return scanSuccessBuffer.value;
+ }
+
+ async function playScanSuccessBufferSound(): Promise {
+ const context = getAudioContext();
+ if (context.state === "suspended") {
+ await context.resume();
+ }
+
+ activeScanSuccessSource.value?.stop();
+ activeScanSuccessSource.value?.disconnect();
+
+ const source = context.createBufferSource();
+ const gainNode = context.createGain();
+ source.buffer = await buildScanSuccessPlaybackBuffer();
+ gainNode.gain.value = sound.value.volume / 100;
+ source.connect(gainNode);
+ gainNode.connect(context.destination);
+ source.onended = () => {
+ if (activeScanSuccessSource.value === source) {
+ activeScanSuccessSource.value = null;
+ }
+ source.disconnect();
+ gainNode.disconnect();
+ };
+ activeScanSuccessSource.value = source;
+ source.start(0);
+ }
+
+ async function buildScanSuccessPlaybackBuffer(): Promise {
+ const sourceBuffer = await loadScanSuccessBuffer();
+ const context = getAudioContext();
+ const warmupFrameCount = Math.max(1, Math.round(context.sampleRate * SCAN_SUCCESS_WARMUP_HEAD_MS / 1000));
+ const outputBuffer = context.createBuffer(
+ sourceBuffer.numberOfChannels,
+ sourceBuffer.length + warmupFrameCount,
+ sourceBuffer.sampleRate
+ );
+
+ for (let channelIndex = 0; channelIndex < sourceBuffer.numberOfChannels; channelIndex += 1) {
+ const outputData = outputBuffer.getChannelData(channelIndex);
+ const sourceData = sourceBuffer.getChannelData(channelIndex);
+ const warmupSourceLength = Math.min(sourceData.length, warmupFrameCount);
+ // 预热头不能是纯静音;纯静音对这类 Windows 问题无效。
+ for (let frameIndex = 0; frameIndex < warmupFrameCount; frameIndex += 1) {
+ const sourceIndex = frameIndex % warmupSourceLength;
+ outputData[frameIndex] = sourceData[sourceIndex] * SCAN_SUCCESS_WARMUP_GAIN;
+ }
+ outputData.set(sourceData, warmupFrameCount);
+ }
+
+ return outputBuffer;
+ }
+
+ async function playSound(type: SoundType): Promise {
+ if (type === "scanSuccess") {
+ await playScanSuccessBufferSound();
+ return;
+ }
+
+ loadSoundPlayers();
+ if (!sound.value[type] || !soundPlayerMap.value) {
+ return;
+ }
+
+ const player = soundPlayerMap.value[type];
+ player.pause();
+ player.muted = false;
+ player.volume = sound.value.volume / 100;
+ player.currentTime = 0;
+ await player.play();
+ }
+
+ async function playScanSuccessSound(): Promise {
+ await playSound("scanSuccess");
+ }
+
+ async function playRegisterSuccessSound(): Promise {
+ await playSound("registerSuccess");
+ }
+
+ return {
+ sound,
+ setSound,
+ loadSoundPlayers,
+ unlockSoundPlayers,
+ playScanSuccessSound,
+ playRegisterSuccessSound
+ };
+});
diff --git a/src/store/tabBarStore.ts b/src/store/tabBarStore.ts
new file mode 100644
index 0000000..206c7b9
--- /dev/null
+++ b/src/store/tabBarStore.ts
@@ -0,0 +1,9 @@
+export const useTabBarStore = defineStore("tab-bar", () => {
+ const router = useRouter();
+
+ const isShowing = computed(() => !!router.currentRoute.value.meta.tabBarVisible);
+
+ return {
+ isShowing
+ };
+});
diff --git a/src/styles/global.less b/src/styles/global.less
new file mode 100644
index 0000000..0cb3bb2
--- /dev/null
+++ b/src/styles/global.less
@@ -0,0 +1,39 @@
+html,
+body,
+#root {
+ --td-swiper-border-radius: 0;
+
+ height: 100%;
+ min-height: 100vh;
+}
+
+html {
+ color-scheme: light;
+ background: #F5F5F8;
+}
+
+html.theme-dark {
+ color-scheme: dark;
+ background: #10161f;
+}
+
+body {
+ margin: 0;
+ color: #111827;
+ background: #F5F5F8;
+ font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
+ transition: background .2s ease, color .2s ease;
+}
+
+html.theme-dark body {
+ color: #f3f4f6;
+ background: #10161f;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+.t-form__label {
+ color: #555;
+}
diff --git a/src/styles/tdesign-custom.css b/src/styles/tdesign-custom.css
new file mode 100644
index 0000000..fa57999
--- /dev/null
+++ b/src/styles/tdesign-custom.css
@@ -0,0 +1,284 @@
+:root, :root[theme-mode="light"] {
+ --td-brand-color-1: #ebf9f6;
+ --td-brand-color-2: #ceebe6;
+ --td-brand-color-3: #a4d5ce;
+ --td-brand-color-4: #76bbb3;
+ --td-brand-color-5: #559f97;
+ --td-brand-color-6: #29857d;
+ --td-brand-color-7: #0f766e;
+ --td-brand-color-8: #00524b;
+ --td-brand-color-9: #003b36;
+ --td-brand-color-10: #002723;
+ --td-warning-color-1: #fff1e9;
+ --td-warning-color-2: #ffd9c2;
+ --td-warning-color-3: #ffb98c;
+ --td-warning-color-4: #fa9550;
+ --td-warning-color-5: #e37318;
+ --td-warning-color-6: #be5a00;
+ --td-warning-color-7: #954500;
+ --td-warning-color-8: #713300;
+ --td-warning-color-9: #532300;
+ --td-warning-color-10: #3b1700;
+ --td-error-color-1: #fff0ed;
+ --td-error-color-2: #ffd8d2;
+ --td-error-color-3: #ffb9b0;
+ --td-error-color-4: #ff9285;
+ --td-error-color-5: #f6685d;
+ --td-error-color-6: #d54941;
+ --td-error-color-7: #ad352f;
+ --td-error-color-8: #881f1c;
+ --td-error-color-9: #68070a;
+ --td-error-color-10: #490002;
+ --td-success-color-1: #e3f9e9;
+ --td-success-color-2: #c6f3d7;
+ --td-success-color-3: #92dab2;
+ --td-success-color-4: #56c08d;
+ --td-success-color-5: #2ba471;
+ --td-success-color-6: #008858;
+ --td-success-color-7: #006c45;
+ --td-success-color-8: #005334;
+ --td-success-color-9: #003b23;
+ --td-success-color-10: #002515;
+ --td-gray-color-1: #f6f6f6;
+ --td-gray-color-2: #eeeceb;
+ --td-gray-color-3: #dddbdb;
+ --td-gray-color-4: #cac9c9;
+ --td-gray-color-5: #b6b6b6;
+ --td-gray-color-6: #a2a2a2;
+ --td-gray-color-7: #8f8f8f;
+ --td-gray-color-8: #7b7c7c;
+ --td-gray-color-9: #6a6b6b;
+ --td-gray-color-10: #585a5a;
+ --td-gray-color-11: #494a4a;
+ --td-gray-color-12: #3a3b3b;
+ --td-gray-color-13: #2c2e2e;
+ --td-gray-color-14: #202222;
+ --td-font-white-1: rgba(255, 255, 255, 1);
+ --td-font-white-2: rgba(255, 255, 255, .55);
+ --td-font-white-3: rgba(255, 255, 255, .35);
+ --td-font-white-4: rgba(255, 255, 255, .22);
+ --td-font-gray-1: rgba(0, 0, 0, .9);
+ --td-font-gray-2: rgba(0, 0, 0, .6);
+ --td-font-gray-3: rgba(0, 0, 0, .4);
+ --td-font-gray-4: rgba(0, 0, 0, .26);
+ --td-brand-color: var(--td-brand-color-7);
+ --td-warning-color: var(--td-warning-color-5);
+ --td-error-color: var(--td-error-color-6);
+ --td-success-color: var(--td-success-color-5);
+ --td-brand-color-focus: var(--td-brand-color-1);
+ --td-brand-color-active: var(--td-brand-color-8);
+ --td-brand-color-disabled: var(--td-brand-color-3);
+ --td-brand-color-light: var(--td-brand-color-1);
+ --td-brand-color-light-active: var(--td-brand-color-2);
+ --td-warning-color-active: var(--td-warning-color-6);
+ --td-warning-color-disabled: var(--td-warning-color-3);
+ --td-warning-color-focus: var(--td-warning-color-2);
+ --td-warning-color-light: var(--td-warning-color-1);
+ --td-warning-color-light-active: var(--td-warning-color-2);
+ --td-error-color-focus: var(--td-error-color-2);
+ --td-error-color-active: var(--td-error-color-7);
+ --td-error-color-disabled: var(--td-error-color-3);
+ --td-error-color-light: var(--td-error-color-1);
+ --td-error-color-light-active: var(--td-error-color-2);
+ --td-success-color-focus: var(--td-success-color-2);
+ --td-success-color-active: var(--td-success-color-6);
+ --td-success-color-disabled: var(--td-success-color-3);
+ --td-success-color-light: var(--td-success-color-1);
+ --td-success-color-light-active: var(--td-success-color-2);
+ --td-mask-active: rgba(0, 0, 0, .6);
+ --td-mask-disabled: rgba(255, 255, 255, .6);
+ --td-bg-color-page: var(--td-gray-color-1);
+ --td-bg-color-container: var(--td-font-white-1);
+ --td-bg-color-container-active: var(--td-gray-color-3);
+ --td-bg-color-secondarycontainer: var(--td-gray-color-1);
+ --td-bg-color-secondarycontainer-active: var(--td-gray-color-4);
+ --td-bg-color-component: var(--td-gray-color-3);
+ --td-bg-color-component-active: var(--td-gray-color-6);
+ --td-bg-color-component-disabled: var(--td-gray-color-2);
+ --td-bg-color-secondarycomponent: var(--td-gray-color-4);
+ --td-bg-color-secondarycomponent-active: var(--td-gray-color-6);
+ --td-bg-color-specialcomponent: #fff;
+ --td-text-color-primary: var(--td-font-gray-1);
+ --td-text-color-secondary: var(--td-font-gray-2);
+ --td-text-color-placeholder: var(--td-font-gray-3);
+ --td-text-color-disabled: var(--td-font-gray-4);
+ --td-text-color-anti: var(--td-font-white-1);
+ --td-text-color-brand: var(--td-brand-color);
+ --td-text-color-link: var(--td-brand-color);
+ --td-border-level-1-color: var(--td-gray-color-3);
+ --td-component-stroke: var(--td-gray-color-3);
+ --td-border-level-2-color: var(--td-gray-color-4);
+ --td-component-border: var(--td-gray-color-4);
+ --td-shadow-1: 0 1px 6px rgba(0, 0, 0, 0.05),0 3px 4px rgba(0, 0, 0, 0.04),0 1px 2px -1px rgba(0, 0, 0, 0.08);
+ --td-shadow-2: 0 3px 10px 2px rgba(0, 0, 0, 0.04),0 6px 8px rgba(0, 0, 0, 0.05),0 4px 4px -2px rgba(0, 0, 0, 0.08);
+ --td-shadow-3: 0 4px 18px 5px rgba(0, 0, 0, 0.05),0 10px 9px 2px rgba(0, 0, 0, 0.04),0 3px 5px -3px rgba(0, 0, 0, 0.08);
+ --td-shadow-4: 0 2px 8px 0 rgba(0, 0, 0, 6%);
+ --td-shadow-inset-top: inset 0 .5px 0 #dcdcdc;
+ --td-shadow-inset-right: inset .5px 0 0 #dcdcdc;
+ --td-shadow-inset-bottom: inset 0 -.5px 0 #dcdcdc;
+ --td-shadow-inset-left: inset -.5px 0 0 #dcdcdc;
+ --td-table-shadow-color: rgba(0, 0, 0, .08);
+ --td-scrollbar-color: rgba(0, 0, 0, .1);
+ --td-scrollbar-hover-color: rgba(0, 0, 0, .3);
+ --td-scroll-track-color: #fff;
+}
+
+:root.dark, :root[theme-mode="dark"] {
+ --td-brand-color-1: #002723;
+ --td-brand-color-2: #003b36;
+ --td-brand-color-3: #00524b;
+ --td-brand-color-4: #0f766e;
+ --td-brand-color-5: #29857d;
+ --td-brand-color-6: #559f97;
+ --td-brand-color-7: #76bbb3;
+ --td-brand-color-8: #a4d5ce;
+ --td-brand-color-9: #ceebe6;
+ --td-brand-color-10: #ebf9f6;
+ --td-warning-color-1: #4f2a1d;
+ --td-warning-color-2: #582f21;
+ --td-warning-color-3: #733c23;
+ --td-warning-color-4: #a75d2b;
+ --td-warning-color-5: #cf6e2d;
+ --td-warning-color-6: #dc7633;
+ --td-warning-color-7: #e8935c;
+ --td-warning-color-8: #ecbf91;
+ --td-warning-color-9: #eed7bf;
+ --td-warning-color-10: #f3e9dc;
+ --td-error-color-1: #472324;
+ --td-error-color-2: #5e2a2d;
+ --td-error-color-3: #703439;
+ --td-error-color-4: #83383e;
+ --td-error-color-5: #a03f46;
+ --td-error-color-6: #c64751;
+ --td-error-color-7: #de6670;
+ --td-error-color-8: #ec888e;
+ --td-error-color-9: #edb1b6;
+ --td-error-color-10: #eeced0;
+ --td-success-color-1: #193a2a;
+ --td-success-color-2: #1a4230;
+ --td-success-color-3: #17533d;
+ --td-success-color-4: #0d7a55;
+ --td-success-color-5: #059465;
+ --td-success-color-6: #43af8a;
+ --td-success-color-7: #46bf96;
+ --td-success-color-8: #80d2b6;
+ --td-success-color-9: #b4e1d3;
+ --td-success-color-10: #deede8;
+ --td-gray-color-1: #f6f6f6;
+ --td-gray-color-2: #eeeceb;
+ --td-gray-color-3: #dddbdb;
+ --td-gray-color-4: #cac9c9;
+ --td-gray-color-5: #b6b6b6;
+ --td-gray-color-6: #a2a2a2;
+ --td-gray-color-7: #8f8f8f;
+ --td-gray-color-8: #7b7c7c;
+ --td-gray-color-9: #6a6b6b;
+ --td-gray-color-10: #585a5a;
+ --td-gray-color-11: #494a4a;
+ --td-gray-color-12: #3a3b3b;
+ --td-gray-color-13: #2c2e2e;
+ --td-gray-color-14: #202222;
+ --td-font-white-1: rgba(255, 255, 255, .9);
+ --td-font-white-2: rgba(255, 255, 255, .55);
+ --td-font-white-3: rgba(255, 255, 255, .35);
+ --td-font-white-4: rgba(255, 255, 255, .22);
+ --td-font-gray-1: rgba(0, 0, 0, .9);
+ --td-font-gray-2: rgba(0, 0, 0, .6);
+ --td-font-gray-3: rgba(0, 0, 0, .4);
+ --td-font-gray-4: rgba(0, 0, 0, .26);
+ --td-brand-color: var(--td-brand-color-6);
+ --td-warning-color: var(--td-warning-color-5);
+ --td-error-color: var(--td-error-color-6);
+ --td-success-color: var(--td-success-color-5);
+ --td-brand-color-focus: var(--td-brand-color-1);
+ --td-brand-color-active: var(--td-brand-color-7);
+ --td-brand-color-disabled: var(--td-brand-color-3);
+ --td-brand-color-light: var(--td-brand-color-1);
+ --td-brand-color-light-active: var(--td-brand-color-2);
+ --td-warning-color-focus: var(--td-warning-color-2);
+ --td-warning-color-active: var(--td-warning-color-4);
+ --td-warning-color-disabled: var(--td-warning-color-3);
+ --td-warning-color-light: var(--td-warning-color-1);
+ --td-warning-color-light-active: var(--td-warning-color-2);
+ --td-error-color-focus: var(--td-error-color-2);
+ --td-error-color-active: var(--td-error-color-5);
+ --td-error-color-disabled: var(--td-error-color-3);
+ --td-error-color-light: var(--td-error-color-1);
+ --td-error-color-light-active: var(--td-error-color-2);
+ --td-success-color-focus: var(--td-success-color-2);
+ --td-success-color-active: var(--td-success-color-4);
+ --td-success-color-disabled: var(--td-success-color-3);
+ --td-success-color-light: var(--td-success-color-1);
+ --td-success-color-light-active: var(--td-success-color-2);
+ --td-mask-active: rgba(0, 0, 0, .4);
+ --td-mask-disabled: rgba(0, 0, 0, .6);
+ --td-bg-color-page: var(--td-gray-color-14);
+ --td-bg-color-container: var(--td-gray-color-13);
+ --td-bg-color-secondarycontainer: var(--td-gray-color-12);
+ --td-bg-color-component: var(--td-gray-color-11);
+ --td-bg-color-container-active: var(--td-gray-color-12);
+ --td-bg-color-secondarycontainer-active: var(--td-gray-color-11);
+ --td-bg-color-component-active: var(--td-gray-color-10);
+ --td-bg-color-component-disabled: var(--td-gray-color-12);
+ --td-bg-color-specialcomponent: transparent;
+ --td-text-color-primary: var(--td-font-white-1);
+ --td-text-color-secondary: var(--td-font-white-2);
+ --td-text-color-placeholder: var(--td-font-white-3);
+ --td-text-color-disabled: var(--td-font-white-4);
+ --td-text-color-anti: var(--td-font-white-1);
+ --td-text-color-brand: var(--td-brand-color-8);
+ --td-text-color-link: var(--td-brand-color-8);
+ --td-border-level-1-color: var(--td-gray-color-11);
+ --td-component-stroke: var(--td-gray-color-11);
+ --td-border-level-2-color: var(--td-gray-color-9);
+ --td-component-border: var(--td-gray-color-9);
+ --td-shadow-1: 0 1px 6px rgba(0, 0, 0, 0.05),0 3px 4px rgba(0, 0, 0, 0.04),0 1px 2px -1px rgba(0, 0, 0, 0.08);
+ --td-shadow-2: 0 3px 10px 2px rgba(0, 0, 0, 0.04),0 6px 8px rgba(0, 0, 0, 0.05),0 4px 4px -2px rgba(0, 0, 0, 0.08);
+ --td-shadow-3: 0 4px 18px 5px rgba(0, 0, 0, 0.05),0 10px 9px 2px rgba(0, 0, 0, 0.04),0 3px 5px -3px rgba(0, 0, 0, 0.08);
+ --td-shadow-inset-top: inset 0 .5px 0 #5e5e5e;
+ --td-shadow-inset-right: inset .5px 0 0 #5e5e5e;
+ --td-shadow-inset-bottom: inset 0 -.5px 0 #5e5e5e;
+ --td-shadow-inset-left: inset -.5px 0 0 #5e5e5e;
+ --td-table-shadow-color: rgba(0, 0, 0, .55);
+ --td-scrollbar-color: rgba(255, 255, 255, .1);
+ --td-scroll-track-color: #333;
+}
+
+:root {
+ --td-font-family: pingfang sc, microsoft yahei, arial regular;
+ --td-font-family-medium: pingfang sc, microsoft yahei, arial medium;
+ --td-font-size-link-small: 12px;
+ --td-font-size-link-medium: 14px;
+ --td-font-size-link-large: 16px;
+ --td-font-size-mark-extraSmall: 10px;
+ --td-font-size-mark-small: 12px;
+ --td-font-size-mark-medium: 14px;
+ --td-font-size-mark-large: 16px;
+ --td-font-size-body-extraSmall: 10px;
+ --td-font-size-body-small: 12px;
+ --td-font-size-body-medium: 14px;
+ --td-font-size-body-large: 16px;
+ --td-font-size-title-small: 14px;
+ --td-font-size-title-medium: 16px;
+ --td-font-size-title-large: 18px;
+ --td-font-size-title-extraLarge: 20px;
+ --td-font-size-headline-small: 24px;
+ --td-font-size-headline-medium: 28px;
+ --td-font-size-headline-large: 36px;
+ --td-font-size-display-medium: 48px;
+ --td-font-size-display-large: 64px;
+ --td-font-size: 10px;
+ --td-font-size-xs: var(--td-font-size-body-extraSmall);
+ --td-font-size-s: var(--td-font-size-body-small);
+ --td-font-size-base: var(--td-font-size-title-small);
+ --td-font-size-m: var(--td-font-size-title-medium);
+ --td-font-size-l: var(--td-font-size-title-large);
+ --td-font-size-xl: var(--td-font-size-title-extraLarge);
+ --td-font-size-xxl: var(--td-font-size-headline-large);
+ --td-radius-small: 4px;
+ --td-radius-default: 6px;
+ --td-radius-large: 18px;
+ --td-radius-extraLarge: 24px;
+ --td-radius-round: 999px;
+ --td-radius-circle: 50%;
+}
diff --git a/src/types/Customer.ts b/src/types/Customer.ts
new file mode 100644
index 0000000..73f0c97
--- /dev/null
+++ b/src/types/Customer.ts
@@ -0,0 +1,60 @@
+import type { Attachment, Model, User } from "timi-web";
+
+export type CustomerGender = "MALE" | "FEMALE";
+
+export type BodyAreaValue = {
+ selectedCodeList: string[];
+};
+
+export type Customer = {
+ code?: string;
+ name?: string;
+ gender?: CustomerGender;
+ age?: number;
+ telephone?: string;
+ address?: string;
+ remark?: string;
+ disease?: string;
+ conditioningPart?: BodyAreaValue;
+ introducerCustomerId?: string;
+ creatorUserId?: string;
+ lastSignInAt?: number;
+ introducerCustomer?: Customer;
+ creatorUser?: Partial;
+ invitedCount?: number;
+ attachmentList?: Attachment[];
+ attachmentIdList?: string[];
+} & Model;
+
+export type CustomerSearchReq = {
+ keyword?: string;
+ introducerCustomerId?: string;
+};
+
+export type CustomerTrendStatReq = {
+ beginCreatedAt: number;
+ endCreatedAt: number;
+};
+
+export type CustomerDailyStatView = {
+ dateValue?: number;
+ newCustomerCount?: number;
+ totalCustomerCount?: number;
+};
+
+export type CustomerGenderStatView = {
+ genderCode?: CustomerGender | "UNKNOWN";
+ count?: number;
+};
+
+export type CustomerInviteUpdateReq = {
+ customerId: string;
+ introducerCustomerId?: string;
+};
+
+export type QuickRegisterReq = {
+ customerCode: string;
+ registrationEventId: string;
+ remark?: string;
+ attachmentIdList?: string[];
+};
diff --git a/src/types/GaoUser.ts b/src/types/GaoUser.ts
new file mode 100644
index 0000000..627f194
--- /dev/null
+++ b/src/types/GaoUser.ts
@@ -0,0 +1,10 @@
+import type { Model, Role, User } from "timi-web";
+
+export type GaoUser = {
+ userId?: string;
+ enabled?: boolean;
+ remark?: string;
+ user?: Partial;
+ roleList?: Array;
+ roleIdList?: string[];
+} & Model;
diff --git a/src/types/RegistrationEvent.ts b/src/types/RegistrationEvent.ts
new file mode 100644
index 0000000..0471d4e
--- /dev/null
+++ b/src/types/RegistrationEvent.ts
@@ -0,0 +1,18 @@
+import type { Model } from "timi-web";
+
+export type RegistrationEventStatus = "ACTIVE" | "INACTIVE" | "DELETED";
+
+export type RegistrationLimitType = "NONE" | "DAILY_HALF_DAY" | "NATURAL_DAY" | "INTERVAL_HOUR" | "NATURAL_MONTH" | "TOTAL_LIMIT";
+
+export type RegistrationEvent = {
+ name: string;
+ description?: string;
+ color?: string;
+ status?: RegistrationEventStatus;
+ enabled?: boolean;
+ requirePhoto?: boolean;
+ limitType?: RegistrationLimitType;
+ limitValue?: number;
+ sort?: number;
+ roleCodeList?: string[];
+} & Model;
diff --git a/src/types/RegistrationEventRecord.ts b/src/types/RegistrationEventRecord.ts
new file mode 100644
index 0000000..7aa87f0
--- /dev/null
+++ b/src/types/RegistrationEventRecord.ts
@@ -0,0 +1,81 @@
+import type { Attachment, Model, User } from "timi-web";
+import type { Customer } from "@/types/Customer";
+import type { RegistrationEvent } from "@/types/RegistrationEvent";
+
+export type RegistrationEventRecord = {
+ customerId?: string;
+ registrationEventId?: string;
+ operatorUserId?: string;
+ remark?: string;
+ registeredAt?: number;
+ customer?: Customer;
+ registrationEvent?: RegistrationEvent;
+ operator?: Partial;
+ attachmentList?: Array>;
+ attachmentIdList?: string[];
+} & Model;
+
+export type RegistrationEventRecordListItemView = {
+ id?: string;
+ customerId?: string;
+ customerName?: string;
+ customerPhotoAttachmentId?: string;
+ registrationEventId?: string;
+ registrationEventName?: string;
+ registeredAt?: number;
+};
+
+export type RegistrationEventRecordRangeReq = {
+ customerId?: string;
+ registrationEventId?: string;
+ registrationEventIdList?: string[];
+ keyword?: string;
+ beginRegisteredAt: number;
+ endRegisteredAt: number;
+};
+
+export type RegistrationEventRecordStatReq = {
+ customerId?: string;
+ beginRegisteredAt: number;
+ endRegisteredAt: number;
+};
+
+export type RegistrationEventRecordTrendStatReq = {
+ customerId?: string;
+ registrationEventId: string;
+ beginRegisteredAt: number;
+ endRegisteredAt: number;
+};
+
+export type CustomerRegisterStatView = {
+ customerId?: string;
+ customerName?: string;
+ registrationEventId?: string;
+ registrationEventName?: string;
+ count?: number;
+ latestRegisteredAt?: number;
+};
+
+export type RegistrationEventRecordDailyStatView = {
+ dateValue?: number;
+ dailyCount?: number;
+ totalCount?: number;
+};
+
+export type RegistrationEventRecordCalendarView = {
+ id?: string;
+ customerId?: string;
+ customerCode?: string;
+ customerName?: string;
+ registrationEventId?: string;
+ registeredAt?: number;
+};
+
+export type RegistrationEventRecordCreateReq = {
+ customerId?: string;
+ customerCode?: string;
+ registrationEventId: string;
+ remark?: string;
+ registeredAt?: number;
+ attachmentIdList?: string[];
+};
diff --git a/src/types/browser-image-compression.d.ts b/src/types/browser-image-compression.d.ts
new file mode 100644
index 0000000..049a8ea
--- /dev/null
+++ b/src/types/browser-image-compression.d.ts
@@ -0,0 +1,18 @@
+declare module "browser-image-compression" {
+ export interface ImageCompressionOptions {
+ alwaysKeepResolution?: boolean;
+ exifOrientation?: number;
+ fileType?: string;
+ initialQuality?: number;
+ libURL?: string;
+ maxIteration?: number;
+ maxSizeMB?: number;
+ maxWidthOrHeight?: number;
+ onProgress?: (progress: number) => void;
+ preserveExif?: boolean;
+ signal?: AbortSignal;
+ useWebWorker?: boolean;
+ }
+
+ export default function imageCompression(file: File, options: ImageCompressionOptions): Promise;
+}
diff --git a/src/utils/customer.ts b/src/utils/customer.ts
new file mode 100644
index 0000000..51ffa09
--- /dev/null
+++ b/src/utils/customer.ts
@@ -0,0 +1,32 @@
+import { AttachmentAPI } from "timi-web";
+import type { BodyAreaValue, Customer } from "@/types/Customer";
+
+export function getCustomerPhotoURL(customer?: Customer): string {
+ const attachment = customer?.attachmentList?.find(item => item.attachType === "PHOTO") || customer?.attachmentList?.[0];
+ if (!attachment?.id) {
+ return "";
+ }
+
+ return AttachmentAPI.getReadURL(attachment.id);
+}
+
+export function createBodyAreaValue(): BodyAreaValue {
+ return {
+ selectedCodeList: []
+ };
+}
+
+export function normalizeBodyAreaValue(value: unknown): BodyAreaValue {
+ if (!value || typeof value !== "object") {
+ return createBodyAreaValue();
+ }
+
+ const raw = value as Partial;
+ if (!Array.isArray(raw.selectedCodeList)) {
+ return createBodyAreaValue();
+ }
+
+ return {
+ selectedCodeList: raw.selectedCodeList.map(item => String(item).trim()).filter(Boolean)
+ };
+}
diff --git a/src/utils/gaoPermission.ts b/src/utils/gaoPermission.ts
new file mode 100644
index 0000000..f11ebdc
--- /dev/null
+++ b/src/utils/gaoPermission.ts
@@ -0,0 +1,78 @@
+export const gaoPermissionCodes = {
+ customer: {
+ create: "GAO:CUSTOMER:CREATE",
+ read: "GAO:CUSTOMER:READ",
+ update: "GAO:CUSTOMER:UPDATE",
+ delete: "GAO:CUSTOMER:DELETE"
+ },
+ registrationEvent: {
+ create: "GAO:REGISTRATION_EVENT:CREATE",
+ read: "GAO:REGISTRATION_EVENT:READ",
+ update: "GAO:REGISTRATION_EVENT:UPDATE",
+ delete: "GAO:REGISTRATION_EVENT:DELETE"
+ },
+ registrationEventRecord: {
+ create: "GAO:REGISTRATION_EVENT_RECORD:CREATE",
+ read: "GAO:REGISTRATION_EVENT_RECORD:READ",
+ update: "GAO:REGISTRATION_EVENT_RECORD:UPDATE",
+ delete: "GAO:REGISTRATION_EVENT_RECORD:DELETE"
+ },
+ stat: {
+ read: "GAO:STAT:READ"
+ },
+ user: {
+ create: "GAO:USER:CREATE",
+ read: "GAO:USER:READ",
+ update: "GAO:USER:UPDATE",
+ delete: "GAO:USER:DELETE"
+ },
+ qrCode: {
+ create: "GAO:QR_CODE:CREATE"
+ }
+} as const;
+
+export const corePermissionCodes = {
+ role: {
+ create: "CORE:ROLE:CREATE",
+ read: "CORE:ROLE:READ",
+ update: "CORE:ROLE:UPDATE",
+ delete: "CORE:ROLE:DELETE"
+ },
+ permission: {
+ create: "CORE:PERMISSION:CREATE",
+ read: "CORE:PERMISSION:READ",
+ update: "CORE:PERMISSION:UPDATE",
+ delete: "CORE:PERMISSION:DELETE"
+ },
+ rolePermission: {
+ create: "CORE:ROLE_PERMISSION:CREATE",
+ read: "CORE:ROLE_PERMISSION:READ",
+ delete: "CORE:ROLE_PERMISSION:DELETE"
+ },
+ roleRelation: {
+ create: "CORE:ROLE_RELATION:CREATE",
+ read: "CORE:ROLE_RELATION:READ",
+ delete: "CORE:ROLE_RELATION:DELETE"
+ },
+ userRole: {
+ create: "CORE:USER_ROLE:CREATE",
+ read: "CORE:USER_ROLE:READ",
+ delete: "CORE:USER_ROLE:DELETE"
+ }
+} as const;
+
+export const coreRoleCodes = {
+ admin: "CORE:ADMIN",
+ userRoleAdmin: "CORE:USER_ROLE_ADMIN"
+} as const;
+
+export const permissionManagementRoleAccess = {
+ value: [
+ coreRoleCodes.admin,
+ coreRoleCodes.userRoleAdmin
+ ],
+ mode: "or"
+} as const;
+
+export type GaoPermissionCodes = typeof gaoPermissionCodes;
+export type CorePermissionCodes = typeof corePermissionCodes;
diff --git a/src/utils/gaoRole.ts b/src/utils/gaoRole.ts
new file mode 100644
index 0000000..5b91003
--- /dev/null
+++ b/src/utils/gaoRole.ts
@@ -0,0 +1,70 @@
+import type { Role } from "@/store/permissionSettingsStore";
+import type { GaoUser } from "@/types/GaoUser";
+
+type GaoUserRole = NonNullable[number];
+
+function buildRoleCode(role: Role): string {
+ return role.moduleCode && !role.code.includes(":") ? `${role.moduleCode}:${role.code}` : role.code;
+}
+
+function getBareRoleCode(code: string): string {
+ const codePartList = code.split(":");
+ return codePartList[codePartList.length - 1] || code;
+}
+
+function findRole(role: GaoUserRole, roleList: Role[]): Role | undefined {
+ if (typeof role === "string") {
+ return roleList.find(roleItem => roleItem.code === role || buildRoleCode(roleItem) === role);
+ }
+ return roleList.find(roleItem => roleItem.id === role.id || roleItem.code === role.code || buildRoleCode(roleItem) === role.code);
+}
+
+function appendCompatibleRoleCode(roleCodeSet: Set, code: string): void {
+ if (!code) {
+ return;
+ }
+
+ roleCodeSet.add(code);
+ roleCodeSet.add(getBareRoleCode(code));
+}
+
+export function getGaoRoleName(role: GaoUserRole | undefined, roleList: Role[]): string {
+ if (!role) {
+ return "未配置角色";
+ }
+
+ const fullRole = findRole(role, roleList);
+ if (fullRole) {
+ return fullRole.name || fullRole.code || "未配置角色";
+ }
+
+ return typeof role === "string" ? getBareRoleCode(role) : role.name || role.code || "未配置角色";
+}
+
+export function buildEffectiveRoleCodeSet(user: GaoUser, roleList: Role[]): Set {
+ const roleCodeSet = new Set();
+ for (const role of user.roleList || []) {
+ const fullRole = findRole(role, roleList);
+ if (fullRole) {
+ appendRoleCode(roleCodeSet, fullRole, roleList, new Set());
+ continue;
+ }
+ appendCompatibleRoleCode(roleCodeSet, typeof role === "string" ? role : role.code);
+ }
+ return roleCodeSet;
+}
+
+function appendRoleCode(roleCodeSet: Set, role: Role, roleList: Role[], visitedRoleIds: Set): void {
+ if (!role.id || visitedRoleIds.has(role.id)) {
+ return;
+ }
+
+ visitedRoleIds.add(role.id);
+ appendCompatibleRoleCode(roleCodeSet, buildRoleCode(role));
+ for (const childRoleId of role.childRoleIdList) {
+ const childRole = roleList.find(item => item.id === childRoleId);
+ if (childRole) {
+ appendRoleCode(roleCodeSet, childRole, roleList, visitedRoleIds);
+ }
+ }
+}
diff --git a/src/utils/imageCompression.ts b/src/utils/imageCompression.ts
new file mode 100644
index 0000000..fb75190
--- /dev/null
+++ b/src/utils/imageCompression.ts
@@ -0,0 +1,27 @@
+import imageCompression from "browser-image-compression";
+
+const PHOTO_MAX_SIZE_MB = 300 / 1024;
+const PHOTO_MAX_WIDTH_OR_HEIGHT = 1920;
+
+/**
+ * 压缩上传图片,统一限制到 300 KB。
+ */
+export async function compressUploadImage(file: File): Promise {
+ return await imageCompression(file, {
+ maxSizeMB: PHOTO_MAX_SIZE_MB,
+ maxWidthOrHeight: PHOTO_MAX_WIDTH_OR_HEIGHT,
+ useWebWorker: true,
+ initialQuality: .86
+ });
+}
+
+/**
+ * 批量压缩上传图片。
+ */
+export async function compressUploadImageList(fileList: File[]): Promise {
+ const result: File[] = [];
+ for (const file of fileList) {
+ result.push(await compressUploadImage(file));
+ }
+ return result;
+}
diff --git a/src/utils/managementQrCode.ts b/src/utils/managementQrCode.ts
new file mode 100644
index 0000000..1fdee5b
--- /dev/null
+++ b/src/utils/managementQrCode.ts
@@ -0,0 +1,278 @@
+import { BarcodeFormat, EncodeHintType, QRCodeWriter } from "@zxing/library";
+
+export interface ManagementQrCodePage {
+ pageIndex: number;
+ codes: string[];
+}
+
+export interface DownloadManagementQrCodeOptions {
+ codes: string[];
+ filePrefix: string;
+ maxCodeLength?: number;
+}
+
+export interface PrintManagementQrCodeOptions {
+ codes: string[];
+ maxCodeLength?: number;
+ title?: string;
+}
+
+export interface ManagementQrCodeGrid {
+ rows: number;
+ columns: number;
+ pageSize: number;
+}
+
+const pageWidth = 2480;
+const pageHeight = 3508;
+const pagePadding = 80;
+const qrSize = 300;
+const minCellGap = 18;
+const codeFontSize = 34;
+const codeTopGap = 3;
+const gridLineWidth = 2;
+const codeTextHorizontalPadding = 28;
+const codeTextWidthRatio = .62;
+const qrWriter = new QRCodeWriter();
+const qrEncodeHints = new Map([
+ [EncodeHintType.ERROR_CORRECTION, "H"],
+ [EncodeHintType.CHARACTER_SET, "UTF-8"],
+ [EncodeHintType.MARGIN, 4]
+]);
+
+export function calculateManagementQrCodeGrid(maxCodeLength = 0): ManagementQrCodeGrid {
+ const codeTextMinWidth = Math.ceil(maxCodeLength * codeFontSize * codeTextWidthRatio + codeTextHorizontalPadding);
+ const cellMinWidth = Math.max(qrSize + minCellGap, codeTextMinWidth + minCellGap);
+ const cellMinHeight = qrSize + codeTopGap + codeFontSize + minCellGap;
+ const columns = Math.max(1, Math.floor((pageWidth - pagePadding * 2) / cellMinWidth));
+ const rows = Math.max(1, Math.floor((pageHeight - pagePadding * 2) / cellMinHeight));
+
+ return {
+ rows,
+ columns,
+ pageSize: rows * columns
+ };
+}
+
+export function splitManagementQrCodePages(codes: string[], maxCodeLength = 0): ManagementQrCodePage[] {
+ const pages: ManagementQrCodePage[] = [];
+ const pageSize = calculateManagementQrCodeGrid(maxCodeLength).pageSize;
+
+ for (let index = 0; index < codes.length; index += pageSize) {
+ pages.push({
+ pageIndex: pages.length,
+ codes: codes.slice(index, index + pageSize)
+ });
+ }
+
+ return pages;
+}
+
+export async function downloadManagementQrCodeImages(options: DownloadManagementQrCodeOptions): Promise {
+ const pages = splitManagementQrCodePages(options.codes, options.maxCodeLength);
+
+ for (const page of pages) {
+ const canvas = renderManagementQrCodePage(page.codes, options.maxCodeLength);
+ await downloadCanvas(canvas, `${options.filePrefix}-${String(page.pageIndex + 1).padStart(2, "0")}.png`);
+ }
+}
+
+export async function printManagementQrCodeImages(options: PrintManagementQrCodeOptions): Promise {
+ const printWindow = window.open("", "_blank");
+ if (!printWindow) {
+ throw new Error("浏览器阻止了打印窗口,请允许弹出窗口后重试");
+ }
+
+ const pages = splitManagementQrCodePages(options.codes, options.maxCodeLength);
+ const imageList = pages.map(page => renderManagementQrCodePage(page.codes, options.maxCodeLength).toDataURL("image/png"));
+ const title = options.title || "客户二维码打印";
+ const imageHTML = imageList.map(src => ``).join("");
+
+ printWindow.document.open();
+ printWindow.document.write(`
+
+
+
+ ${escapeHTML(title)}
+
+
+${imageHTML}
+`);
+ printWindow.document.close();
+ await waitPrintImagesLoaded(printWindow.document);
+ printWindow.focus();
+ printWindow.print();
+}
+
+function renderManagementQrCodePage(codes: string[], maxCodeLength = 0): HTMLCanvasElement {
+ const canvas = document.createElement("canvas");
+ canvas.width = pageWidth;
+ canvas.height = pageHeight;
+ const grid = calculateManagementQrCodeGrid(maxCodeLength);
+
+ const context = canvas.getContext("2d");
+ if (!context) {
+ throw new Error("当前浏览器不支持 Canvas");
+ }
+
+ context.fillStyle = "#ffffff";
+ context.fillRect(0, 0, pageWidth, pageHeight);
+ context.fillStyle = "#000000";
+ context.font = `500 ${codeFontSize}px Arial, sans-serif`;
+ context.textAlign = "center";
+ context.textBaseline = "top";
+
+ const cellWidth = (pageWidth - pagePadding * 2) / grid.columns;
+ const cellHeight = (pageHeight - pagePadding * 2) / grid.rows;
+
+ drawGridLines(context, grid, cellWidth, cellHeight);
+
+ codes.forEach((code, index) => {
+ const rowIndex = Math.floor(index / grid.columns);
+ const columnIndex = index % grid.columns;
+ const cellLeft = pagePadding + columnIndex * cellWidth;
+ const cellTop = pagePadding + rowIndex * cellHeight;
+ const qrLeft = Math.round(cellLeft + (cellWidth - qrSize) / 2);
+ const qrTop = Math.round(cellTop + (cellHeight - qrSize - codeTopGap - codeFontSize) / 2);
+
+ drawQrCode(context, code, qrLeft, qrTop, qrSize);
+ context.fillStyle = "#000000";
+ context.fillText(code, cellLeft + cellWidth / 2, qrTop + qrSize + codeTopGap);
+ });
+
+ return canvas;
+}
+
+async function waitPrintImagesLoaded(document: Document): Promise {
+ const imageList = Array.from(document.images);
+ await Promise.all(imageList.map(image => {
+ if (image.complete) {
+ return Promise.resolve();
+ }
+
+ return new Promise((resolve, reject) => {
+ image.onload = () => resolve();
+ image.onerror = () => reject(new Error("打印图片加载失败"));
+ });
+ }));
+}
+
+function escapeHTML(value: string): string {
+ return value
+ .replaceAll("&", "&")
+ .replaceAll("<", "<")
+ .replaceAll(">", ">")
+ .replaceAll("\"", """);
+}
+
+function drawGridLines(context: CanvasRenderingContext2D, grid: ManagementQrCodeGrid, cellWidth: number, cellHeight: number): void {
+ context.strokeStyle = "#d1d5db";
+ context.lineWidth = gridLineWidth;
+
+ for (let rowIndex = 0; rowIndex <= grid.rows; rowIndex++) {
+ const top = Math.round(pagePadding + rowIndex * cellHeight);
+ context.beginPath();
+ context.moveTo(pagePadding, top);
+ context.lineTo(pageWidth - pagePadding, top);
+ context.stroke();
+ }
+
+ for (let columnIndex = 0; columnIndex <= grid.columns; columnIndex++) {
+ const left = Math.round(pagePadding + columnIndex * cellWidth);
+ context.beginPath();
+ context.moveTo(left, pagePadding);
+ context.lineTo(left, pageHeight - pagePadding);
+ context.stroke();
+ }
+}
+
+function drawQrCode(context: CanvasRenderingContext2D, code: string, left: number, top: number, qrSize: number): void {
+ const matrix = qrWriter.encode(code, BarcodeFormat.QR_CODE, qrSize, qrSize, qrEncodeHints);
+ const width = matrix.getWidth();
+ const height = matrix.getHeight();
+ const sourceCanvas = document.createElement("canvas");
+ sourceCanvas.width = width;
+ sourceCanvas.height = height;
+ const sourceContext = sourceCanvas.getContext("2d");
+
+ if (!sourceContext) {
+ throw new Error("当前浏览器不支持 Canvas");
+ }
+
+ sourceContext.fillStyle = "#ffffff";
+ sourceContext.fillRect(0, 0, width, height);
+ sourceContext.fillStyle = "#000000";
+
+ for (let y = 0; y < height; y++) {
+ for (let x = 0; x < width; x++) {
+ if (matrix.get(x, y)) {
+ sourceContext.fillRect(x, y, 1, 1);
+ }
+ }
+ }
+
+ context.fillStyle = "#ffffff";
+ context.fillRect(left, top, qrSize, qrSize);
+ context.imageSmoothingEnabled = false;
+ context.drawImage(sourceCanvas, left, top, qrSize, qrSize);
+ context.imageSmoothingEnabled = true;
+}
+
+async function downloadCanvas(canvas: HTMLCanvasElement, fileName: string): Promise {
+ const blob = await new Promise((resolve, reject) => {
+ canvas.toBlob(result => {
+ if (result) {
+ resolve(result);
+ return;
+ }
+
+ reject(new Error("图片生成失败"));
+ }, "image/png");
+ });
+ const link = document.createElement("a");
+ const url = URL.createObjectURL(blob);
+
+ link.href = url;
+ link.download = fileName;
+ link.click();
+
+ await new Promise(resolve => {
+ window.setTimeout(resolve, 80);
+ });
+
+ URL.revokeObjectURL(url);
+}
diff --git a/src/utils/registrationEventRecord.ts b/src/utils/registrationEventRecord.ts
new file mode 100644
index 0000000..4590cd0
--- /dev/null
+++ b/src/utils/registrationEventRecord.ts
@@ -0,0 +1,11 @@
+import { AttachmentAPI } from "timi-web";
+import type { RegistrationEventRecord } from "@/types/RegistrationEventRecord";
+
+export function getRegistrationEventRecordPhotoURL(record?: RegistrationEventRecord): string {
+ const attachment = record?.attachmentList?.find(item => item.attachType === "PHOTO") || record?.attachmentList?.[0];
+ if (!attachment?.id) {
+ return "";
+ }
+
+ return AttachmentAPI.getReadURL(attachment.id);
+}
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..ae394ad
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,47 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": [
+ "src/*"
+ ],
+ "timi-web": [
+ "../timi-web/dist/src/index.d.ts"
+ ],
+ "timi-web/*": [
+ "../timi-web/dist/src/*"
+ ],
+ "vue": [
+ "node_modules/vue"
+ ],
+ "pinia": [
+ "node_modules/pinia"
+ ],
+ "vue-router": [
+ "node_modules/vue-router"
+ ]
+ },
+ "lib": [
+ "ES2021",
+ "DOM",
+ "DOM.Iterable"
+ ],
+ "types": [
+ "vite/client",
+ "tdesign-mobile-vue/global"
+ ],
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.d.ts",
+ "src/**/*.vue",
+ "auto-imports.d.ts",
+ "components.d.ts"
+ ]
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a5b06bf
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.node.json"
+ }
+ ]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..3945ae4
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,13 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": [
+ "vite.config.ts",
+ ".eslintrc.cjs"
+ ]
+}
diff --git a/tsconfig.publish.json b/tsconfig.publish.json
new file mode 100644
index 0000000..7e57b30
--- /dev/null
+++ b/tsconfig.publish.json
@@ -0,0 +1,25 @@
+{
+ "extends": "./tsconfig.app.json",
+ "compilerOptions": {
+ "paths": {
+ "@/*": [
+ "src/*"
+ ],
+ "timi-web": [
+ "../timi-web/dist/src/index.d.ts"
+ ],
+ "timi-web/*": [
+ "../timi-web/dist/src/*"
+ ],
+ "vue": [
+ "node_modules/vue"
+ ],
+ "pinia": [
+ "node_modules/pinia"
+ ],
+ "vue-router": [
+ "node_modules/vue-router"
+ ]
+ }
+ }
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..313379d
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,88 @@
+import { fileURLToPath, URL } from "node:url";
+import { defineConfig, loadEnv } from "vite";
+import vue from "@vitejs/plugin-vue";
+import AutoImport from "unplugin-auto-import/vite";
+import Components from "unplugin-vue-components/vite";
+import { TDesignResolver } from "unplugin-vue-components/resolvers";
+
+const localTimiWebRoot = fileURLToPath(new URL("../timi-web", import.meta.url));
+const projectRoot = fileURLToPath(new URL(".", import.meta.url));
+
+export default defineConfig(({ mode }) => {
+ const env = loadEnv(mode, process.cwd(), "");
+ const useLocalTimiWeb = env.VITE_USE_LOCAL_TIMI_WEB !== "false";
+ const useLocalTimiWebSource = useLocalTimiWeb && mode === "development";
+ const useLocalTimiWebPublish = useLocalTimiWeb && mode !== "development";
+ return {
+ resolve: {
+ dedupe: ["vue", "pinia", "vue-router"],
+ alias: [
+ {
+ find: "@",
+ replacement: fileURLToPath(new URL("./src", import.meta.url))
+ },
+ ...(useLocalTimiWeb
+ ? [
+ {
+ find: /^timi-web$/,
+ replacement: useLocalTimiWebSource
+ ? fileURLToPath(new URL("../timi-web/src/index.ts", import.meta.url))
+ : fileURLToPath(new URL("../timi-web/dist/timi-web.mjs", import.meta.url))
+ },
+ {
+ find: /^timi-web\/style\.css$/,
+ replacement: useLocalTimiWebPublish
+ ? fileURLToPath(new URL("../timi-web/dist/timi-web.css", import.meta.url))
+ : fileURLToPath(new URL("../timi-web/src/assets/style/timi-web.less", import.meta.url))
+ }
+ ]
+ : [])
+ ]
+ },
+ plugins: [
+ vue(),
+ AutoImport({
+ imports: ["vue", "vue-router", "pinia"],
+ dts: "auto-imports.d.ts",
+ eslintrc: {
+ enabled: true,
+ filepath: "./.eslintrc-auto-import.json",
+ globalsPropValue: true
+ },
+ resolvers: [
+ TDesignResolver({
+ library: "mobile-vue"
+ })
+ ]
+ }),
+ Components({
+ dirs: ["src/components", "src/layout"],
+ dts: "components.d.ts",
+ resolvers: [
+ TDesignResolver({
+ library: "mobile-vue"
+ })
+ ]
+ })
+ ],
+ css: {
+ preprocessorOptions: {
+ less: {
+ javascriptEnabled: true
+ }
+ }
+ },
+ server: {
+ port: 84,
+ allowedHosts: [
+ "gao.imyeyu.dev"
+ ],
+ fs: {
+ allow: [
+ projectRoot,
+ localTimiWebRoot
+ ]
+ }
+ }
+ };
+});