Преглед на файлове

feat: 初始化移动端项目

zengy преди 6 дни
ревизия
be8aecb81c
променени са 90 файла, в които са добавени 11970 реда и са изтрити 0 реда
  1. 3 0
      .env.development
  2. 58 0
      .gitignore
  3. 40 0
      README.md
  4. 12 0
      index.html
  5. 8168 0
      package-lock.json
  6. 34 0
      package.json
  7. 11 0
      src/App.vue
  8. 157 0
      src/components/ActionFormDrawer.vue
  9. 69 0
      src/components/AlarmAuditDrawer.vue
  10. 21 0
      src/components/AppHeader.vue
  11. 39 0
      src/components/BusinessCard.vue
  12. 36 0
      src/components/BusinessListPage.vue
  13. 28 0
      src/components/DetailPage.vue
  14. 21 0
      src/components/FieldList.vue
  15. 130 0
      src/components/FormField.vue
  16. 79 0
      src/components/InspectCompleteDrawer.vue
  17. 109 0
      src/components/PhotoPreview.vue
  18. 34 0
      src/components/SearchBar.vue
  19. 22 0
      src/components/SegmentTabs.vue
  20. 47 0
      src/components/UploadPanel.vue
  21. 68 0
      src/data/mock.ts
  22. 7 0
      src/env.d.ts
  23. 7 0
      src/main.ts
  24. 17 0
      src/manifest.json
  25. 54 0
      src/pages.json
  26. 109 0
      src/pages/contacts/index.vue
  27. 12 0
      src/pages/emergency/audit.vue
  28. 13 0
      src/pages/emergency/dispatch.vue
  29. 5 0
      src/pages/emergency/events.vue
  30. 29 0
      src/pages/emergency/index.vue
  31. 10 0
      src/pages/emergency/plan-detail.vue
  32. 5 0
      src/pages/emergency/plans.vue
  33. 138 0
      src/pages/login/index.vue
  34. 121 0
      src/pages/message/alarm-detail.vue
  35. 131 0
      src/pages/message/index.vue
  36. 68 0
      src/pages/message/notice-detail.vue
  37. 93 0
      src/pages/message/notices.vue
  38. 28 0
      src/pages/message/warning-detail.vue
  39. 165 0
      src/pages/message/workorder-detail.vue
  40. 75 0
      src/pages/office/alarms.vue
  41. 9 0
      src/pages/office/daily-patrol.vue
  42. 51 0
      src/pages/office/device-detail.vue
  43. 104 0
      src/pages/office/devices.vue
  44. 14 0
      src/pages/office/event-report.vue
  45. 58 0
      src/pages/office/index.vue
  46. 62 0
      src/pages/office/patrol-detail.vue
  47. 86 0
      src/pages/office/patrol.vue
  48. 126 0
      src/pages/profile/basic.vue
  49. 110 0
      src/pages/profile/index.vue
  50. 64 0
      src/pages/profile/login-log.vue
  51. 56 0
      src/pages/profile/password.vue
  52. 5 0
      src/pages/profile/warnings.vue
  53. 75 0
      src/pages/profile/workorders.vue
  54. 70 0
      src/services/alarms.ts
  55. 81 0
      src/services/api.ts
  56. 71 0
      src/services/auth.ts
  57. 20 0
      src/services/contacts.ts
  58. 77 0
      src/services/equipment.ts
  59. 89 0
      src/services/inspect-tasks.ts
  60. 21 0
      src/services/login-logs.ts
  61. 56 0
      src/services/notices.ts
  62. 14 0
      src/services/office.ts
  63. 65 0
      src/services/profile.ts
  64. 141 0
      src/services/workorders.ts
  65. BIN
      src/static/tabbar/contacts-active.png
  66. 1 0
      src/static/tabbar/contacts-active.svg
  67. BIN
      src/static/tabbar/contacts.png
  68. 1 0
      src/static/tabbar/contacts.svg
  69. BIN
      src/static/tabbar/emergency-active.png
  70. 1 0
      src/static/tabbar/emergency-active.svg
  71. BIN
      src/static/tabbar/emergency.png
  72. 1 0
      src/static/tabbar/emergency.svg
  73. BIN
      src/static/tabbar/message-active.png
  74. 1 0
      src/static/tabbar/message-active.svg
  75. BIN
      src/static/tabbar/message.png
  76. 1 0
      src/static/tabbar/message.svg
  77. BIN
      src/static/tabbar/office-active.png
  78. 1 0
      src/static/tabbar/office-active.svg
  79. BIN
      src/static/tabbar/office.png
  80. 1 0
      src/static/tabbar/office.svg
  81. BIN
      src/static/tabbar/profile-active.png
  82. 1 0
      src/static/tabbar/profile-active.svg
  83. BIN
      src/static/tabbar/profile.png
  84. 1 0
      src/static/tabbar/profile.svg
  85. 24 0
      src/stores/user.ts
  86. 76 0
      src/styles/global.scss
  87. 13 0
      src/utils/auth.ts
  88. 13 0
      src/utils/navigation.ts
  89. 17 0
      tsconfig.json
  90. 19 0
      vite.config.ts

+ 3 - 0
.env.development

@@ -0,0 +1,3 @@
+VITE_APP_BASE_API=/dev-api
+# App/小程序真机调试时填写局域网可访问的服务地址,例如 http://192.168.1.10:8301
+VITE_APP_API_ORIGIN=

+ 58 - 0
.gitignore

@@ -0,0 +1,58 @@
+# Dependencies
+node_modules/
+
+# Build outputs
+dist/
+unpackage/
+
+# Tool caches and temporary files
+.vite/
+.cache/
+.temp/
+.tmp/
+*.tsbuildinfo
+
+# Test outputs
+coverage/
+test-results/
+playwright-report/
+blob-report/
+
+# Local environment overrides
+.env.local
+.env.*.local
+
+# Logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# IDE and editor files
+.idea/
+.hbuilderx/
+.vscode/*
+!.vscode/extensions.json
+!.vscode/settings.json
+*.iml
+*.suo
+*.user
+
+# Local browser profiles and generated preview screenshots
+.edge-preview*/
+/*-preview.png
+
+# Local signing credentials
+*.keystore
+*.jks
+*.p12
+*.pfx
+*.mobileprovision
+*.key
+local.properties
+
+# Operating system files
+.DS_Store
+Thumbs.db
+Desktop.ini

+ 40 - 0
README.md

@@ -0,0 +1,40 @@
+# 城市地下管网管控平台移动端
+
+基于 uni-app(Vue 3 + TypeScript)的多端移动应用,目标端包括 H5、微信小程序和 App。
+
+## 当前阶段
+
+- 已按 `E:\work\prd\app\login.html` 和 `index.html` 完成第一阶段静态页面拆分。
+- 页面数据统一来自 `src/data/mock.ts`,当前不发起后端请求。
+- 接口入口预留在 `src/services/api.ts`,第二阶段可在此补充基址、鉴权、请求拦截和错误处理。
+
+## 本地运行
+
+```bash
+npm install
+npm run dev:h5
+```
+
+H5 开发服务固定使用 `http://localhost:5174`,与 PC 端开发服务错开。
+
+其他命令:
+
+```bash
+npm run type-check
+npm run build:h5
+npm run build:mp-weixin
+npm run build:app
+```
+
+App 端请使用 HBuilderX 打开项目并运行到模拟器或真机。
+
+## 页面结构
+
+- `pages/login`:登录
+- `pages/message`:消息、工单、预警、事件和通知
+- `pages/office`:设备、故障、巡检、日常巡查和事件上报
+- `pages/emergency`:事件、预案、调度和审核
+- `pages/contacts`:通讯录
+- `pages/profile`:个人中心、工单、预警和账号资料
+
+公共组件位于 `src/components`,静态数据位于 `src/data`。

+ 12 - 0
index.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>城市地下管网管控平台</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.ts"></script>
+  </body>
+</html>

+ 8168 - 0
package-lock.json

@@ -0,0 +1,8168 @@
+{
+  "name": "city-life-line-mobile",
+  "version": "0.1.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "city-life-line-mobile",
+      "version": "0.1.0",
+      "dependencies": {
+        "@dcloudio/uni-app": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-app-plus": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-components": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-h5": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-mp-weixin": "3.0.0-alpha-5030120260930001",
+        "pinia": "2.1.7",
+        "pinyin-pro": "^3.27.0",
+        "vue": "3.4.21"
+      },
+      "devDependencies": {
+        "@dcloudio/types": "3.4.31",
+        "@dcloudio/vite-plugin-uni": "3.0.0-alpha-5030120260930001",
+        "@types/node": "22.10.2",
+        "sass": "1.77.8",
+        "typescript": "5.4.5",
+        "vite": "5.2.8",
+        "vue-tsc": "2.0.6"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.24.7.tgz",
+      "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/highlight": "^7.24.7",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.7.tgz",
+      "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.25.2",
+      "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.25.2.tgz",
+      "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
+      "license": "MIT",
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.24.7",
+        "@babel/generator": "^7.25.0",
+        "@babel/helper-compilation-targets": "^7.25.2",
+        "@babel/helper-module-transforms": "^7.25.2",
+        "@babel/helpers": "^7.25.0",
+        "@babel/parser": "^7.25.0",
+        "@babel/template": "^7.25.0",
+        "@babel/traverse": "^7.25.2",
+        "@babel/types": "^7.25.2",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.8.tgz",
+      "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.8",
+        "@babel/types": "^7.29.8",
+        "@jridgewell/gen-mapping": "^0.3.12",
+        "@jridgewell/trace-mapping": "^0.3.28",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/generator/node_modules/@babel/parser": {
+      "version": "7.29.9",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.9.tgz",
+      "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.8"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/generator/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+      "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+      "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.29.7",
+        "@babel/helper-validator-option": "^7.29.7",
+        "browserslist": "^4.24.0",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
+      "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "@babel/helper-member-expression-to-functions": "^7.29.7",
+        "@babel/helper-optimise-call-expression": "^7.29.7",
+        "@babel/helper-replace-supers": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+        "@babel/traverse": "^7.29.7",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-create-regexp-features-plugin": {
+      "version": "7.29.10",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.10.tgz",
+      "integrity": "sha512-/YY9soQuWa8TURtHXHT+GbklpbAA+dZErxFGHIr6qgDg96xuGWrTAs1+MfjgVJPF0YLQsOVsOYs8lhgsPbOinQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "regexpu-core": "^6.5.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-define-polyfill-provider": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz",
+      "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "debug": "^4.4.3",
+        "lodash.debounce": "^4.0.8",
+        "resolve": "^1.22.11"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": {
+      "version": "4.4.3",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": {
+      "version": "1.22.13",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.13.tgz",
+      "integrity": "sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "is-core-module": "^2.17.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/@babel/helper-globals": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+      "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-member-expression-to-functions": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
+      "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-member-expression-to-functions/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+      "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+      "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-optimise-call-expression": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
+      "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-optimise-call-expression/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+      "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-remap-async-to-generator": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz",
+      "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "@babel/helper-wrap-function": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-replace-supers": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
+      "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-member-expression-to-functions": "^7.29.7",
+        "@babel/helper-optimise-call-expression": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
+      "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-skip-transparent-expression-wrappers/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+      "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+      "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+      "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-wrap-function": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz",
+      "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/template": "^7.29.7",
+        "@babel/traverse": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-wrap-function/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.29.10",
+      "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.29.10.tgz",
+      "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/template": "^7.29.7",
+        "@babel/types": "^7.29.8"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.25.9.tgz",
+      "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.25.6",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.6.tgz",
+      "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.25.6"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.29.7.tgz",
+      "integrity": "sha512-j8SrR0zLZrRsC09DlszEx8FpMiwukKffYXMK0d5LmOglO7vGG6sz/BR/20yHqWH+Lnn31JTt2PE3hIWNgM2J6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.29.7.tgz",
+      "integrity": "sha512-r8j8escF+U2FUHo0KOhPUdMzUO+jp9fInva6+ACVAF3Y97Ev+5iNZwiqTghmzNeWwDkOPlYuTcfb1vDaoZKmAQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.29.7.tgz",
+      "integrity": "sha512-GE1TFSiuFeGsCxmYXZl8HwoPrVlwe4rHPFE8weieGKZqnDORK+Ar3vgWMgW+AOxQ6/2TgLSKx9p6W7O4rC6qgQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.7.tgz",
+      "integrity": "sha512-oBNVCvnO5tND+xSopWvV8WNGfpTfgP4Zr/YXXSj8zfmcPktp5Ku/aZlsIowgSD4fjmgHn6sGmB9APVsU5zOdhA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.29.7.tgz",
+      "integrity": "sha512-QQt9qKHZ2sg/kivaLr7lnQr8HVrQDdBNSfCsTjiDxRuX/K5ORyKq+Bu8Xr0cDE3Dfkv0cw28Ve0EKyKMvulkOw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+        "@babel/plugin-transform-optional-chaining": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.13.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.29.7.tgz",
+      "integrity": "sha512-pn6QacGLgvCcwc+syUhKE/qSjV2D1IHDB84RNxWYSt1mW3K/SCtjinZ2p0cETJxAWBjPy3K/1lHwG5BjjPxNlw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-proposal-private-property-in-object": {
+      "version": "7.21.0-placeholder-for-preset-env.2",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+      "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-assertions": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.29.7.tgz",
+      "integrity": "sha512-/An1OCBN93thpBAGyfsK2pcf0jvju1SAtKkL2Ny++B5Sy6sqgzXDQH1cZxWbF96Wuk+bn41MDA9bLd4VVAw6rw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-attributes": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz",
+      "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-meta": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+      "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-jsx": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+      "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-typescript": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+      "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+      "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+        "@babel/helper-plugin-utils": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-arrow-functions": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.29.7.tgz",
+      "integrity": "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-async-generator-functions": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz",
+      "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-remap-async-to-generator": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-async-to-generator": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz",
+      "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-remap-async-to-generator": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.29.7.tgz",
+      "integrity": "sha512-cUSmjh72N+rN4PrkFlN1dJwNCwjVp5d38/CQrEsFggkD10UiFlBFgdH3tv5dNsLuHY+3S8db2xCHjhZcv5WgvA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-block-scoping": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz",
+      "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-class-properties": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz",
+      "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-class-static-block": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz",
+      "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.12.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-classes": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz",
+      "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "@babel/helper-compilation-targets": "^7.29.7",
+        "@babel/helper-globals": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-replace-supers": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-computed-properties": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz",
+      "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/template": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-destructuring": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz",
+      "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-dotall-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.29.7.tgz",
+      "integrity": "sha512-3qc18hsD2RdZiyJNDNc7HQpv6xbncwh8FYtxNFFzclSyh/trPD9KkVR9BDECUjDLvb7yJVF15GfYUuC+LMkkiQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-duplicate-keys": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.29.7.tgz",
+      "integrity": "sha512-6IvRRriEMqnBwD6chtxdLpMYCHWEzN+oL5cyQtjykya19UgzbmKhxmhZgKC/LHxS2nYr9Q/qYPZ5Lr6jOL9+yQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.7.tgz",
+      "integrity": "sha512-2wiIyo2BjtgU7HufSeDnL9L2O7zr8jmhFKuSr65VpRkUiRKRNpb0mdlk56+XPPKoIrfHqzbMuglDvZun0RISsA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-dynamic-import": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.29.7.tgz",
+      "integrity": "sha512-giOlEm/EFjfjr+te9NsdjkUo2v4f8rS/SXPumRVHAtbNcyNlvtREkU1dZzaIDclNpnaVhlCqRdFKhJBjBikzLg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-explicit-resource-management": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.29.7.tgz",
+      "integrity": "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/plugin-transform-destructuring": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.29.7.tgz",
+      "integrity": "sha512-zFpMOTLZBdW5LfObqcSbL6kefg4R4eLdmvS0wbN9M6D5Mym/sKm9toOoWyVOa+xDjvCnuWcHls2YonXwHvH3CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-export-namespace-from": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz",
+      "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-for-of": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz",
+      "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-function-name": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz",
+      "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-json-strings": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.29.7.tgz",
+      "integrity": "sha512-RRnE2+eon1rJAq8MnoF1b5kTpY1vU88twHcvcKMrsqP/jxIRqDVs9iJB5fqPuqyeFAW0wJo4MlUIPpQCq/aRsg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-literals": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz",
+      "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz",
+      "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-member-expression-literals": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.29.7.tgz",
+      "integrity": "sha512-hl1kwFZCCiDyfH25Xmco9jTrkPgnS9pmOzSG7W5I4SaGbLeqKv417hcU2RKmaxoPEgsoJh7ZPOrnPGq99bHoUg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-amd": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.29.7.tgz",
+      "integrity": "sha512-fxtQoH3m5ywUSIfaH0FGCzWu4McsYon5bD3K4XnskC7f+OyQMj7rsOMi4NvvmJ83WwBAg4UCe+ov4VZlqEvyew==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-commonjs": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz",
+      "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-systemjs": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.8.tgz",
+      "integrity": "sha512-6iSnEK0zlkLKU4heofK/AdmRD4e2SHVpJMtrwnTCzhnaM98ria4rTrOXBBi45BTTYnJtO8txnPsX4fChYXkmeA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "@babel/traverse": "^7.29.8"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-umd": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.29.7.tgz",
+      "integrity": "sha512-B4UkaTK3QpgCwJnrxKfMPKdo92CN7OKXAlpAAnM3UPu0Q0lCCk57ylA9AJbRy2v8dDKOPAAWcoR6CMyeoHwRCA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz",
+      "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-new-target": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.29.7.tgz",
+      "integrity": "sha512-fEo41GmsOUhOBlw8ioo6zvjX5Xc2Lqkzlyfqbpsk3eB6TReV18uhxZ0esfEokVbY2+PVJAQHNKxER6lGrzNd3A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz",
+      "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-numeric-separator": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz",
+      "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-object-rest-spread": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz",
+      "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/plugin-transform-destructuring": "^7.29.7",
+        "@babel/plugin-transform-parameters": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-object-super": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.29.7.tgz",
+      "integrity": "sha512-Ea/diGcw0twB5IlZPO5sgET6fJsLJqPABqTuFWIR+iMPGPZJkATEIWx0wa+aEQ5UY1CBQyP/gkAiLEqn1vBiQA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-replace-supers": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-optional-catch-binding": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz",
+      "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-optional-chaining": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz",
+      "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-parameters": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz",
+      "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-methods": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz",
+      "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-property-in-object": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz",
+      "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "@babel/helper-create-class-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-property-literals": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.29.7.tgz",
+      "integrity": "sha512-bOMRLQuI0A5ZqHq3OWJ89/rXpJ/NJrbVhXiP4zwPGMs6kpcVsuTUNjwoE30K0Qm3mf48a/TnRYYD6vPNqcg6jA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-regenerator": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.8.tgz",
+      "integrity": "sha512-0UpIXPtdDtMXfnV2OJAVMLpj3H/92vmkA6lpSRakmycJvj3VUy6Xs1dM8tXRugupykr5WB+LpiVl0J8LMVg2mg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-regexp-modifiers": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.29.7.tgz",
+      "integrity": "sha512-mB5Fs0VWrJ42ZCmc8114v60qetdaUVNkj9PmSZRmanCZM3S9hm0CFRLjRmYIsuXav14l2jvZ+4T8iiCGnhj3nQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-reserved-words": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.29.7.tgz",
+      "integrity": "sha512-5+YhdpVgmfSmwZyLMftfaiffLRMHjzIRHFHHLdibcSyJm2pasMrKHrO3Ptrt2DRshjvpgjEJJ1zVW14WPq/6QA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-shorthand-properties": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.29.7.tgz",
+      "integrity": "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-spread": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.8.tgz",
+      "integrity": "sha512-4S9ksMGVWUshvgK0mKfvZky7leuG5/uoFVwMpAomJ8bMoDJiNHRVmc1EglwW/CmGVSqqWpEbXm9FmbRit22qoA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-sticky-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz",
+      "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-template-literals": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.29.7.tgz",
+      "integrity": "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-typeof-symbol": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.29.7.tgz",
+      "integrity": "sha512-223mNGoTkBiTEWFoK+Q6Go3tueMRclO8vxxxxquNCYuNI4jWOofFKJRRDu6SDrB8Sgo1UEGW9T4GAQ8ZyRso1A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-typescript": {
+      "version": "7.29.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.9.tgz",
+      "integrity": "sha512-FFwIwzU+7SCOuxxV4YtJql6T9981ZVTm+FHO5GhVsRqCTdy0WwrEZh3l42ARpXruJUDGOptdduHW6Zr7pNPLNg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "@babel/helper-create-class-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+        "@babel/plugin-syntax-typescript": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-escapes": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.29.7.tgz",
+      "integrity": "sha512-jCfXxSjf94lf4E0hKE0AByxF6F3/pVFqRdUUNkDJhsY0m1ZKjnN6ZYyMeHNpzflxb/0q5b7t3p+BE+SLF1WOtA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-property-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.29.7.tgz",
+      "integrity": "sha512-OgZ+zoAJgZLUCunsTRQ5LAjOywDv5zzZ2/hQ5aMw1pGXyY2rtE8/chXYUmu3AlVHKpm10KEdG9aMwbI/K76ZGw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz",
+      "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.29.7.tgz",
+      "integrity": "sha512-BLOhLht9DOJwIxlmp91wHvkXv1lguuHS3/FwUO8HL1H0u8s4hR1gASVFyilu9iGtcTRYqjTZmlsFFeQletntEg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/preset-env": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.29.7.tgz",
+      "integrity": "sha512-GYzX36n1nsciIb0uyH0GHwxwtNwPQIcpxSeiVLDtG/B7jB5xXgchnmL1f/jCX5o+pwnaDBtO60ONSJhEBJfxYA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.29.7",
+        "@babel/helper-compilation-targets": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/helper-validator-option": "^7.29.7",
+        "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.29.7",
+        "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.29.7",
+        "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.29.7",
+        "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.7",
+        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.29.7",
+        "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.29.7",
+        "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+        "@babel/plugin-syntax-import-assertions": "^7.29.7",
+        "@babel/plugin-syntax-import-attributes": "^7.29.7",
+        "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+        "@babel/plugin-transform-arrow-functions": "^7.29.7",
+        "@babel/plugin-transform-async-generator-functions": "^7.29.7",
+        "@babel/plugin-transform-async-to-generator": "^7.29.7",
+        "@babel/plugin-transform-block-scoped-functions": "^7.29.7",
+        "@babel/plugin-transform-block-scoping": "^7.29.7",
+        "@babel/plugin-transform-class-properties": "^7.29.7",
+        "@babel/plugin-transform-class-static-block": "^7.29.7",
+        "@babel/plugin-transform-classes": "^7.29.7",
+        "@babel/plugin-transform-computed-properties": "^7.29.7",
+        "@babel/plugin-transform-destructuring": "^7.29.7",
+        "@babel/plugin-transform-dotall-regex": "^7.29.7",
+        "@babel/plugin-transform-duplicate-keys": "^7.29.7",
+        "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.7",
+        "@babel/plugin-transform-dynamic-import": "^7.29.7",
+        "@babel/plugin-transform-explicit-resource-management": "^7.29.7",
+        "@babel/plugin-transform-exponentiation-operator": "^7.29.7",
+        "@babel/plugin-transform-export-namespace-from": "^7.29.7",
+        "@babel/plugin-transform-for-of": "^7.29.7",
+        "@babel/plugin-transform-function-name": "^7.29.7",
+        "@babel/plugin-transform-json-strings": "^7.29.7",
+        "@babel/plugin-transform-literals": "^7.29.7",
+        "@babel/plugin-transform-logical-assignment-operators": "^7.29.7",
+        "@babel/plugin-transform-member-expression-literals": "^7.29.7",
+        "@babel/plugin-transform-modules-amd": "^7.29.7",
+        "@babel/plugin-transform-modules-commonjs": "^7.29.7",
+        "@babel/plugin-transform-modules-systemjs": "^7.29.7",
+        "@babel/plugin-transform-modules-umd": "^7.29.7",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.7",
+        "@babel/plugin-transform-new-target": "^7.29.7",
+        "@babel/plugin-transform-nullish-coalescing-operator": "^7.29.7",
+        "@babel/plugin-transform-numeric-separator": "^7.29.7",
+        "@babel/plugin-transform-object-rest-spread": "^7.29.7",
+        "@babel/plugin-transform-object-super": "^7.29.7",
+        "@babel/plugin-transform-optional-catch-binding": "^7.29.7",
+        "@babel/plugin-transform-optional-chaining": "^7.29.7",
+        "@babel/plugin-transform-parameters": "^7.29.7",
+        "@babel/plugin-transform-private-methods": "^7.29.7",
+        "@babel/plugin-transform-private-property-in-object": "^7.29.7",
+        "@babel/plugin-transform-property-literals": "^7.29.7",
+        "@babel/plugin-transform-regenerator": "^7.29.7",
+        "@babel/plugin-transform-regexp-modifiers": "^7.29.7",
+        "@babel/plugin-transform-reserved-words": "^7.29.7",
+        "@babel/plugin-transform-shorthand-properties": "^7.29.7",
+        "@babel/plugin-transform-spread": "^7.29.7",
+        "@babel/plugin-transform-sticky-regex": "^7.29.7",
+        "@babel/plugin-transform-template-literals": "^7.29.7",
+        "@babel/plugin-transform-typeof-symbol": "^7.29.7",
+        "@babel/plugin-transform-unicode-escapes": "^7.29.7",
+        "@babel/plugin-transform-unicode-property-regex": "^7.29.7",
+        "@babel/plugin-transform-unicode-regex": "^7.29.7",
+        "@babel/plugin-transform-unicode-sets-regex": "^7.29.7",
+        "@babel/preset-modules": "0.1.6-no-external-plugins",
+        "babel-plugin-polyfill-corejs2": "^0.4.15",
+        "babel-plugin-polyfill-corejs3": "^0.14.0",
+        "babel-plugin-polyfill-regenerator": "^0.6.6",
+        "core-js-compat": "^3.48.0",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/preset-modules": {
+      "version": "0.1.6-no-external-plugins",
+      "resolved": "https://registry.npmmirror.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+      "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.29.10",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.10.tgz",
+      "integrity": "sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/runtime-corejs3": {
+      "version": "7.29.10",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.29.10.tgz",
+      "integrity": "sha512-R4FKrg4Vy0hB7PfAxf9LOorEPd5/36SCIXPXAvjlQaQmPvtrjwoDXV15jsSm2ecsqBW1Iewwb7mEnG83xIEApg==",
+      "license": "MIT",
+      "dependencies": {
+        "core-js-pure": "^3.48.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.29.7.tgz",
+      "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.29.7",
+        "@babel/parser": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template/node_modules/@babel/code-frame": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.7.tgz",
+      "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template/node_modules/@babel/parser": {
+      "version": "7.29.9",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.9.tgz",
+      "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.8"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/template/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template/node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "license": "ISC"
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.29.10",
+      "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.10.tgz",
+      "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.29.7",
+        "@babel/generator": "^7.29.8",
+        "@babel/helper-globals": "^7.29.7",
+        "@babel/parser": "^7.29.9",
+        "@babel/template": "^7.29.7",
+        "@babel/types": "^7.29.8",
+        "debug": "^4.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/@babel/code-frame": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.7.tgz",
+      "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/@babel/parser": {
+      "version": "7.29.9",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.9.tgz",
+      "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.8"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "license": "ISC"
+    },
+    "node_modules/@babel/types": {
+      "version": "7.25.6",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.25.6.tgz",
+      "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.24.8",
+        "@babel/helper-validator-identifier": "^7.24.7",
+        "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@dcloudio/types": {
+      "version": "3.4.31",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.4.31.tgz",
+      "integrity": "sha512-YAqOfJpcAwMs4Fagv2oP+iRHSCJOJoN8JUYyoRD6gwfANhsI9QaYj4/j22FzSopfHkqjX50B7YkG/VRAyz9OnA==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@dcloudio/uni-app": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app/-/uni-app-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-qdyyPwL7u6frgu0fMKmTUrA5K5a5chtESsAFRY2tci9JUEQF49ndL+lIhrYK7h58nmkzuMqCCY4oZnp3CwNKhQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cloud": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-components": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-console": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-push": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-stat": "3.0.0-alpha-5030120260930001",
+        "@vue/shared": "3.4.21"
+      },
+      "peerDependencies": {
+        "@dcloudio/types": "3.4.31"
+      }
+    },
+    "node_modules/@dcloudio/uni-app-plus": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-plus/-/uni-app-plus-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-J9cZijx2lZpMFEnWKv2v9slzytTHRh62Tc96r1wWeYTDYAeLA+zBJtmccvxiBIe1HMibwYxFJgXngE74O/ZiGw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-app-uts": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-app-vite": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-app-vue": "3.0.0-alpha-5030120260930001",
+        "debug": "4.3.7",
+        "fs-extra": "10.1.0",
+        "licia": "1.41.1",
+        "postcss-selector-parser": "6.1.2"
+      }
+    },
+    "node_modules/@dcloudio/uni-app-uts": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-uts/-/uni-app-uts-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-BL3pSl5LDzdSQiMFGjMsxKLwHJFJnJeOGL9eTDWe3CH0fCUY0+R4ne3fKtL5IbXuXofd5EPX+yKjKVEILWQE0Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/parser": "7.25.6",
+        "@babel/types": "7.25.6",
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-console": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-nvue-styler": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@jridgewell/gen-mapping": "^0.3.3",
+        "@jridgewell/trace-mapping": "^0.3.19",
+        "@rollup/pluginutils": "5.1.0",
+        "@vue/compiler-core": "3.4.21",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/consolidate": "1.0.0",
+        "@vue/shared": "3.4.21",
+        "debug": "4.3.7",
+        "es-module-lexer": "1.5.4",
+        "estree-walker": "2.0.2",
+        "fast-glob": "3.3.3",
+        "fs-extra": "10.1.0",
+        "magic-string": "0.30.11",
+        "picocolors": "1.1.0",
+        "source-map-js": "1.2.1",
+        "unimport": "4.1.1"
+      }
+    },
+    "node_modules/@dcloudio/uni-app-vite": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vite/-/uni-app-vite-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-2ALfEmRpKN8z0MLnO+8fBO5pcKjSfy6YYOabX9fhfVzs8P4RN/z8Y+SsncIhH0CSo02ltmztLR7IdtFKgHy+8Q==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-nvue-styler": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@rollup/pluginutils": "5.1.0",
+        "@vitejs/plugin-vue": "5.2.4",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "debug": "4.3.7",
+        "fs-extra": "10.1.0",
+        "picocolors": "1.1.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-app-vue": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vue/-/uni-app-vue-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-lOFjcviEPxlRPBYV89CSM2AXNiSylO2vRydqeuMmZAC3ULC/c/PGlKO2ATpMao57exND/U00cQOOaHBNgN+Xdw==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@dcloudio/uni-cli-shared": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-m+BYTQDAw5R4bo8eqwr74kIZUorUNVlmn62cFt0Kx++7sspvB1RxHCZW17Hx3KP2FLVVLedijIfkr/x3GvSk8w==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@ampproject/remapping": "^2.1.2",
+        "@babel/code-frame": "7.24.7",
+        "@babel/core": "7.25.2",
+        "@babel/parser": "7.25.6",
+        "@babel/types": "7.25.6",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-nvue-styler": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@intlify/core-base": "9.1.9",
+        "@intlify/shared": "9.1.9",
+        "@intlify/vue-devtools": "9.1.9",
+        "@rolldown/pluginutils": "^1.0.1",
+        "@rollup/pluginutils": "5.1.0",
+        "@vue/compiler-core": "3.4.21",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/compiler-ssr": "3.4.21",
+        "@vue/server-renderer": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "adm-zip": "0.5.16",
+        "autoprefixer": "10.4.20",
+        "base64url": "^3.0.1",
+        "chokidar": "3.6.0",
+        "compare-versions": "^3.6.0",
+        "debug": "4.3.7",
+        "entities": "^7.0.0",
+        "es-module-lexer": "1.5.4",
+        "esbuild": "0.20.2",
+        "estree-walker": "2.0.2",
+        "fast-glob": "3.3.3",
+        "fs-extra": "10.1.0",
+        "hash-sum": "2.0.0",
+        "isbinaryfile": "5.0.2",
+        "jsonc-parser": "3.3.1",
+        "lines-and-columns": "^2.0.4",
+        "magic-string": "0.30.11",
+        "merge": "2.1.1",
+        "mime": "3.0.0",
+        "module-alias": "2.2.3",
+        "nostics": "^1.1.4",
+        "os-locale-s-fix": "^1.0.8-fix-1",
+        "picocolors": "1.1.0",
+        "postcss-import": "^14.0.2",
+        "postcss-load-config": "^3.1.1",
+        "postcss-modules": "^4.3.0",
+        "postcss-selector-parser": "6.1.2",
+        "resolve": "1.22.8",
+        "source-map-js": "1.2.1",
+        "tapable": "^2.2.0",
+        "tinycolor2": "1.6.0",
+        "unimport": "4.1.1",
+        "unplugin-auto-import": "19.1.0",
+        "xregexp": "5.1.2"
+      },
+      "engines": {
+        "node": ">=22.12.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-cli-shared/node_modules/picomatch": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz",
+      "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/@dcloudio/uni-cli-shared/node_modules/unplugin-auto-import": {
+      "version": "19.1.0",
+      "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-19.1.0.tgz",
+      "integrity": "sha512-B+TGBEBHqY9aR+7YfShfLujETOHstzpV+yaqgy5PkfV0QG7Py+TYMX7vJ9W4SrysHR+UzR+gzcx/nuZjmPeclA==",
+      "license": "MIT",
+      "dependencies": {
+        "local-pkg": "^1.0.0",
+        "magic-string": "^0.30.17",
+        "picomatch": "^4.0.2",
+        "unimport": "^4.1.1",
+        "unplugin": "^2.2.0",
+        "unplugin-utils": "^0.2.4"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@nuxt/kit": "^3.2.2",
+        "@vueuse/core": "*"
+      },
+      "peerDependenciesMeta": {
+        "@nuxt/kit": {
+          "optional": true
+        },
+        "@vueuse/core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@dcloudio/uni-cli-shared/node_modules/unplugin-auto-import/node_modules/magic-string": {
+      "version": "0.30.21",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz",
+      "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.5"
+      }
+    },
+    "node_modules/@dcloudio/uni-cloud": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cloud/-/uni-cloud-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-QKdvThP8P/Ad7lqlyt+u63ohfidzfAt1kxJfmg+2VS0FCitxqea1XgC1rg/f1AXEFTVtK5AU90GXJY7erhnQOQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/shared": "3.4.21",
+        "fast-glob": "3.3.3"
+      }
+    },
+    "node_modules/@dcloudio/uni-components": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-components/-/uni-components-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-TPZi/GkTV8OoI3wkuIckQjGvADKMxKGaqePmcHs97MK/2F0DXEdCcn+ngwX7kFbiyv2aJh0t5dqSlik4X/Ytbg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cloud": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-h5": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001"
+      }
+    },
+    "node_modules/@dcloudio/uni-console": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-console/-/uni-console-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-PDmPQ3vHH0ipRNm3c0hY/UXUsbjk03ZJb0ajDF9oXcmSJG0VOPJR8LIODmFBnwSAqKzGH6k8shMAsHbARubomg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "fs-extra": "10.1.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-h5": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-den0lxkgdybfsBi5idpsT4HUPMPB22yOf8HCKvu2SEceoMUkssGYZEqccjHtzJOhgOcuUo7LxZja5qIge2dQCw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-h5-vite": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-h5-vue": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/server-renderer": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "debug": "4.3.7",
+        "localstorage-polyfill": "^1.0.1",
+        "postcss-selector-parser": "6.1.2",
+        "safe-area-insets": "1.4.1",
+        "vue-router": "4.4.4",
+        "xmlhttprequest": "^1.8.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-h5-vite": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vite/-/uni-h5-vite-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-ey2q5kmF2UalErUD6fEuJNIrEqG/G4da2xn86s/JeQLrTfhJqksVqLhZbTItsZTWwGgguOoRaV9Ox9TpUmHKDw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@rollup/pluginutils": "5.1.0",
+        "@vitejs/plugin-basic-ssl": "1.2.0",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/server-renderer": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "debug": "4.3.7",
+        "fs-extra": "10.1.0",
+        "mime": "3.0.0",
+        "module-alias": "2.2.3"
+      }
+    },
+    "node_modules/@dcloudio/uni-h5-vue": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vue/-/uni-h5-vue-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-fd2V5oXqsxBIhcqmeHkn6T6zR6u0zsIy+TAZ5HqnP/b4SBkBgRuJVzsfcX688AwILSOYf52UrFO+5GC4E+x6YQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/server-renderer": "3.4.21"
+      }
+    },
+    "node_modules/@dcloudio/uni-i18n": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-i18n/-/uni-i18n-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-Xbw80/0/MRSkeZXJJJwccGuumeKdhYss3OfwLfNEAn4zjz8S1b68V00dqnYUSF8KhiPtOli6xQUrns/RsrXZvQ==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@dcloudio/uni-mp-compiler": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-compiler/-/uni-mp-compiler-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-yhe0qTHIboJSkQ+4lx/QlESaEwr3MFxGJjDHnchddRjYa623SqPtWH4iJm0UxeZrh8FSRe22u+pqo6LYDT7qiw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/generator": "7.25.6",
+        "@babel/parser": "7.25.6",
+        "@babel/types": "7.25.6",
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/compiler-core": "3.4.21",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "estree-walker": "2.0.2"
+      }
+    },
+    "node_modules/@dcloudio/uni-mp-compiler/node_modules/@babel/generator": {
+      "version": "7.25.6",
+      "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.25.6.tgz",
+      "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.25.6",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^2.5.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-mp-compiler/node_modules/jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@dcloudio/uni-mp-vite": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vite/-/uni-mp-vite-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-CITIo6JewzI/sOBUQTIzWzVjssZAsvmdCZqErwZQZYLzgNrldkkTKC0QgpBJiDWqV7pcxnPKxa8rq3l53WMu3g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-i18n": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-mp-compiler": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-mp-vue": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "debug": "4.3.7"
+      }
+    },
+    "node_modules/@dcloudio/uni-mp-vue": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vue/-/uni-mp-vue-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-ilMYsHija8LAut/Q/vbfAkeL3Eo3u+qA4oPTvl0P3dBwWpEJNwA/X/Sp5XIqTYaZtLODy2nJ85gqEE1k7QpFtw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/shared": "3.4.21"
+      }
+    },
+    "node_modules/@dcloudio/uni-mp-weixin": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-CMLNdAR89v92Q+43Kpi/bqHOqK+QE2lL3WcN4ckEOCz3+rvZf4b6zxxZD0LDatr/DFC7j8esuYmXmuZwNDLwyQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-mp-compiler": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-mp-vite": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-mp-vue": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@vue/shared": "3.4.21",
+        "jimp": "0.10.3",
+        "licia": "1.41.1",
+        "qrcode-reader": "1.0.4",
+        "qrcode-terminal": "0.12.0",
+        "ws": "8.18.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-nvue-styler": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-nvue-styler/-/uni-nvue-styler-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-/33fgvje91gSDHlcunDoG6AbgLc1Qap4+c6RLJP0TApua/jOjHWZlVKlMINQPHLq3vDQANZ6BJz+JQJUFdbfUQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@vue/shared": "3.4.21",
+        "parse-css-font": "^4.0.0",
+        "postcss": "8.5.6",
+        "tinycolor2": "1.6.0"
+      }
+    },
+    "node_modules/@dcloudio/uni-nvue-styler/node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "license": "ISC"
+    },
+    "node_modules/@dcloudio/uni-nvue-styler/node_modules/postcss": {
+      "version": "8.5.6",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
+      "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.11",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/@dcloudio/uni-push": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-push/-/uni-push-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-KsPkfoN+iI8BH5SxQo6iulwlHfaOkHWkGz2cjSYONQg2k1oYNm+WphdwXR8HkL+MdQ5ScsjcI0D8CtyeLFR9vA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001"
+      }
+    },
+    "node_modules/@dcloudio/uni-shared": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-shared/-/uni-shared-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-fxr+1n30OkC5Z81MjA4w+MU3V2Uo6tHzW6aY0mCzb46Ri3jvrwQZeDp5e9lTxxPILjG4VODZs8vvY+RMRtgVVA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@vue/shared": "3.4.21"
+      }
+    },
+    "node_modules/@dcloudio/uni-stat": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stat/-/uni-stat-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-BlfIuWN7s4BBbgrFw25JXA3q6gERDTNRzbtrhZsVuECqjui1jKHcEOuTCgn3qwRenD2Uqfw+hSHT2PQVmlOl7w==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "debug": "4.3.7"
+      }
+    },
+    "node_modules/@dcloudio/vite-plugin-uni": {
+      "version": "3.0.0-alpha-5030120260930001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/vite-plugin-uni/-/vite-plugin-uni-3.0.0-alpha-5030120260930001.tgz",
+      "integrity": "sha512-r+yQUVASA/QuPtAhWuA3zjarCAeejAoxd+wiIaKJj49JtN1Dt/PofIaNvV2NV3n7F25G1vTvj9Qs09RbzltmZw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/core": "7.25.2",
+        "@babel/plugin-syntax-import-meta": "^7.10.4",
+        "@babel/plugin-transform-typescript": "^7.23.3",
+        "@babel/types": "7.25.6",
+        "@dcloudio/uni-cli-shared": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-nvue-styler": "3.0.0-alpha-5030120260930001",
+        "@dcloudio/uni-shared": "3.0.0-alpha-5030120260930001",
+        "@rollup/pluginutils": "5.1.0",
+        "@vitejs/plugin-legacy": "5.3.2",
+        "@vitejs/plugin-vue": "5.2.4",
+        "@vitejs/plugin-vue-jsx": "3.1.0",
+        "@vue/compiler-core": "3.4.21",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "cac": "6.7.9",
+        "debug": "4.3.7",
+        "es-module-lexer": "1.5.4",
+        "estree-walker": "2.0.2",
+        "express": "4.20.0",
+        "fast-glob": "3.3.3",
+        "fs-extra": "10.1.0",
+        "hash-sum": "2.0.0",
+        "jsonc-parser": "3.3.1",
+        "magic-string": "0.30.11",
+        "picocolors": "1.1.0",
+        "source-map-js": "1.2.1",
+        "terser": "^5.4.0",
+        "unplugin-auto-import": "19.1.0"
+      },
+      "bin": {
+        "uni": "bin/uni.js"
+      },
+      "engines": {
+        "node": ">=22.12.0"
+      },
+      "peerDependencies": {
+        "vite": "5.2.8"
+      }
+    },
+    "node_modules/@dcloudio/vite-plugin-uni/node_modules/picomatch": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz",
+      "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/@dcloudio/vite-plugin-uni/node_modules/unplugin-auto-import": {
+      "version": "19.1.0",
+      "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-19.1.0.tgz",
+      "integrity": "sha512-B+TGBEBHqY9aR+7YfShfLujETOHstzpV+yaqgy5PkfV0QG7Py+TYMX7vJ9W4SrysHR+UzR+gzcx/nuZjmPeclA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "local-pkg": "^1.0.0",
+        "magic-string": "^0.30.17",
+        "picomatch": "^4.0.2",
+        "unimport": "^4.1.1",
+        "unplugin": "^2.2.0",
+        "unplugin-utils": "^0.2.4"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@nuxt/kit": "^3.2.2",
+        "@vueuse/core": "*"
+      },
+      "peerDependenciesMeta": {
+        "@nuxt/kit": {
+          "optional": true
+        },
+        "@vueuse/core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@dcloudio/vite-plugin-uni/node_modules/unplugin-auto-import/node_modules/magic-string": {
+      "version": "0.30.21",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz",
+      "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.5"
+      }
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+      "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+      "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+      "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+      "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+      "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+      "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+      "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+      "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+      "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+      "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+      "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+      "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+      "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+      "cpu": [
+        "mips64el"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+      "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+      "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+      "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+      "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+      "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+      "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+      "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+      "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+      "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+      "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@intlify/core-base": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz",
+      "integrity": "sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/devtools-if": "9.1.9",
+        "@intlify/message-compiler": "9.1.9",
+        "@intlify/message-resolver": "9.1.9",
+        "@intlify/runtime": "9.1.9",
+        "@intlify/shared": "9.1.9",
+        "@intlify/vue-devtools": "9.1.9"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@intlify/devtools-if": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz",
+      "integrity": "sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/shared": "9.1.9"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@intlify/message-compiler": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz",
+      "integrity": "sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/message-resolver": "9.1.9",
+        "@intlify/shared": "9.1.9",
+        "source-map": "0.6.1"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@intlify/message-resolver": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz",
+      "integrity": "sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@intlify/runtime": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/runtime/-/runtime-9.1.9.tgz",
+      "integrity": "sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/message-compiler": "9.1.9",
+        "@intlify/message-resolver": "9.1.9",
+        "@intlify/shared": "9.1.9"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@intlify/shared": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.1.9.tgz",
+      "integrity": "sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@intlify/vue-devtools": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz",
+      "integrity": "sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/message-resolver": "9.1.9",
+        "@intlify/runtime": "9.1.9",
+        "@intlify/shared": "9.1.9"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@jimp/bmp": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/bmp/-/bmp-0.10.3.tgz",
+      "integrity": "sha512-keMOc5woiDmONXsB/6aXLR4Z5Q+v8lFq3EY2rcj2FmstbDMhRuGbmcBxlEgOqfRjwvtf/wOtJ3Of37oAWtVfLg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "bmp-js": "^0.1.0",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/core": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/core/-/core-0.10.3.tgz",
+      "integrity": "sha512-Gd5IpL3U2bFIO57Fh/OA3HCpWm4uW/pU01E75rI03BXfTdz3T+J7TwvyG1XaqsQ7/DSlS99GXtLQPlfFIe28UA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "any-base": "^1.1.0",
+        "buffer": "^5.2.0",
+        "core-js": "^3.4.1",
+        "exif-parser": "^0.1.12",
+        "file-type": "^9.0.0",
+        "load-bmfont": "^1.3.1",
+        "mkdirp": "^0.5.1",
+        "phin": "^2.9.1",
+        "pixelmatch": "^4.0.2",
+        "tinycolor2": "^1.4.1"
+      }
+    },
+    "node_modules/@jimp/custom": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/custom/-/custom-0.10.3.tgz",
+      "integrity": "sha512-nZmSI+jwTi5IRyNLbKSXQovoeqsw+D0Jn0SxW08wYQvdkiWA8bTlDQFgQ7HVwCAKBm8oKkDB/ZEo9qvHJ+1gAQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/core": "^0.10.3",
+        "core-js": "^3.4.1"
+      }
+    },
+    "node_modules/@jimp/gif": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/gif/-/gif-0.10.3.tgz",
+      "integrity": "sha512-vjlRodSfz1CrUvvrnUuD/DsLK1GHB/yDZXHthVdZu23zYJIW7/WrIiD1IgQ5wOMV7NocfrvPn2iqUfBP81/WWA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1",
+        "omggif": "^1.0.9"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/jpeg": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/jpeg/-/jpeg-0.10.3.tgz",
+      "integrity": "sha512-AAANwgUZOt6f6P7LZxY9lyJ9xclqutYJlsxt3JbriXUGJgrrFAIkcKcqv1nObgmQASSAQKYaMV9KdHjMlWFKlQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1",
+        "jpeg-js": "^0.3.4"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-blit": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-blit/-/plugin-blit-0.10.3.tgz",
+      "integrity": "sha512-5zlKlCfx4JWw9qUVC7GI4DzXyxDWyFvgZLaoGFoT00mlXlN75SarlDwc9iZ/2e2kp4bJWxz3cGgG4G/WXrbg3Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-blur": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-blur/-/plugin-blur-0.10.3.tgz",
+      "integrity": "sha512-cTOK3rjh1Yjh23jSfA6EHCHjsPJDEGLC8K2y9gM7dnTUK1y9NNmkFS23uHpyjgsWFIoH9oRh2SpEs3INjCpZhQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-circle": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-circle/-/plugin-circle-0.10.3.tgz",
+      "integrity": "sha512-51GAPIVelqAcfuUpaM5JWJ0iWl4vEjNXB7p4P7SX5udugK5bxXUjO6KA2qgWmdpHuCKtoNgkzWU9fNSuYp7tCA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-color": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-color/-/plugin-color-0.10.3.tgz",
+      "integrity": "sha512-RgeHUElmlTH7vpI4WyQrz6u59spiKfVQbsG/XUzfWGamFSixa24ZDwX/yV/Ts+eNaz7pZeIuv533qmKPvw2ujg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1",
+        "tinycolor2": "^1.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-contain": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-contain/-/plugin-contain-0.10.3.tgz",
+      "integrity": "sha512-bYJKW9dqzcB0Ihc6u7jSyKa3juStzbLs2LFr6fu8TzA2WkMS/R8h+ddkiO36+F9ILTWHP0CIA3HFe5OdOGcigw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-blit": ">=0.3.5",
+        "@jimp/plugin-resize": ">=0.3.5",
+        "@jimp/plugin-scale": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-cover": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-cover/-/plugin-cover-0.10.3.tgz",
+      "integrity": "sha512-pOxu0cM0BRPzdV468n4dMocJXoMbTnARDY/EpC3ZW15SpMuc/dr1KhWQHgoQX5kVW1Wt8zgqREAJJCQ5KuPKDA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-crop": ">=0.3.5",
+        "@jimp/plugin-resize": ">=0.3.5",
+        "@jimp/plugin-scale": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-crop": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-crop/-/plugin-crop-0.10.3.tgz",
+      "integrity": "sha512-nB7HgOjjl9PgdHr076xZ3Sr6qHYzeBYBs9qvs3tfEEUeYMNnvzgCCGtUl6eMakazZFCMk3mhKmcB9zQuHFOvkg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-displace": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-displace/-/plugin-displace-0.10.3.tgz",
+      "integrity": "sha512-8t3fVKCH5IVqI4lewe4lFFjpxxr69SQCz5/tlpDLQZsrNScNJivHdQ09zljTrVTCSgeCqQJIKgH2Q7Sk/pAZ0w==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-dither": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-dither/-/plugin-dither-0.10.3.tgz",
+      "integrity": "sha512-JCX/oNSnEg1kGQ8ffZ66bEgQOLCY3Rn+lrd6v1jjLy/mn9YVZTMsxLtGCXpiCDC2wG/KTmi4862ysmP9do9dAQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-fisheye": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.10.3.tgz",
+      "integrity": "sha512-RRZb1wqe+xdocGcFtj2xHU7sF7xmEZmIa6BmrfSchjyA2b32TGPWKnP3qyj7p6LWEsXn+19hRYbjfyzyebPElQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-flip": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-flip/-/plugin-flip-0.10.3.tgz",
+      "integrity": "sha512-0epbi8XEzp0wmSjoW9IB0iMu0yNF17aZOxLdURCN3Zr+8nWPs5VNIMqSVa1Y62GSyiMDpVpKF/ITiXre+EqrPg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-rotate": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-gaussian": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.10.3.tgz",
+      "integrity": "sha512-25eHlFbHUDnMMGpgRBBeQ2AMI4wsqCg46sue0KklI+c2BaZ+dGXmJA5uT8RTOrt64/K9Wz5E+2n7eBnny4dfpQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-invert": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-invert/-/plugin-invert-0.10.3.tgz",
+      "integrity": "sha512-effYSApWY/FbtlzqsKXlTLkgloKUiHBKjkQnqh5RL4oQxh/33j6aX+HFdDyQKtsXb8CMd4xd7wyiD2YYabTa0g==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-mask": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-mask/-/plugin-mask-0.10.3.tgz",
+      "integrity": "sha512-twrg8q8TIhM9Z6Jcu9/5f+OCAPaECb0eKrrbbIajJqJ3bCUlj5zbfgIhiQIzjPJ6KjpnFPSqHQfHkU1Vvk/nVw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-normalize": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-normalize/-/plugin-normalize-0.10.3.tgz",
+      "integrity": "sha512-xkb5eZI/mMlbwKkDN79+1/t/+DBo8bBXZUMsT4gkFgMRKNRZ6NQPxlv1d3QpRzlocsl6UMxrHnhgnXdLAcgrXw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-print": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-print/-/plugin-print-0.10.3.tgz",
+      "integrity": "sha512-wjRiI6yjXsAgMe6kVjizP+RgleUCLkH256dskjoNvJzmzbEfO7xQw9g6M02VET+emnbY0CO83IkrGm2q43VRyg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1",
+        "load-bmfont": "^1.4.0"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-blit": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-resize": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-resize/-/plugin-resize-0.10.3.tgz",
+      "integrity": "sha512-rf8YmEB1d7Sg+g4LpqF0Mp+dfXfb6JFJkwlAIWPUOR7lGsPWALavEwTW91c0etEdnp0+JB9AFpy6zqq7Lwkq6w==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-rotate": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-rotate/-/plugin-rotate-0.10.3.tgz",
+      "integrity": "sha512-YXLlRjm18fkW9MOHUaVAxWjvgZM851ofOipytz5FyKp4KZWDLk+dZK1JNmVmK7MyVmAzZ5jsgSLhIgj+GgN0Eg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-blit": ">=0.3.5",
+        "@jimp/plugin-crop": ">=0.3.5",
+        "@jimp/plugin-resize": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-scale": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-scale/-/plugin-scale-0.10.3.tgz",
+      "integrity": "sha512-5DXD7x7WVcX1gUgnlFXQa8F+Q3ThRYwJm+aesgrYvDOY+xzRoRSdQvhmdd4JEEue3lyX44DvBSgCIHPtGcEPaw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-resize": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-shadow": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-shadow/-/plugin-shadow-0.10.3.tgz",
+      "integrity": "sha512-/nkFXpt2zVcdP4ETdkAUL0fSzyrC5ZFxdcphbYBodqD7fXNqChS/Un1eD4xCXWEpW8cnG9dixZgQgStjywH0Mg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-blur": ">=0.3.5",
+        "@jimp/plugin-resize": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/plugin-threshold": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugin-threshold/-/plugin-threshold-0.10.3.tgz",
+      "integrity": "sha512-Dzh0Yq2wXP2SOnxcbbiyA4LJ2luwrdf1MghNIt9H+NX7B+IWw/N8qA2GuSm9n4BPGSLluuhdAWJqHcTiREriVA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5",
+        "@jimp/plugin-color": ">=0.8.0",
+        "@jimp/plugin-resize": ">=0.8.0"
+      }
+    },
+    "node_modules/@jimp/plugins": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/plugins/-/plugins-0.10.3.tgz",
+      "integrity": "sha512-jTT3/7hOScf0EIKiAXmxwayHhryhc1wWuIe3FrchjDjr9wgIGNN2a7XwCgPl3fML17DXK1x8EzDneCdh261bkw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/plugin-blit": "^0.10.3",
+        "@jimp/plugin-blur": "^0.10.3",
+        "@jimp/plugin-circle": "^0.10.3",
+        "@jimp/plugin-color": "^0.10.3",
+        "@jimp/plugin-contain": "^0.10.3",
+        "@jimp/plugin-cover": "^0.10.3",
+        "@jimp/plugin-crop": "^0.10.3",
+        "@jimp/plugin-displace": "^0.10.3",
+        "@jimp/plugin-dither": "^0.10.3",
+        "@jimp/plugin-fisheye": "^0.10.3",
+        "@jimp/plugin-flip": "^0.10.3",
+        "@jimp/plugin-gaussian": "^0.10.3",
+        "@jimp/plugin-invert": "^0.10.3",
+        "@jimp/plugin-mask": "^0.10.3",
+        "@jimp/plugin-normalize": "^0.10.3",
+        "@jimp/plugin-print": "^0.10.3",
+        "@jimp/plugin-resize": "^0.10.3",
+        "@jimp/plugin-rotate": "^0.10.3",
+        "@jimp/plugin-scale": "^0.10.3",
+        "@jimp/plugin-shadow": "^0.10.3",
+        "@jimp/plugin-threshold": "^0.10.3",
+        "core-js": "^3.4.1",
+        "timm": "^1.6.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/png": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/png/-/png-0.10.3.tgz",
+      "integrity": "sha512-YKqk/dkl+nGZxSYIDQrqhmaP8tC3IK8H7dFPnnzFVvbhDnyYunqBZZO3SaZUKTichClRw8k/CjBhbc+hifSGWg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/utils": "^0.10.3",
+        "core-js": "^3.4.1",
+        "pngjs": "^3.3.3"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/tiff": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/tiff/-/tiff-0.10.3.tgz",
+      "integrity": "sha512-7EsJzZ5Y/EtinkBGuwX3Bi4S+zgbKouxjt9c82VJTRJOQgLWsE/RHqcyRCOQBhHAZ9QexYmDz34medfLKdoX0g==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "core-js": "^3.4.1",
+        "utif": "^2.0.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/types": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/types/-/types-0.10.3.tgz",
+      "integrity": "sha512-XGmBakiHZqseSWr/puGN+CHzx0IKBSpsKlmEmsNV96HKDiP6eu8NSnwdGCEq2mmIHe0JNcg1hqg59hpwtQ7Tiw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/bmp": "^0.10.3",
+        "@jimp/gif": "^0.10.3",
+        "@jimp/jpeg": "^0.10.3",
+        "@jimp/png": "^0.10.3",
+        "@jimp/tiff": "^0.10.3",
+        "core-js": "^3.4.1",
+        "timm": "^1.6.1"
+      },
+      "peerDependencies": {
+        "@jimp/custom": ">=0.3.5"
+      }
+    },
+    "node_modules/@jimp/utils": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/@jimp/utils/-/utils-0.10.3.tgz",
+      "integrity": "sha512-VcSlQhkil4ReYmg1KkN+WqHyYfZ2XfZxDsKAHSfST1GEz/RQHxKZbX+KhFKtKflnL0F4e6DlNQj3vznMNXCR2w==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "core-js": "^3.4.1",
+        "regenerator-runtime": "^0.13.3"
+      }
+    },
+    "node_modules/@jimp/utils/node_modules/regenerator-runtime": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+      "license": "MIT"
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.13",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.0",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "node_modules/@jridgewell/remapping": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+      "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/source-map": {
+      "version": "0.3.11",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+      "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+      "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+      "license": "MIT"
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.31",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+      "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@napi-rs/lzma-linux-x64-gnu": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz",
+      "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==",
+      "cpu": [
+        "x64"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": "^22.20 || ^24.12 || >=25"
+      }
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.5",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@rolldown/pluginutils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+      "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+      "license": "MIT"
+    },
+    "node_modules/@rollup/pluginutils": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+      "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "^1.0.0",
+        "estree-walker": "^2.0.2",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.64.5.tgz",
+      "integrity": "sha512-MrfgRQSpD5hkkRg6XI16B6EDLb+6+xp8xje6bpdSwkYw+qxrBKbUVrRAQu9h82UT+QumSIVQ8HXsXjPd2dlhqw==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.64.5.tgz",
+      "integrity": "sha512-+uu2p/R9Tzn8GpoQyX1pAo5dmKT1DhXevfaCzqzmPFhnLjHLWw7uWkaVGlxmhwYoRiYYhsGfRcD5cTBpL7rgSw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.64.5.tgz",
+      "integrity": "sha512-17dys+YEmzwzzFVHQAVDONg5FALXY9kd99HFEpfk4gJVHYxoh5bGea3D4t1fXXnwkTcOe25wPyd6nWS0I8IdLQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.64.5.tgz",
+      "integrity": "sha512-wg0zQEKkEvFZf1UaaX1UELOoPs//OSKUG7D+yITuqOsAvza7LvHTv5Wu4nmMfzNG7EYI2jp2PJC7Id6OETmsYQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.64.5.tgz",
+      "integrity": "sha512-CoJmWcpEMuwin+TZ/ev/H9uDyF/uxUKQSWXdmIPn/UBx/uGV9+4ebMp0FwnlhWR9PE1AdzYsKf3bZevhif38+A==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.64.5.tgz",
+      "integrity": "sha512-PxZnLAaTUAL5xG0W2BXLeYPKrK2b3LIASV2/e/Kf7PZvSLI1iAQIm9B9aJD+YyFIT7hc6qaMV3+OOO35R28LfA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.64.5.tgz",
+      "integrity": "sha512-uPo3IvnONjhbFXwWgroBeFwOicuhT7ZwQrnzkzmOtBJzeQbkUJUE1SJDfDI31ijQ5+ZUIA6sPrdUMxTSnxUWAg==",
+      "cpu": [
+        "arm"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.64.5.tgz",
+      "integrity": "sha512-ywI8Jyuc4LyHYTjC0mw4yA1ulvZBkHusdpWnoiEBsmBuHvSnt90btTBGCZ+s/2y+YNNfVAEKy33nPo5UI9zTmg==",
+      "cpu": [
+        "arm"
+      ],
+      "libc": [
+        "musl"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.64.5.tgz",
+      "integrity": "sha512-tmuXJoQ/3ovSr637aykZMdQteU/CB2APAz2CrvsbibuoHZi1BS1Db13cVViBdEARGwXCLn1DSJ8wsjoThLJPGA==",
+      "cpu": [
+        "arm64"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.64.5.tgz",
+      "integrity": "sha512-5FMjSYNcUOHx7oW8Qu9KB6jGPpvF/8sG7+BDHwU/Ihh1/6FMJ9ySmsFG4tJ1qbNRuP8OLzCBDso4sF0mQaLuFQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "libc": [
+        "musl"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loong64-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.64.5.tgz",
+      "integrity": "sha512-K8ZJ+neLDbUkIrL8dqF/5LtuVCrKwo27kREgOlxjBEjlOXwHvDnHLU8Z/UKv/B49qi7e8hsSDOyoJwhwqhvX4w==",
+      "cpu": [
+        "loong64"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loong64-musl": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.64.5.tgz",
+      "integrity": "sha512-NlVxsq7PFPv0DBKGuNWRDKixQYQCjM53zl04mxEcKMBmJbCBIUm1JdPfIWDRHyOOFzzYPmLQzfeEwh4716ayQg==",
+      "cpu": [
+        "loong64"
+      ],
+      "libc": [
+        "musl"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.64.5.tgz",
+      "integrity": "sha512-ARhRHJYs5eCFet5azfrHD97vOkD8OzNW2RSMlvo5CcBqXaTOLfp0OHDtUQh7/K5AL5fUYoFp2fgC9KDg4vVYMQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-ppc64-musl": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.64.5.tgz",
+      "integrity": "sha512-atSgreM5C7jpxd9aEXN+6vJ5wTd05iYw+S3FiQpw7VsoEl8B90llbq35ARON+GOHj5QlVQEq2vOKWCHTob/BSQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "libc": [
+        "musl"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.64.5.tgz",
+      "integrity": "sha512-vmlmwBFGnjVWxSRoVabNkyYuscSmg52Pd0fM8jEbNT3Jmka4A6HcB84x4uAmuumznWfBVaxKOqU6jbEgomWKCA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-musl": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.64.5.tgz",
+      "integrity": "sha512-hhJrP6S9WkbsbcHgUkvCBS5Cn8IdsG8XjlLZyxjnv9+NdoYfbbZE4TWJYr8apdaj1M5t5Y1id2StnEslxpNFyA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "libc": [
+        "musl"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.64.5.tgz",
+      "integrity": "sha512-NNVCyN9pGrwFmQa4bf+Cnf5aVH3g6ZpnlOg1Cs/H9swIHT9bRixijfzUqyEIWm1WtiAuR1LJ+rJH6zpBm8kgQA==",
+      "cpu": [
+        "s390x"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.64.5.tgz",
+      "integrity": "sha512-dR9nd6OKnvSS60Ifz/L7Mj5zzYyoqyRn2NwTuaOONKaa3xsVGXyp8YusMbvFyEOR94DxnwgcbgsFqkHd29ZSzQ==",
+      "cpu": [
+        "x64"
+      ],
+      "libc": [
+        "glibc"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.64.5.tgz",
+      "integrity": "sha512-1tzsMjaqhsh3bAO6SJiJqh8hIr9sSPRd+i2vPPxJHod8/XYnf9TEnK0z/u3r1z1AkI347X0KbRSg9dWcxeGahw==",
+      "cpu": [
+        "x64"
+      ],
+      "libc": [
+        "musl"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-openbsd-x64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.64.5.tgz",
+      "integrity": "sha512-01mWMQblKoXXsmk28KXtpbA96w7g/aOWUoV3AC16fdHdqkykGalqyyM+5u8M7uP5/MEMiiPv69Hv7iv/hEH/dA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-openharmony-arm64": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.64.5.tgz",
+      "integrity": "sha512-trdnMPb/DNm4V/CgsaoGgr90HfQQ071wfK0KoIs4YpLvjBgVQGXhGabg2Z6nK4EcYNilrb9ZZPcsP6+zpJIdxQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.64.5.tgz",
+      "integrity": "sha512-x2LxZlfdfsw99T6/qb9EqE/Qi84JWzibjyOJyhJsgFJy6CafaTiqIXCCnslCGrV5XWNh7fwrS3FbRENcuKnooA==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.64.5.tgz",
+      "integrity": "sha512-/Qd/9aDQIo0+jmItgBmPIs8195YVbDxRRApn47GyufgbutCDOh7eP5vSKKlI4QNFeaI+wKQAkSMsPnF3EuMpaA==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-gnu": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.64.5.tgz",
+      "integrity": "sha512-ngUJ/XvOWrqbd2IMsfXfh2xXFLTP3sY7sCKvxbGvYdBZ1KmXFd3ewDZ9n3/GNzAUgzRuhLT/UvJRivbNoAQRBw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.64.5.tgz",
+      "integrity": "sha512-IhV6ew/DuzUWwHaYmlh7MrPCV3lKFUq/amTEwysi4r/mwNPAEfAMh5dYWeTSPTeMy2pFHGMEWYtPkHzfX3tG5A==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.9.tgz",
+      "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+      "license": "MIT"
+    },
+    "node_modules/@types/node": {
+      "version": "22.10.2",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.2.tgz",
+      "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "undici-types": "~6.20.0"
+      }
+    },
+    "node_modules/@vitejs/plugin-basic-ssl": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz",
+      "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.21.3"
+      },
+      "peerDependencies": {
+        "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
+      }
+    },
+    "node_modules/@vitejs/plugin-legacy": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-5.3.2.tgz",
+      "integrity": "sha512-8moCOrIMaZ/Rjln0Q6GsH6s8fAt1JOI3k8nmfX4tXUxE5KAExVctSyOBk+A25GClsdSWqIk2yaUthH3KJ2X4tg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.23.9",
+        "@babel/preset-env": "^7.23.9",
+        "browserslist": "^4.23.0",
+        "browserslist-to-esbuild": "^2.1.1",
+        "core-js": "^3.36.0",
+        "magic-string": "^0.30.7",
+        "regenerator-runtime": "^0.14.1",
+        "systemjs": "^6.14.3"
+      },
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "peerDependencies": {
+        "terser": "^5.4.0",
+        "vite": "^5.0.0"
+      }
+    },
+    "node_modules/@vitejs/plugin-vue": {
+      "version": "5.2.4",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+      "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+      "license": "MIT",
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^5.0.0 || ^6.0.0",
+        "vue": "^3.2.25"
+      }
+    },
+    "node_modules/@vitejs/plugin-vue-jsx": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.1.0.tgz",
+      "integrity": "sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.23.3",
+        "@babel/plugin-transform-typescript": "^7.23.3",
+        "@vue/babel-plugin-jsx": "^1.1.5"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^4.0.0 || ^5.0.0",
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/@volar/language-core": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.1.6.tgz",
+      "integrity": "sha512-pAlMCGX/HatBSiDFMdMyqUshkbwWbLxpN/RL7HCQDOo2gYBE+uS+nanosLc1qR6pTQ/U8q00xt8bdrrAFPSC0A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@volar/source-map": "2.1.6"
+      }
+    },
+    "node_modules/@volar/source-map": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.1.6.tgz",
+      "integrity": "sha512-TeyH8pHHonRCHYI91J7fWUoxi0zWV8whZTVRlsWHSYfjm58Blalkf9LrZ+pj6OiverPTmrHRkBsG17ScQyWECw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "muggle-string": "^0.4.0"
+      }
+    },
+    "node_modules/@volar/typescript": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.1.6.tgz",
+      "integrity": "sha512-JgPGhORHqXuyC3r6skPmPHIZj4LoMmGlYErFTuPNBq9Nhc9VTv7ctHY7A3jMN3ngKEfRrfnUcwXHztvdSQqNfw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@volar/language-core": "2.1.6",
+        "path-browserify": "^1.0.1"
+      }
+    },
+    "node_modules/@vue/babel-helper-vue-transform-on": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz",
+      "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@vue/babel-plugin-jsx": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz",
+      "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.27.1",
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/plugin-syntax-jsx": "^7.27.1",
+        "@babel/template": "^7.27.2",
+        "@babel/traverse": "^7.28.0",
+        "@babel/types": "^7.28.2",
+        "@vue/babel-helper-vue-transform-on": "1.5.0",
+        "@vue/babel-plugin-resolve-type": "1.5.0",
+        "@vue/shared": "^3.5.18"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      },
+      "peerDependenciesMeta": {
+        "@babel/core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/babel-plugin-jsx/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-jsx/node_modules/@vue/shared": {
+      "version": "3.5.43",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.43.tgz",
+      "integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@vue/babel-plugin-resolve-type": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz",
+      "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.27.1",
+        "@babel/helper-module-imports": "^7.27.1",
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/parser": "^7.28.0",
+        "@vue/compiler-sfc": "^3.5.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sxzz"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@babel/code-frame": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.7.tgz",
+      "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@babel/parser": {
+      "version": "7.29.9",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.9.tgz",
+      "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.8"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-core": {
+      "version": "3.5.43",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.43.tgz",
+      "integrity": "sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.8",
+        "@vue/shared": "3.5.43",
+        "entities": "^7.0.1",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.2.1"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-dom": {
+      "version": "3.5.43",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.43.tgz",
+      "integrity": "sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@vue/compiler-core": "3.5.43",
+        "@vue/shared": "3.5.43"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-sfc": {
+      "version": "3.5.43",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.43.tgz",
+      "integrity": "sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.8",
+        "@vue/compiler-core": "3.5.43",
+        "@vue/compiler-dom": "3.5.43",
+        "@vue/compiler-ssr": "3.5.43",
+        "@vue/shared": "3.5.43",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.21",
+        "postcss": "^8.5.28",
+        "source-map-js": "^1.2.1"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-ssr": {
+      "version": "3.5.43",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.43.tgz",
+      "integrity": "sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@vue/compiler-dom": "3.5.43",
+        "@vue/shared": "3.5.43"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/shared": {
+      "version": "3.5.43",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.43.tgz",
+      "integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/magic-string": {
+      "version": "0.30.21",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz",
+      "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.5"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type/node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
+      "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.23.9",
+        "@vue/shared": "3.4.21",
+        "entities": "^4.5.0",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "node_modules/@vue/compiler-core/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
+      "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/compiler-core": "3.4.21",
+        "@vue/shared": "3.4.21"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
+      "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.23.9",
+        "@vue/compiler-core": "3.4.21",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-ssr": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.7",
+        "postcss": "^8.4.35",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
+      "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/shared": "3.4.21"
+      }
+    },
+    "node_modules/@vue/consolidate": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@vue/consolidate/-/consolidate-1.0.0.tgz",
+      "integrity": "sha512-oTyUE+QHIzLw2PpV14GD/c7EohDyP64xCniWTcqcEmTd699eFqTIwOmtDYjcO1j3QgdXoJEoWv1/cCdLrRoOfg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.12.0"
+      }
+    },
+    "node_modules/@vue/devtools-api": {
+      "version": "6.6.4",
+      "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+      "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
+      "license": "MIT"
+    },
+    "node_modules/@vue/language-core": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-2.0.6.tgz",
+      "integrity": "sha512-UzqU12tzf9XLqRO3TiWPwRNpP4fyUzE6MAfOQWQNZ4jy6a30ARRUpmODDKq6O8C4goMc2AlPqTmjOHPjHkilSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@volar/language-core": "~2.1.2",
+        "@vue/compiler-dom": "^3.4.0",
+        "@vue/shared": "^3.4.0",
+        "computeds": "^0.0.1",
+        "minimatch": "^9.0.3",
+        "path-browserify": "^1.0.1",
+        "vue-template-compiler": "^2.7.14"
+      },
+      "peerDependencies": {
+        "typescript": "*"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz",
+      "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/shared": "3.4.21"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
+      "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/reactivity": "3.4.21",
+        "@vue/shared": "3.4.21"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
+      "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/runtime-core": "3.4.21",
+        "@vue/shared": "3.4.21",
+        "csstype": "^3.1.3"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
+      "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.4.21",
+        "@vue/shared": "3.4.21"
+      },
+      "peerDependencies": {
+        "vue": "3.4.21"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.21.tgz",
+      "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
+      "license": "MIT"
+    },
+    "node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/acorn": {
+      "version": "8.19.0",
+      "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.19.0.tgz",
+      "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==",
+      "license": "MIT",
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/adm-zip": {
+      "version": "0.5.16",
+      "resolved": "https://registry.npmmirror.com/adm-zip/-/adm-zip-0.5.16.tgz",
+      "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.0"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/any-base": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/any-base/-/any-base-1.1.0.tgz",
+      "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==",
+      "license": "MIT"
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "license": "ISC",
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/autoprefixer": {
+      "version": "10.4.20",
+      "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.20.tgz",
+      "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "browserslist": "^4.23.3",
+        "caniuse-lite": "^1.0.30001646",
+        "fraction.js": "^4.3.7",
+        "normalize-range": "^0.1.2",
+        "picocolors": "^1.0.1",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "bin": {
+        "autoprefixer": "bin/autoprefixer"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs2": {
+      "version": "0.4.17",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz",
+      "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.28.6",
+        "@babel/helper-define-polyfill-provider": "^0.6.8",
+        "semver": "^6.3.1"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs3": {
+      "version": "0.14.2",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz",
+      "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-define-polyfill-provider": "^0.6.8",
+        "core-js-compat": "^3.48.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-regenerator": {
+      "version": "0.6.8",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz",
+      "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-define-polyfill-provider": "^0.6.8"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/base64url": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/base64url/-/base64url-3.0.1.tgz",
+      "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/baseline-browser-mapping": {
+      "version": "2.11.28",
+      "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.28.tgz",
+      "integrity": "sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==",
+      "license": "Apache-2.0",
+      "bin": {
+        "baseline-browser-mapping": "dist/cli.cjs"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
+      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/bmp-js": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmmirror.com/bmp-js/-/bmp-js-0.1.0.tgz",
+      "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==",
+      "license": "MIT"
+    },
+    "node_modules/body-parser": {
+      "version": "1.20.3",
+      "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.3.tgz",
+      "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "content-type": "~1.0.5",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "on-finished": "2.4.1",
+        "qs": "6.13.0",
+        "raw-body": "2.5.2",
+        "type-is": "~1.6.18",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/body-parser/node_modules/qs": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz",
+      "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "side-channel": "^1.0.6"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.1.7.tgz",
+      "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.29.3",
+      "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.29.3.tgz",
+      "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "baseline-browser-mapping": "^2.11.26",
+        "caniuse-lite": "^1.0.30001813",
+        "electron-to-chromium": "^1.5.439",
+        "node-releases": "^2.0.57",
+        "update-browserslist-db": "^1.3.3"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/browserslist-to-esbuild": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/browserslist-to-esbuild/-/browserslist-to-esbuild-2.1.1.tgz",
+      "integrity": "sha512-KN+mty6C3e9AN8Z5dI1xeN15ExcRNeISoC3g7V0Kax/MMF9MSoYA2G7lkTTcVUFntiEjkpI0HNgqJC1NjdyNUw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "meow": "^13.0.0"
+      },
+      "bin": {
+        "browserslist-to-esbuild": "cli/index.js"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "browserslist": "*"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/buffer-equal": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/buffer-equal/-/buffer-equal-0.0.1.tgz",
+      "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/bytes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/cac": {
+      "version": "6.7.9",
+      "resolved": "https://registry.npmmirror.com/cac/-/cac-6.7.9.tgz",
+      "integrity": "sha512-XN5qEpfNQCJ8jRaZgitSkkukjMRCGio+X3Ks5KUbGGlPbV+pSem1l9VuzooCBXOiMFshUZgyYqg6rgN8rjkb/w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
+      "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001815",
+      "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001815.tgz",
+      "integrity": "sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "CC-BY-4.0"
+    },
+    "node_modules/centra": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmmirror.com/centra/-/centra-2.7.0.tgz",
+      "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6"
+      }
+    },
+    "node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+      "license": "MIT",
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "license": "MIT"
+    },
+    "node_modules/commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/compare-versions": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/compare-versions/-/compare-versions-3.6.0.tgz",
+      "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
+      "license": "MIT"
+    },
+    "node_modules/computeds": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz",
+      "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/confbox": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz",
+      "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+      "license": "MIT"
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-type": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz",
+      "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "license": "MIT"
+    },
+    "node_modules/cookie": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.6.0.tgz",
+      "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/core-js": {
+      "version": "3.50.0",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.50.0.tgz",
+      "integrity": "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/core-js-compat": {
+      "version": "3.50.0",
+      "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.50.0.tgz",
+      "integrity": "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "browserslist": "^4.28.7"
+      },
+      "engines": {
+        "node": ">=6.4.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/core-js-pure": {
+      "version": "3.50.0",
+      "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.50.0.tgz",
+      "integrity": "sha512-6GP3Pxz4IKyWjAfa747vIu/jilB5z29JWROLqH/b+pXVcpgh6tM06ZIBwSuglgVqzDYURhOK6oEzTrG0bCHitA==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/css-font-size-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz",
+      "integrity": "sha512-Q+svMDbMlelgCfH/RVDKtTDaf5021O486ZThQPIpahnIjUkMUslC+WuOQSWTgGSrNCH08Y7tYNEmmy0hkfMI8Q==",
+      "license": "MIT"
+    },
+    "node_modules/css-font-stretch-keywords": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz",
+      "integrity": "sha512-KmugPO2BNqoyp9zmBIUGwt58UQSfyk1X5DbOlkb2pckDXFSAfjsD5wenb88fNrD6fvS+vu90a/tsPpb9vb0SLg==",
+      "license": "MIT"
+    },
+    "node_modules/css-font-style-keywords": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz",
+      "integrity": "sha512-0Fn0aTpcDktnR1RzaBYorIxQily85M2KXRpzmxQPgh8pxUN9Fcn00I8u9I3grNr1QXVgCl9T5Imx0ZwKU973Vg==",
+      "license": "MIT"
+    },
+    "node_modules/css-font-weight-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz",
+      "integrity": "sha512-5So8/NH+oDD+EzsnF4iaG4ZFHQ3vaViePkL1ZbZ5iC/KrsCY+WHq/lvOgrtmuOQ9pBBZ1ADGpaf+A4lj1Z9eYA==",
+      "license": "MIT"
+    },
+    "node_modules/css-list-helpers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/css-list-helpers/-/css-list-helpers-2.0.0.tgz",
+      "integrity": "sha512-9Bj8tZ0jWbAM3u/U6m/boAzAwLPwtjzFvwivr2piSvyVa3K3rChJzQy4RIHkNkKiZCHrEMWDJWtTR8UyVhdDnQ==",
+      "license": "MIT"
+    },
+    "node_modules/css-system-font-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz",
+      "integrity": "sha512-1umTtVd/fXS25ftfjB71eASCrYhilmEsvDEI6wG/QplnmlfmVM5HkZ/ZX46DT5K3eblFPgLUHt5BRCb0YXkSFA==",
+      "license": "MIT"
+    },
+    "node_modules/cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+      "license": "MIT",
+      "bin": {
+        "cssesc": "bin/cssesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz",
+      "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+      "license": "MIT"
+    },
+    "node_modules/de-indent": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz",
+      "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
+    },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.5.452",
+      "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.452.tgz",
+      "integrity": "sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==",
+      "license": "ISC"
+    },
+    "node_modules/encodeurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/entities": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz",
+      "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-module-lexer": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
+      "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
+      "license": "MIT"
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+      "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.20.2.tgz",
+      "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.20.2",
+        "@esbuild/android-arm": "0.20.2",
+        "@esbuild/android-arm64": "0.20.2",
+        "@esbuild/android-x64": "0.20.2",
+        "@esbuild/darwin-arm64": "0.20.2",
+        "@esbuild/darwin-x64": "0.20.2",
+        "@esbuild/freebsd-arm64": "0.20.2",
+        "@esbuild/freebsd-x64": "0.20.2",
+        "@esbuild/linux-arm": "0.20.2",
+        "@esbuild/linux-arm64": "0.20.2",
+        "@esbuild/linux-ia32": "0.20.2",
+        "@esbuild/linux-loong64": "0.20.2",
+        "@esbuild/linux-mips64el": "0.20.2",
+        "@esbuild/linux-ppc64": "0.20.2",
+        "@esbuild/linux-riscv64": "0.20.2",
+        "@esbuild/linux-s390x": "0.20.2",
+        "@esbuild/linux-x64": "0.20.2",
+        "@esbuild/netbsd-x64": "0.20.2",
+        "@esbuild/openbsd-x64": "0.20.2",
+        "@esbuild/sunos-x64": "0.20.2",
+        "@esbuild/win32-arm64": "0.20.2",
+        "@esbuild/win32-ia32": "0.20.2",
+        "@esbuild/win32-x64": "0.20.2"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
+      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+      "license": "MIT"
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/exif-parser": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmmirror.com/exif-parser/-/exif-parser-0.1.12.tgz",
+      "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="
+    },
+    "node_modules/express": {
+      "version": "4.20.0",
+      "resolved": "https://registry.npmmirror.com/express/-/express-4.20.0.tgz",
+      "integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "accepts": "~1.3.8",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.20.3",
+        "content-disposition": "0.5.4",
+        "content-type": "~1.0.4",
+        "cookie": "0.6.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "encodeurl": "~2.0.0",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.2.0",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "merge-descriptors": "1.0.3",
+        "methods": "~1.1.2",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.10",
+        "proxy-addr": "~2.0.7",
+        "qs": "6.11.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.2.1",
+        "send": "0.19.0",
+        "serve-static": "1.16.0",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/exsolve": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.1.3.tgz",
+      "integrity": "sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==",
+      "license": "MIT"
+    },
+    "node_modules/fast-glob": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz",
+      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.2",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.8"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/fastq": {
+      "version": "1.20.3",
+      "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.3.tgz",
+      "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==",
+      "license": "ISC",
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/file-type": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmmirror.com/file-type/-/file-type-9.0.0.tgz",
+      "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+      "license": "MIT",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz",
+      "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "statuses": "2.0.1",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/finalhandler/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.16.1.tgz",
+      "integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/forwarded": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
+      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fraction.js": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz",
+      "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "patreon",
+        "url": "https://github.com/sponsors/rawify"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fs-extra": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/generic-names": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/generic-names/-/generic-names-4.0.0.tgz",
+      "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==",
+      "license": "MIT",
+      "dependencies": {
+        "loader-utils": "^3.2.0"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/global": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz",
+      "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
+      "license": "MIT",
+      "dependencies": {
+        "min-document": "^2.19.0",
+        "process": "^0.11.10"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "license": "ISC"
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hash-sum": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-2.0.0.tgz",
+      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+      "license": "MIT"
+    },
+    "node_modules/hasown": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.4.tgz",
+      "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+      "license": "MIT",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "he": "bin/he"
+      }
+    },
+    "node_modules/http-errors": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/icss-replace-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
+      "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==",
+      "license": "ISC"
+    },
+    "node_modules/icss-utils": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz",
+      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+      "license": "ISC",
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/immutable": {
+      "version": "4.3.9",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.9.tgz",
+      "integrity": "sha512-ObHy4YN7ycwZOUCLI1/6svfyAFu7vL8RhAvVu/bh/RZW9EPlOyDaQ9jDQWCtdqzaXUjgXZCW1migtHE7YI7UGQ==",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/invert-kv": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/invert-kv/-/invert-kv-3.0.1.tgz",
+      "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/invert-kv?sponsor=1"
+      }
+    },
+    "node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "license": "MIT",
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.17.0",
+      "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.17.0.tgz",
+      "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==",
+      "license": "MIT",
+      "dependencies": {
+        "hasown": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-function": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/is-function/-/is-function-1.0.2.tgz",
+      "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==",
+      "license": "MIT"
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "license": "MIT",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/isbinaryfile": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-5.0.2.tgz",
+      "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 18.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/gjtorikian/"
+      }
+    },
+    "node_modules/jimp": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmmirror.com/jimp/-/jimp-0.10.3.tgz",
+      "integrity": "sha512-meVWmDMtyUG5uYjFkmzu0zBgnCvvxwWNi27c4cg55vWNVC9ES4Lcwb+ogx+uBBQE3Q+dLKjXaLl0JVW+nUNwbQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "@jimp/custom": "^0.10.3",
+        "@jimp/plugins": "^0.10.3",
+        "@jimp/types": "^0.10.3",
+        "core-js": "^3.4.1",
+        "regenerator-runtime": "^0.13.3"
+      }
+    },
+    "node_modules/jimp/node_modules/regenerator-runtime": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+      "license": "MIT"
+    },
+    "node_modules/jpeg-js": {
+      "version": "0.3.7",
+      "resolved": "https://registry.npmmirror.com/jpeg-js/-/jpeg-js-0.3.7.tgz",
+      "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "license": "MIT"
+    },
+    "node_modules/jsesc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz",
+      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "license": "MIT",
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsonc-parser": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+      "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+      "license": "MIT"
+    },
+    "node_modules/jsonfile": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.1.tgz",
+      "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
+      "license": "MIT",
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/lcid": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/lcid/-/lcid-3.1.1.tgz",
+      "integrity": "sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==",
+      "license": "MIT",
+      "dependencies": {
+        "invert-kv": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/licia": {
+      "version": "1.41.1",
+      "resolved": "https://registry.npmmirror.com/licia/-/licia-1.41.1.tgz",
+      "integrity": "sha512-XqObV8u1KEMdYWaNK0leRrTwhzKnLQEkhbnuUu7qGNH3zJoN7l9sfvF6PfHstSCuUOmpEP+0SBjRrk0I9uZs8g==",
+      "license": "MIT"
+    },
+    "node_modules/lilconfig": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz",
+      "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/lines-and-columns": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz",
+      "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==",
+      "license": "MIT",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      }
+    },
+    "node_modules/load-bmfont": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/load-bmfont/-/load-bmfont-1.4.2.tgz",
+      "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==",
+      "license": "MIT",
+      "dependencies": {
+        "buffer-equal": "0.0.1",
+        "mime": "^1.3.4",
+        "parse-bmfont-ascii": "^1.0.3",
+        "parse-bmfont-binary": "^1.0.5",
+        "parse-bmfont-xml": "^1.1.4",
+        "phin": "^3.7.1",
+        "xhr": "^2.0.1",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/load-bmfont/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/load-bmfont/node_modules/phin": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmmirror.com/phin/-/phin-3.7.1.tgz",
+      "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==",
+      "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+      "license": "MIT",
+      "dependencies": {
+        "centra": "^2.7.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/loader-utils": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.3.1.tgz",
+      "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12.13.0"
+      }
+    },
+    "node_modules/local-pkg": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.2.1.tgz",
+      "integrity": "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==",
+      "license": "MIT",
+      "dependencies": {
+        "mlly": "^1.7.4",
+        "pkg-types": "^2.3.0",
+        "quansync": "^0.2.11"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/local-pkg/node_modules/confbox": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.3.1.tgz",
+      "integrity": "sha512-cKUSoKa8YxFZZSmraVi7onONx3amu77ngK3kGpsYHDH7drPwCRkQE1RYMPlLRrMtnciRj274XNRxcHxnKmDSnA==",
+      "license": "MIT"
+    },
+    "node_modules/local-pkg/node_modules/pkg-types": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.3.tgz",
+      "integrity": "sha512-j/lCFdcppV0JxWpCEITdbDltBxPP6cHT+yNJ6Go2OgoSA9518X847X9z0p6LtA4Nc16+eQzCZjRrWanTGvHJ5w==",
+      "license": "MIT",
+      "dependencies": {
+        "confbox": "^0.3.1",
+        "exsolve": "^1.1.1",
+        "pathe": "^2.0.3"
+      }
+    },
+    "node_modules/localstorage-polyfill": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/localstorage-polyfill/-/localstorage-polyfill-1.0.1.tgz",
+      "integrity": "sha512-m4iHVZxFH5734oQcPKU08025gIz2+4bjWR9lulP8ZYxEJR0BpA0w32oJmkzh8y3UI9ci7xCBehQDc3oA1X+VHw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.30.11",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz",
+      "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.0"
+      }
+    },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/meow": {
+      "version": "13.2.0",
+      "resolved": "https://registry.npmmirror.com/meow/-/meow-13.2.0.tgz",
+      "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/merge": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz",
+      "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==",
+      "license": "MIT"
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+      "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
+      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+      "license": "MIT",
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/mime": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-3.0.0.tgz",
+      "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/min-document": {
+      "version": "2.19.2",
+      "resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.2.tgz",
+      "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==",
+      "license": "MIT",
+      "dependencies": {
+        "dom-walk": "^0.1.0"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "9.0.9",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.9.tgz",
+      "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/mkdirp": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+      "license": "MIT",
+      "dependencies": {
+        "minimist": "^1.2.6"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/mlly": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.2.tgz",
+      "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
+      "license": "MIT",
+      "dependencies": {
+        "acorn": "^8.16.0",
+        "pathe": "^2.0.3",
+        "pkg-types": "^1.3.1",
+        "ufo": "^1.6.3"
+      }
+    },
+    "node_modules/module-alias": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz",
+      "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
+      "license": "MIT"
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
+    "node_modules/muggle-string": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz",
+      "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.20",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.20.tgz",
+      "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.58",
+      "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.58.tgz",
+      "integrity": "sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/nostics": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/nostics/-/nostics-1.3.0.tgz",
+      "integrity": "sha512-wzRsrJwNlFbqIRQt8aCeL2WE8USip/uuvGSOZV1D02CxX8ABTMbw8IywKjH7yWHETMXbWJI4OBpihg9rmz2Vyg==",
+      "license": "MIT"
+    },
+    "node_modules/object-inspect": {
+      "version": "1.13.4",
+      "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
+      "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/omggif": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmmirror.com/omggif/-/omggif-1.0.10.tgz",
+      "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==",
+      "license": "MIT"
+    },
+    "node_modules/on-finished": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/os-locale-s-fix": {
+      "version": "1.0.8-fix-1",
+      "resolved": "https://registry.npmmirror.com/os-locale-s-fix/-/os-locale-s-fix-1.0.8-fix-1.tgz",
+      "integrity": "sha512-Sv0OvhPiMutICiwORAUefv02DCPb62IelBmo8ZsSrRHyI3FStqIWZvjqDkvtjU+lcujo7UNir+dCwKSqlEQ/5w==",
+      "license": "MIT",
+      "dependencies": {
+        "lcid": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10",
+        "yarn": "^1.22.4"
+      }
+    },
+    "node_modules/pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+      "license": "(MIT AND Zlib)"
+    },
+    "node_modules/parse-bmfont-ascii": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
+      "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==",
+      "license": "MIT"
+    },
+    "node_modules/parse-bmfont-binary": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
+      "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==",
+      "license": "MIT"
+    },
+    "node_modules/parse-bmfont-xml": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmmirror.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz",
+      "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==",
+      "license": "MIT",
+      "dependencies": {
+        "xml-parse-from-string": "^1.0.0",
+        "xml2js": "^0.5.0"
+      }
+    },
+    "node_modules/parse-css-font": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/parse-css-font/-/parse-css-font-4.0.0.tgz",
+      "integrity": "sha512-lnY7dTUfjRXsSo5G5C639L8RaBBaVSgL+5hacIFKsNHzeCJQ5SFSZv1DZmc7+wZv/22PFGOq2YbaEHLdaCS/mQ==",
+      "license": "MIT",
+      "dependencies": {
+        "css-font-size-keywords": "^1.0.0",
+        "css-font-stretch-keywords": "^1.0.1",
+        "css-font-style-keywords": "^1.0.1",
+        "css-font-weight-keywords": "^1.0.0",
+        "css-list-helpers": "^2.0.0",
+        "css-system-font-keywords": "^1.0.0",
+        "unquote": "^1.1.1"
+      }
+    },
+    "node_modules/parse-headers": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/parse-headers/-/parse-headers-2.0.6.tgz",
+      "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==",
+      "license": "MIT"
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/path-browserify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz",
+      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "license": "MIT"
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.10",
+      "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
+      "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/pathe": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz",
+      "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+      "license": "MIT"
+    },
+    "node_modules/phin": {
+      "version": "2.9.3",
+      "resolved": "https://registry.npmmirror.com/phin/-/phin-2.9.3.tgz",
+      "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==",
+      "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+      "license": "MIT"
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.0.tgz",
+      "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
+      "license": "ISC"
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.2.tgz",
+      "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pinia": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
+      "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/devtools-api": "^6.5.0",
+        "vue-demi": ">=0.14.5"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.4.0",
+        "typescript": ">=4.4.4",
+        "vue": "^2.6.14 || ^3.3.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pinia/node_modules/vue-demi": {
+      "version": "0.14.10",
+      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
+      "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pinyin-pro": {
+      "version": "3.27.0",
+      "resolved": "https://registry.npmmirror.com/pinyin-pro/-/pinyin-pro-3.27.0.tgz",
+      "integrity": "sha512-Osdgjwe7Rm17N2paDMM47yW+jUIUH3+0RGo8QP39ZTLpTaJVDK0T58hOLaMQJbcMmAebVuK2ePunTEVEx1clNQ==",
+      "license": "MIT"
+    },
+    "node_modules/pixelmatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/pixelmatch/-/pixelmatch-4.0.2.tgz",
+      "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==",
+      "license": "ISC",
+      "dependencies": {
+        "pngjs": "^3.0.0"
+      },
+      "bin": {
+        "pixelmatch": "bin/pixelmatch"
+      }
+    },
+    "node_modules/pkg-types": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz",
+      "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+      "license": "MIT",
+      "dependencies": {
+        "confbox": "^0.1.8",
+        "mlly": "^1.7.4",
+        "pathe": "^2.0.1"
+      }
+    },
+    "node_modules/pngjs": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-3.4.0.tgz",
+      "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.5.29",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.29.tgz",
+      "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.19",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/postcss-import": {
+      "version": "14.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz",
+      "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==",
+      "license": "MIT",
+      "dependencies": {
+        "postcss-value-parser": "^4.0.0",
+        "read-cache": "^1.0.0",
+        "resolve": "^1.1.7"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.0.0"
+      }
+    },
+    "node_modules/postcss-load-config": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
+      "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
+      "license": "MIT",
+      "dependencies": {
+        "lilconfig": "^2.0.5",
+        "yaml": "^1.10.2"
+      },
+      "engines": {
+        "node": ">= 10"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/postcss/"
+      },
+      "peerDependencies": {
+        "postcss": ">=8.0.9",
+        "ts-node": ">=9.0.0"
+      },
+      "peerDependenciesMeta": {
+        "postcss": {
+          "optional": true
+        },
+        "ts-node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/postcss-modules": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/postcss-modules/-/postcss-modules-4.3.1.tgz",
+      "integrity": "sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==",
+      "license": "MIT",
+      "dependencies": {
+        "generic-names": "^4.0.0",
+        "icss-replace-symbols": "^1.1.0",
+        "lodash.camelcase": "^4.3.0",
+        "postcss-modules-extract-imports": "^3.0.0",
+        "postcss-modules-local-by-default": "^4.0.0",
+        "postcss-modules-scope": "^3.0.0",
+        "postcss-modules-values": "^4.0.0",
+        "string-hash": "^1.1.1"
+      },
+      "peerDependencies": {
+        "postcss": "^8.0.0"
+      }
+    },
+    "node_modules/postcss-modules-extract-imports": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
+      "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
+      "license": "ISC",
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-local-by-default": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
+      "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
+      "license": "MIT",
+      "dependencies": {
+        "icss-utils": "^5.0.0",
+        "postcss-selector-parser": "^7.0.0",
+        "postcss-value-parser": "^4.1.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+      "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+      "license": "MIT",
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-modules-scope": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+      "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
+      "license": "ISC",
+      "dependencies": {
+        "postcss-selector-parser": "^7.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+      "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+      "license": "MIT",
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-modules-values": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+      "license": "ISC",
+      "dependencies": {
+        "icss-utils": "^5.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-selector-parser": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+      "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+      "license": "MIT",
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-value-parser": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+      "license": "MIT"
+    },
+    "node_modules/postcss/node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "license": "ISC"
+    },
+    "node_modules/postcss/node_modules/source-map-js": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.2.tgz",
+      "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
+      "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.8.tgz",
+      "integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "forwarded": "0.2.0",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/express"
+      }
+    },
+    "node_modules/qrcode-reader": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/qrcode-reader/-/qrcode-reader-1.0.4.tgz",
+      "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/qrcode-terminal": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz",
+      "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==",
+      "bin": {
+        "qrcode-terminal": "bin/qrcode-terminal.js"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz",
+      "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/quansync": {
+      "version": "0.2.11",
+      "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz",
+      "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/antfu"
+        },
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/sxzz"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/queue-microtask": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
+      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.2.tgz",
+      "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/read-cache": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.2.tgz",
+      "integrity": "sha512-/peqiBB/n07gQGLsWaHho3WfvUyRscw0gYTsEFMhrIe/nWLkYaf5SbKYjGYqtRV3aPwykJgF2VEMo1ac4bnsGA==",
+      "license": "MIT"
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "license": "MIT",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/regenerate": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.5.0.tgz",
+      "integrity": "sha512-1s+CxXjJ71i7LNVy8nYwg47XV4y6lAnOEhsMtSKq3WpmPfhl9LuKlTqKIn/3yUpE8lBz+W+TT88Bxyhnr0U4yw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regenerate-unicode-properties": {
+      "version": "10.3.0",
+      "resolved": "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.3.0.tgz",
+      "integrity": "sha512-9ns8odR8e9q3otKeHj3DE80jZYKg6zVeZKE+zQmRKXFoVUcuiTGeO6iusDhPRoIQQPVPRvH+SfBhrTud4eczuw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "regenerate": "^1.4.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regexpu-core": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-6.5.3.tgz",
+      "integrity": "sha512-E8VgUoSK+LMQrLboDxavm76MTBGrQhx9RiNuomRmYnZ10Uw12HrI8fkxOOncktb2hBpzIZ9SV/347euQHG5z+g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "regenerate": "^1.5.0",
+        "regenerate-unicode-properties": "^10.3.0",
+        "regjsgen": "^0.8.0",
+        "regjsparser": "^0.13.0",
+        "unicode-match-property-ecmascript": "^2.0.0",
+        "unicode-match-property-value-ecmascript": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/regjsgen": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmmirror.com/regjsgen/-/regjsgen-0.8.0.tgz",
+      "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regjsparser": {
+      "version": "0.13.4",
+      "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.13.4.tgz",
+      "integrity": "sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "jsesc": "~3.1.0"
+      },
+      "bin": {
+        "regjsparser": "bin/parser"
+      }
+    },
+    "node_modules/resolve": {
+      "version": "1.22.8",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz",
+      "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+      "license": "MIT",
+      "dependencies": {
+        "is-core-module": "^2.13.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
+      "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+      "license": "MIT",
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "4.64.5",
+      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.64.5.tgz",
+      "integrity": "sha512-EAP5ZHcz2ijbgCWwPkpI7zh6bfsri2Ez5FtCy2dCp1k62duXzfG7DLGGh7RU2QQXWwavT+u4qpvDF/TWOiiGTw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "1.0.9"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@napi-rs/lzma-linux-x64-gnu": "1.5.1",
+        "@rollup/rollup-android-arm-eabi": "4.64.5",
+        "@rollup/rollup-android-arm64": "4.64.5",
+        "@rollup/rollup-darwin-arm64": "4.64.5",
+        "@rollup/rollup-darwin-x64": "4.64.5",
+        "@rollup/rollup-freebsd-arm64": "4.64.5",
+        "@rollup/rollup-freebsd-x64": "4.64.5",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.64.5",
+        "@rollup/rollup-linux-arm-musleabihf": "4.64.5",
+        "@rollup/rollup-linux-arm64-gnu": "4.64.5",
+        "@rollup/rollup-linux-arm64-musl": "4.64.5",
+        "@rollup/rollup-linux-loong64-gnu": "4.64.5",
+        "@rollup/rollup-linux-loong64-musl": "4.64.5",
+        "@rollup/rollup-linux-ppc64-gnu": "4.64.5",
+        "@rollup/rollup-linux-ppc64-musl": "4.64.5",
+        "@rollup/rollup-linux-riscv64-gnu": "4.64.5",
+        "@rollup/rollup-linux-riscv64-musl": "4.64.5",
+        "@rollup/rollup-linux-s390x-gnu": "4.64.5",
+        "@rollup/rollup-linux-x64-gnu": "4.64.5",
+        "@rollup/rollup-linux-x64-musl": "4.64.5",
+        "@rollup/rollup-openbsd-x64": "4.64.5",
+        "@rollup/rollup-openharmony-arm64": "4.64.5",
+        "@rollup/rollup-win32-arm64-msvc": "4.64.5",
+        "@rollup/rollup-win32-ia32-msvc": "4.64.5",
+        "@rollup/rollup-win32-x64-gnu": "4.64.5",
+        "@rollup/rollup-win32-x64-msvc": "4.64.5",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/run-parallel": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
+      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "queue-microtask": "^1.2.2"
+      }
+    },
+    "node_modules/safe-area-insets": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/safe-area-insets/-/safe-area-insets-1.4.1.tgz",
+      "integrity": "sha512-r/nRWTjFGhhm3w1Z6Kd/jY11srN+lHt2mNl1E/emQGW8ic7n3Avu4noibklfSM+Y34peNphHD/BSZecav0sXYQ==",
+      "license": "ISC"
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/sass": {
+      "version": "1.77.8",
+      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.77.8.tgz",
+      "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "chokidar": ">=3.0.0 <4.0.0",
+        "immutable": "^4.0.0",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "bin": {
+        "sass": "sass.js"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/sax": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.6.1.tgz",
+      "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=11.0.0"
+      }
+    },
+    "node_modules/scule": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
+      "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
+      "license": "MIT"
+    },
+    "node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/send": {
+      "version": "0.19.0",
+      "resolved": "https://registry.npmmirror.com/send/-/send-0.19.0.tgz",
+      "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "2.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/send/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/send/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/serve-static": {
+      "version": "1.16.0",
+      "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.16.0.tgz",
+      "integrity": "sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.18.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/serve-static/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/serve-static/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/serve-static/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/serve-static/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/serve-static/node_modules/send": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz",
+      "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "2.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/side-channel": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.1.tgz",
+      "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+      "dev": true,
+      "license": "MIT",
+      "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"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-list": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.1.tgz",
+      "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
+      "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-weakmap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+      "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3",
+        "side-channel-map": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/string-hash": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/string-hash/-/string-hash-1.1.3.tgz",
+      "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==",
+      "license": "CC0-1.0"
+    },
+    "node_modules/strip-literal": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-3.1.0.tgz",
+      "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==",
+      "license": "MIT",
+      "dependencies": {
+        "js-tokens": "^9.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/strip-literal/node_modules/js-tokens": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz",
+      "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+      "license": "MIT"
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/systemjs": {
+      "version": "6.15.1",
+      "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.15.1.tgz",
+      "integrity": "sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/tapable": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.3.3.tgz",
+      "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/terser": {
+      "version": "5.51.2",
+      "resolved": "https://registry.npmmirror.com/terser/-/terser-5.51.2.tgz",
+      "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==",
+      "devOptional": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.15.0",
+        "commander": "^2.20.0",
+        "source-map-support": "~0.5.20"
+      },
+      "bin": {
+        "terser": "bin/terser"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/timm": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmmirror.com/timm/-/timm-1.7.1.tgz",
+      "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==",
+      "license": "MIT"
+    },
+    "node_modules/tinycolor2": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz",
+      "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
+      "license": "MIT"
+    },
+    "node_modules/to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "license": "MIT",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "5.4.5",
+      "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz",
+      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+      "devOptional": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/ufo": {
+      "version": "1.6.4",
+      "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.4.tgz",
+      "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
+      "license": "MIT"
+    },
+    "node_modules/undici-types": {
+      "version": "6.20.0",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz",
+      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/unicode-canonical-property-names-ecmascript": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+      "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-match-property-ecmascript": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+      "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "unicode-canonical-property-names-ecmascript": "^2.0.0",
+        "unicode-property-aliases-ecmascript": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-match-property-value-ecmascript": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
+      "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-property-aliases-ecmascript": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz",
+      "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unimport": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/unimport/-/unimport-4.1.1.tgz",
+      "integrity": "sha512-j9+fijH6aDd05yv1fXlyt7HSxtOWtGtrZeYTVBsSUg57Iuf+Ps2itIZjeyu7bEQ4k0WOgYhHrdW8m/pJgOpl5g==",
+      "license": "MIT",
+      "dependencies": {
+        "acorn": "^8.14.0",
+        "escape-string-regexp": "^5.0.0",
+        "estree-walker": "^3.0.3",
+        "fast-glob": "^3.3.3",
+        "local-pkg": "^1.0.0",
+        "magic-string": "^0.30.17",
+        "mlly": "^1.7.4",
+        "pathe": "^2.0.2",
+        "picomatch": "^4.0.2",
+        "pkg-types": "^1.3.1",
+        "scule": "^1.3.0",
+        "strip-literal": "^3.0.0",
+        "unplugin": "^2.1.2",
+        "unplugin-utils": "^0.2.3"
+      },
+      "engines": {
+        "node": ">=18.12.0"
+      }
+    },
+    "node_modules/unimport/node_modules/escape-string-regexp": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/unimport/node_modules/estree-walker": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
+      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "^1.0.0"
+      }
+    },
+    "node_modules/unimport/node_modules/magic-string": {
+      "version": "0.30.21",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz",
+      "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.5"
+      }
+    },
+    "node_modules/unimport/node_modules/picomatch": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz",
+      "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/unplugin": {
+      "version": "2.3.11",
+      "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.11.tgz",
+      "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==",
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/remapping": "^2.3.5",
+        "acorn": "^8.15.0",
+        "picomatch": "^4.0.3",
+        "webpack-virtual-modules": "^0.6.2"
+      },
+      "engines": {
+        "node": ">=18.12.0"
+      }
+    },
+    "node_modules/unplugin-utils": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.5.tgz",
+      "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==",
+      "license": "MIT",
+      "dependencies": {
+        "pathe": "^2.0.3",
+        "picomatch": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=18.12.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sxzz"
+      }
+    },
+    "node_modules/unplugin-utils/node_modules/picomatch": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz",
+      "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/unplugin/node_modules/picomatch": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz",
+      "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/unquote": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/unquote/-/unquote-1.1.1.tgz",
+      "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==",
+      "license": "MIT"
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz",
+      "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "escalade": "^3.2.0",
+        "picocolors": "^1.1.1"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/update-browserslist-db/node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "license": "ISC"
+    },
+    "node_modules/utif": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/utif/-/utif-2.0.1.tgz",
+      "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==",
+      "license": "MIT",
+      "dependencies": {
+        "pako": "^1.0.5"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "license": "MIT"
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/vite": {
+      "version": "5.2.8",
+      "resolved": "https://registry.npmmirror.com/vite/-/vite-5.2.8.tgz",
+      "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==",
+      "license": "MIT",
+      "dependencies": {
+        "esbuild": "^0.20.1",
+        "postcss": "^8.4.38",
+        "rollup": "^4.13.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || >=20.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^18.0.0 || >=20.0.0",
+        "less": "*",
+        "lightningcss": "^1.21.0",
+        "sass": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "lightningcss": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue": {
+      "version": "3.4.21",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz",
+      "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/runtime-dom": "3.4.21",
+        "@vue/server-renderer": "3.4.21",
+        "@vue/shared": "3.4.21"
+      },
+      "peerDependencies": {
+        "typescript": "*"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-router": {
+      "version": "4.4.4",
+      "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.4.4.tgz",
+      "integrity": "sha512-3MlnDqwRwZwCQVbtVfpsU+nrNymNjnXSsQtXName5925NVC1+326VVfYH9vSrA0N13teGEo8z5x7gbRnGjCDiQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@vue/devtools-api": "^6.6.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/vue-template-compiler": {
+      "version": "2.7.16",
+      "resolved": "https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz",
+      "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "de-indent": "^1.0.2",
+        "he": "^1.2.0"
+      }
+    },
+    "node_modules/vue-tsc": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.0.6.tgz",
+      "integrity": "sha512-kK50W4XqQL34vHRkxlRWLicrT6+F9xfgCgJ4KSmCHcytKzc1u3c94XXgI+CjmhOSxyw0krpExF7Obo7y4+0dVQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@volar/typescript": "~2.1.2",
+        "@vue/language-core": "2.0.6",
+        "semver": "^7.5.4"
+      },
+      "bin": {
+        "vue-tsc": "bin/vue-tsc.js"
+      },
+      "peerDependencies": {
+        "typescript": "*"
+      }
+    },
+    "node_modules/vue-tsc/node_modules/semver": {
+      "version": "7.8.5",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+      "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/webpack-virtual-modules": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+      "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+      "license": "MIT"
+    },
+    "node_modules/ws": {
+      "version": "8.18.0",
+      "resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.0.tgz",
+      "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/xhr": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmmirror.com/xhr/-/xhr-2.6.0.tgz",
+      "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==",
+      "license": "MIT",
+      "dependencies": {
+        "global": "~4.4.0",
+        "is-function": "^1.0.1",
+        "parse-headers": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "node_modules/xml-parse-from-string": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
+      "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==",
+      "license": "MIT"
+    },
+    "node_modules/xml2js": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.5.0.tgz",
+      "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+      "license": "MIT",
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/xmlhttprequest": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmmirror.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+      "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/xregexp": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/xregexp/-/xregexp-5.1.2.tgz",
+      "integrity": "sha512-6hGgEMCGhqCTFEJbqmWrNIPqfpdirdGWkqshu7fFZddmTSfgv5Sn9D2SaKloR79s5VUiUlpwzg3CM3G6D3VIlw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.9"
+      }
+    },
+    "node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "license": "ISC"
+    },
+    "node_modules/yaml": {
+      "version": "1.10.3",
+      "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.3.tgz",
+      "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">= 6"
+      }
+    }
+  }
+}

+ 34 - 0
package.json

@@ -0,0 +1,34 @@
+{
+  "name": "city-life-line-mobile",
+  "version": "0.1.0",
+  "private": true,
+  "description": "沅陵太常片区城市地下管网管控平台移动端",
+  "scripts": {
+    "dev:h5": "uni",
+    "dev:mp-weixin": "uni -p mp-weixin",
+    "dev:app": "uni -p app",
+    "build:h5": "uni build",
+    "build:mp-weixin": "uni build -p mp-weixin",
+    "build:app": "uni build -p app",
+    "type-check": "vue-tsc --noEmit"
+  },
+  "dependencies": {
+    "@dcloudio/uni-app": "3.0.0-alpha-5030120260930001",
+    "@dcloudio/uni-app-plus": "3.0.0-alpha-5030120260930001",
+    "@dcloudio/uni-components": "3.0.0-alpha-5030120260930001",
+    "@dcloudio/uni-h5": "3.0.0-alpha-5030120260930001",
+    "@dcloudio/uni-mp-weixin": "3.0.0-alpha-5030120260930001",
+    "pinia": "2.1.7",
+    "pinyin-pro": "^3.27.0",
+    "vue": "3.4.21"
+  },
+  "devDependencies": {
+    "@dcloudio/types": "3.4.31",
+    "@dcloudio/vite-plugin-uni": "3.0.0-alpha-5030120260930001",
+    "@types/node": "22.10.2",
+    "sass": "1.77.8",
+    "typescript": "5.4.5",
+    "vite": "5.2.8",
+    "vue-tsc": "2.0.6"
+  }
+}

+ 11 - 0
src/App.vue

@@ -0,0 +1,11 @@
+<script setup lang="ts">
+import { onLaunch } from '@dcloudio/uni-app'
+
+onLaunch(() => {
+  // 第一阶段仅初始化静态应用;鉴权、字典和用户信息将在接口联调阶段接入。
+})
+</script>
+
+<style lang="scss">
+@import './styles/global.scss';
+</style>

Файловите разлики са ограничени, защото са твърде много
+ 157 - 0
src/components/ActionFormDrawer.vue


Файловите разлики са ограничени, защото са твърде много
+ 69 - 0
src/components/AlarmAuditDrawer.vue


+ 21 - 0
src/components/AppHeader.vue

@@ -0,0 +1,21 @@
+<script setup lang="ts">
+import { navigateBack } from '@/utils/navigation'
+
+withDefaults(defineProps<{ title: string; back?: boolean; transparent?: boolean }>(), { back: true, transparent: false })
+</script>
+
+<template>
+  <view class="nav" :class="{ transparent }">
+    <view class="nav-side" @tap="back && navigateBack()"><text v-if="back" class="back">‹</text></view>
+    <text class="nav-title">{{ title }}</text>
+    <view class="nav-side"><slot name="right" /></view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.nav { position: sticky; top: 0; z-index: 20; display: grid; grid-template-columns: 90rpx 1fr 90rpx; align-items: center; height: calc(92rpx + env(safe-area-inset-top)); padding-top: env(safe-area-inset-top); color: #20324a; background: rgba(255,255,255,.97); border-bottom: 1rpx solid #e8edf3; }
+.nav.transparent { color: #fff; background: transparent; border-bottom: 0; }
+.nav-side { display: flex; align-items: center; justify-content: center; min-width: 90rpx; height: 90rpx; }
+.back { transform: translateY(-3rpx); font-size: 64rpx; font-weight: 300; line-height: 1; }
+.nav-title { overflow: hidden; font-size: 34rpx; font-weight: 650; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
+</style>

+ 39 - 0
src/components/BusinessCard.vue

@@ -0,0 +1,39 @@
+<script setup lang="ts">
+import { computed } from 'vue'
+import type { ListItem } from '@/data/mock'
+
+const props = withDefaults(defineProps<{ item: ListItem; idLabel?: string; detailLabel?: string }>(), { detailLabel: '查看详情' })
+defineEmits<{ open: [item: ListItem] }>()
+const splitNumber = computed(() => props.idLabel === '工单编号' || props.idLabel === '预警编号')
+</script>
+
+<template>
+  <view class="business-card card" @tap="$emit('open', item)">
+    <view v-if="splitNumber" class="split-body">
+      <view class="number-row"><view class="number-main"><text>{{ idLabel }}</text><text>{{ item.id }}</text></view><view class="status-group"><text class="status-pill" :class="item.tone">{{ item.status }}</text></view></view>
+      <view class="info-column"><view v-for="field in item.fields" :key="field.label" class="field-row"><text class="label">{{ field.label }}</text><text class="value">{{ field.value }}</text></view></view>
+    </view>
+    <template v-else>
+      <view class="card-head"><view class="title-wrap"><text class="dot"></text><text class="title">{{ item.title }}</text></view><view class="status-group"><text class="status-pill" :class="item.tone">{{ item.status }}</text></view></view>
+      <view class="number"><text>{{ idLabel || '编号' }}</text><text>{{ item.id }}</text></view>
+      <view v-for="field in item.fields" :key="field.label" class="field-row"><text class="label">{{ field.label }}</text><text class="value">{{ field.value }}</text></view>
+    </template>
+    <view class="card-foot"><text v-if="item.secondaryStatus" class="status-pill foot-status" :class="item.secondaryTone">{{ item.secondaryStatus }}</text><text>{{ item.actionLabel || detailLabel }}</text><text class="arrow">›</text></view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.business-card { padding: 25rpx 25rpx 0; margin-bottom: 20rpx; overflow: hidden; }
+.split-body{display:block}.number-row{display:flex;align-items:center;justify-content:space-between;gap:16rpx;padding-bottom:18rpx;margin-bottom:2rpx;border-bottom:2rpx dashed #cdd7e2}.number-main{display:flex;align-items:center;gap:20rpx;min-width:0}.number-main text:first-child{flex-shrink:0;color:#8b98a8;font-size:23rpx}.number-main text:last-child{color:#08264c;font-size:25rpx;font-weight:700;line-height:1.55;word-break:break-all}.status-group{display:flex;flex-shrink:0;align-items:center;justify-content:flex-end;gap:8rpx;flex-wrap:wrap}.info-column{min-width:0}
+.card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16rpx; padding-bottom: 18rpx; border-bottom: 1rpx solid #edf1f5; }
+.title-wrap { display: flex; flex: 1; align-items: center; min-width: 0; }
+.dot { flex-shrink: 0; width: 13rpx; height: 13rpx; margin-right: 14rpx; border-radius: 50%; background: #08264c; box-shadow: 0 0 0 7rpx #e7edf3; }
+.title { overflow: hidden; color: #21344d; font-size: 30rpx; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
+.number, .field-row { display: grid; grid-template-columns: 145rpx 1fr; gap: 12rpx; padding-top: 17rpx; line-height: 1.55; }
+.number { color: #607087; font-size: 25rpx; }
+.label { color: #8b98a8; font-size: 25rpx; }
+.value { color: #43546a; font-size: 25rpx; }
+.card-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8rpx; height: 74rpx; margin-top: 18rpx; color: #08264c; border-top: 1rpx solid #edf1f5; font-size: 25rpx; }
+.foot-status { margin-right: auto; }
+.arrow { transform: translateY(-2rpx); font-size: 40rpx; font-weight: 300; }
+</style>

+ 36 - 0
src/components/BusinessListPage.vue

@@ -0,0 +1,36 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import AppHeader from './AppHeader.vue'
+import SearchBar from './SearchBar.vue'
+import SegmentTabs from './SegmentTabs.vue'
+import BusinessCard from './BusinessCard.vue'
+import type { ListItem } from '@/data/mock'
+import { navigateTo, showStaticToast } from '@/utils/navigation'
+
+const props = withDefaults(defineProps<{ title: string; items: ListItem[]; tabs?: string[]; detailPath: string; placeholder?: string; idLabel?: string; detailLabel?: string }>(), { tabs: () => ['全部'], placeholder: '请输入编号或名称', idLabel: '编号', detailLabel: '查看详情' })
+const keyword = ref('')
+const active = ref(0)
+const filtered = computed(() => props.items.filter(x => !keyword.value || `${x.id}${x.title}${x.status}${x.fields.map(f => f.value).join('')}`.includes(keyword.value)))
+
+function openDetail(item: ListItem) {
+  const separator = props.detailPath.includes('?') ? '&' : '?'
+  navigateTo(`${props.detailPath}${separator}status=${encodeURIComponent(item.status)}`)
+}
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader :title="title" />
+    <SegmentTabs v-if="tabs.length > 1" v-model="active" :items="tabs" />
+    <SearchBar v-model="keyword" :placeholder="placeholder" @search="showStaticToast(keyword ? `已筛选“${keyword}”` : '请输入查询条件')" />
+    <view class="filter-bar"><text>共 {{ filtered.length }} 条</text><text class="filter" @tap="showStaticToast('筛选面板将在接口联调阶段接入')">筛选⌄</text></view>
+    <view class="page-content list-content">
+      <BusinessCard v-for="item in filtered" :key="item.id" :item="item" :id-label="idLabel" :detail-label="detailLabel" @open="openDetail(item)" />
+      <view v-if="!filtered.length" class="empty"><text class="empty-icon">⌕</text><text>暂无匹配数据</text></view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.filter-bar{display:flex;align-items:center;justify-content:space-between;padding:0 26rpx 16rpx;color:#8a97a7;background:#fff;font-size:23rpx}.filter{color:#4f6279}.list-content{padding-top:22rpx}.empty{display:flex;flex-direction:column;align-items:center;padding:120rpx 0;color:#9aa6b4}.empty-icon{margin-bottom:15rpx;font-size:70rpx}
+</style>

+ 28 - 0
src/components/DetailPage.vue

@@ -0,0 +1,28 @@
+<script setup lang="ts">
+import AppHeader from './AppHeader.vue'
+import FieldList from './FieldList.vue'
+import SegmentTabs from './SegmentTabs.vue'
+import { ref } from 'vue'
+import type { Field, Tone } from '@/data/mock'
+import { showStaticToast } from '@/utils/navigation'
+
+withDefaults(defineProps<{ title: string; name: string; number: string; status: string; tone?: Tone; fields: Field[]; actions?: string[]; tabs?: string[] }>(), { tone: '', actions: () => [], tabs: () => [] })
+const active = ref(0)
+</script>
+
+<template>
+  <view class="page detail-page">
+    <AppHeader :title="title" />
+    <view class="detail-banner"><view class="detail-symbol">⌁</view><view class="banner-main"><text class="name">{{ name }}</text><text class="number">{{ number }}</text></view><text class="status-pill" :class="tone">{{ status }}</text></view>
+    <SegmentTabs v-if="tabs.length" v-model="active" :items="tabs" />
+    <view class="page-content">
+      <template v-if="!tabs.length || active === 0"><view class="section-title">基本信息</view><FieldList :fields="fields" /><slot /></template>
+      <view v-else class="timeline card"><view v-for="(item, i) in ['系统创建记录', '管理员接收并审核', '现场人员反馈处置进度']" :key="item" class="timeline-item"><view class="time-dot" :class="{ current: i === 0 }"></view><view><text class="log-title">{{ item }}</text><text class="log-time">2026-09-29 {{ 10 + i }}:25</text><text class="log-detail">静态处理日志示例,真实操作记录将在接口联调后展示。</text></view></view></view>
+      <view v-if="actions.length" class="action-bar"><button v-for="(action, i) in actions" :key="action" :class="i === actions.length - 1 ? 'primary-btn' : 'ghost-btn'" @tap="showStaticToast(`${action}功能将在接口联调阶段启用`)">{{ action }}</button></view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.detail-page{padding-bottom:110rpx}.detail-banner{display:flex;align-items:center;padding:28rpx 26rpx;color:#fff;background:linear-gradient(135deg,#061b34,#174e76)}.detail-symbol{display:flex;align-items:center;justify-content:center;width:82rpx;height:82rpx;margin-right:20rpx;border-radius:20rpx;background:rgba(255,255,255,.17);font-size:48rpx}.banner-main{display:flex;flex:1;flex-direction:column;min-width:0}.name{overflow:hidden;font-size:31rpx;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.number{margin-top:10rpx;color:rgba(255,255,255,.74);font-size:22rpx}.detail-banner .status-pill{background:rgba(255,255,255,.9)}.timeline{padding:12rpx 25rpx}.timeline-item{position:relative;display:grid;grid-template-columns:35rpx 1fr;gap:14rpx;padding:25rpx 0}.timeline-item:not(:last-child)::after{content:'';position:absolute;top:49rpx;bottom:-22rpx;left:11rpx;width:2rpx;background:#dfe6ee}.time-dot{z-index:1;width:23rpx;height:23rpx;margin-top:4rpx;border:5rpx solid #fff;border-radius:50%;background:#aab6c3;box-shadow:0 0 0 2rpx #aab6c3}.time-dot.current{background:#08264c;box-shadow:0 0 0 2rpx #08264c}.log-title,.log-time,.log-detail{display:block}.log-title{color:#34485f;font-weight:600}.log-time{margin-top:8rpx;color:#98a3b1;font-size:22rpx}.log-detail{margin-top:10rpx;color:#718096;font-size:24rpx;line-height:1.55}.action-bar{position:fixed;z-index:30;right:0;bottom:0;left:0;display:flex;gap:18rpx;padding:16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));background:#fff;box-shadow:0 -5rpx 20rpx rgba(38,59,83,.08)}.action-bar button{flex:1;margin:0}
+</style>

+ 21 - 0
src/components/FieldList.vue

@@ -0,0 +1,21 @@
+<script setup lang="ts">
+import type { Field } from '@/data/mock'
+
+defineProps<{ fields: Field[] }>()
+</script>
+
+<template>
+  <view class="field-list card">
+    <view v-for="field in fields" :key="field.label" class="field-item">
+      <text class="label">{{ field.label }}</text><text class="value">{{ field.value }}</text>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.field-list { padding: 5rpx 25rpx; }
+.field-item { display: grid; grid-template-columns: 180rpx 1fr; gap: 18rpx; padding: 22rpx 0; border-bottom: 1rpx solid #edf1f5; line-height: 1.55; }
+.field-item:last-child { border-bottom: 0; }
+.label { color: #8794a5; }
+.value { color: #30445d; text-align: right; word-break: break-all; }
+</style>

+ 130 - 0
src/components/FormField.vue

@@ -0,0 +1,130 @@
+<script setup lang="ts">
+import { computed, ref, watch } from 'vue'
+
+const props = withDefaults(defineProps<{ label: string; modelValue?: string; placeholder?: string; required?: boolean; type?: 'input' | 'textarea' | 'select' | 'datetime'; password?: boolean; futureOnly?: boolean; pastOnly?: boolean }>(), { modelValue: '', placeholder: '请输入', required: false, type: 'input', password: false, futureOnly: false, pastOnly: false })
+const emit = defineEmits<{ 'update:modelValue': [value: string]; select: [] }>()
+
+const pad = (value: number) => String(value).padStart(2, '0')
+const now = new Date()
+const minimum = new Date(now)
+minimum.setSeconds(0, 0)
+minimum.setMinutes(minimum.getMinutes() + 1)
+const currentDate = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
+const currentTime = `${pad(now.getHours())}:${pad(now.getMinutes())}`
+const minimumDate = `${minimum.getFullYear()}-${pad(minimum.getMonth() + 1)}-${pad(minimum.getDate())}`
+const minimumTime = `${pad(minimum.getHours())}:${pad(minimum.getMinutes())}`
+const defaultDate = computed(() => props.futureOnly ? minimumDate : currentDate)
+const defaultTime = computed(() => props.futureOnly ? minimumTime : currentTime)
+const dateValue = computed(() => String(props.modelValue || '').match(/^(\d{4}-\d{2}-\d{2})/)?.[1] || '')
+const timeValue = computed(() => String(props.modelValue || '').match(/[ T](\d{2}:\d{2})/)?.[1] || '')
+const dateIndexes = ref([0, 0, 0])
+const timeIndexes = ref([0, 0])
+const numberRange = (start: number, end: number) => Array.from({ length: end - start + 1 }, (_, index) => pad(start + index))
+const firstYear = computed(() => props.futureOnly ? minimum.getFullYear() : 2000)
+const lastYear = computed(() => props.pastOnly ? now.getFullYear() : 2100)
+const dateYears = computed(() => Array.from({ length: Math.max(1, lastYear.value - firstYear.value + 1) }, (_, index) => String(firstYear.value + index)))
+const selectedYear = computed(() => Number(dateYears.value[dateIndexes.value[0]] || dateYears.value[0]))
+const lastMonth = computed(() => props.pastOnly && selectedYear.value === now.getFullYear() ? now.getMonth() + 1 : 12)
+const dateMonths = computed(() => numberRange(props.futureOnly && selectedYear.value === minimum.getFullYear() ? minimum.getMonth() + 1 : 1, lastMonth.value))
+const selectedMonth = computed(() => Number(dateMonths.value[dateIndexes.value[1]] || dateMonths.value[0]))
+const daysInMonth = computed(() => new Date(selectedYear.value, selectedMonth.value, 0).getDate())
+const firstDay = computed(() => props.futureOnly && selectedYear.value === minimum.getFullYear() && selectedMonth.value === minimum.getMonth() + 1 ? minimum.getDate() : 1)
+const lastDay = computed(() => props.pastOnly && selectedYear.value === now.getFullYear() && selectedMonth.value === now.getMonth() + 1 ? now.getDate() : daysInMonth.value)
+const dateDays = computed(() => numberRange(firstDay.value, lastDay.value))
+const dateRanges = computed(() => [dateYears.value, dateMonths.value, dateDays.value])
+const selectedDate = computed(() => `${dateYears.value[dateIndexes.value[0]]}-${dateMonths.value[dateIndexes.value[1]]}-${dateDays.value[dateIndexes.value[2]]}`)
+const activeDate = computed(() => dateValue.value || defaultDate.value)
+const firstHour = computed(() => props.futureOnly && activeDate.value === minimumDate ? minimum.getHours() : 0)
+const firstMinute = computed(() => props.futureOnly && activeDate.value === minimumDate && selectedHour.value === minimum.getHours() ? minimum.getMinutes() : 0)
+const lastHour = computed(() => props.pastOnly && activeDate.value === currentDate ? now.getHours() : 23)
+const timeHours = computed(() => numberRange(firstHour.value, lastHour.value))
+const selectedHour = computed(() => Number(timeHours.value[timeIndexes.value[0]] || timeHours.value[0]))
+const lastMinute = computed(() => props.pastOnly && activeDate.value === currentDate && selectedHour.value === now.getHours() ? now.getMinutes() : 59)
+const timeMinutes = computed(() => numberRange(firstMinute.value, lastMinute.value))
+const timeRanges = computed(() => [timeHours.value, timeMinutes.value])
+
+watch(() => props.modelValue, syncPickerIndexes, { immediate: true })
+
+function syncPickerIndexes(value?: string) {
+  const matched = String(value || '').match(/^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})/)
+  if (!matched) { dateIndexes.value = [0, 0, 0]; timeIndexes.value = [0, 0]; return }
+  const yearIndex = dateYears.value.indexOf(matched[1])
+  dateIndexes.value[0] = Math.max(0, yearIndex)
+  dateIndexes.value[1] = Math.max(0, dateMonths.value.indexOf(matched[2]))
+  dateIndexes.value[2] = Math.max(0, dateDays.value.indexOf(matched[3]))
+  timeIndexes.value[0] = Math.max(0, timeHours.value.indexOf(matched[4]))
+  timeIndexes.value[1] = Math.max(0, timeMinutes.value.indexOf(matched[5]))
+  dateIndexes.value = [...dateIndexes.value]
+  timeIndexes.value = [...timeIndexes.value]
+}
+
+function emitDateTime(date: string, time: string) {
+  emit('update:modelValue', `${date} ${time}:00`)
+}
+
+function onDateColumnChange(event: Event) {
+  const { column, value } = (event as CustomEvent<{ column: number; value: number }>).detail
+  dateIndexes.value[column] = value
+  if (column === 0) { dateIndexes.value[1] = 0; dateIndexes.value[2] = 0 }
+  if (column === 1) dateIndexes.value[2] = 0
+  dateIndexes.value = [...dateIndexes.value]
+}
+
+function onDateChange(event: Event) {
+  dateIndexes.value = [...(event as CustomEvent<{ value: number[] }>).detail.value]
+  const date = selectedDate.value
+  const earliestTime = props.futureOnly && date === minimumDate ? minimumTime : '00:00'
+  let time = timeValue.value || defaultTime.value
+  if (time < earliestTime) time = earliestTime
+  if (props.pastOnly && date === currentDate && time > currentTime) time = currentTime
+  emitDateTime(date, time)
+}
+
+function onTimeColumnChange(event: Event) {
+  const { column, value } = (event as CustomEvent<{ column: number; value: number }>).detail
+  timeIndexes.value[column] = value
+  if (column === 0) timeIndexes.value[1] = 0
+  timeIndexes.value = [...timeIndexes.value]
+}
+
+function onTimeChange(event: Event) {
+  timeIndexes.value = [...(event as CustomEvent<{ value: number[] }>).detail.value]
+  const time = `${timeHours.value[timeIndexes.value[0]]}:${timeMinutes.value[timeIndexes.value[1]]}`
+  emitDateTime(dateValue.value || defaultDate.value, time)
+}
+
+function onInput(event: Event) {
+  emit('update:modelValue', (event as CustomEvent<{ value: string }>).detail.value)
+}
+</script>
+
+<template>
+  <view class="form-field">
+    <view class="label"><text v-if="required" class="required">*</text>{{ label }}</view>
+    <textarea v-if="type === 'textarea'" :value="modelValue" :placeholder="placeholder" maxlength="500" @input="onInput" />
+    <view v-else-if="type === 'select'" class="select" @tap="$emit('select')"><text :class="{ placeholder: !modelValue }">{{ modelValue || placeholder }}</text><text>⌄</text></view>
+    <view v-else-if="type === 'datetime'" class="date-time-row">
+      <picker class="date-time-picker" mode="multiSelector" :range="dateRanges" :value="dateIndexes" @change="onDateChange" @columnchange="onDateColumnChange">
+        <view class="select"><text :class="{ placeholder: !dateValue }">{{ dateValue || '选择日期' }}</text><text>⌄</text></view>
+      </picker>
+      <picker class="date-time-picker" mode="multiSelector" :range="timeRanges" :value="timeIndexes" @change="onTimeChange" @columnchange="onTimeColumnChange">
+        <view class="select"><text :class="{ placeholder: !timeValue }">{{ timeValue || '选择时间' }}</text><text>⌄</text></view>
+      </picker>
+    </view>
+    <input v-else :value="modelValue" :placeholder="placeholder" :password="password" @input="onInput" />
+  </view>
+</template>
+
+<style scoped lang="scss">
+.form-field { padding: 22rpx 0; border-bottom: 1rpx solid #edf1f5; }
+.label { margin-bottom: 16rpx; color: #34485f; font-size: 27rpx; }
+.required { margin-right: 6rpx; color: #e34d59; }
+input, .select, textarea { width: 100%; border: 1rpx solid #dce4ed; border-radius: 12rpx; background: #f8fafc; font-size: 27rpx; }
+input, .select { height: 78rpx; padding: 0 20rpx; }
+.date-time-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12rpx; }
+.date-time-picker { display: block; min-width: 0; }
+.date-time-picker .select { box-sizing: border-box; }
+.select { display: flex; align-items: center; justify-content: space-between; }
+textarea { height: 190rpx; padding: 20rpx; line-height: 1.6; }
+.placeholder { color: #a4afbd; }
+</style>

+ 79 - 0
src/components/InspectCompleteDrawer.vue

@@ -0,0 +1,79 @@
+<script setup lang="ts">
+import { ref, watch } from 'vue'
+import FormField from './FormField.vue'
+import UploadPanel from './UploadPanel.vue'
+import { completeMobileInspectTask, uploadInspectTaskPhoto } from '@/services/inspect-tasks'
+
+const props = defineProps<{ modelValue: boolean; taskId: number }>()
+const emit = defineEmits<{ 'update:modelValue': [value: boolean]; completed: [] }>()
+const time = ref('')
+const photos = ref<string[]>([])
+const issue = ref('')
+const process = ref('')
+const submitting = ref(false)
+
+watch(() => props.modelValue, value => { if (value) reset() })
+
+function nowText() {
+  const now = new Date()
+  const pad = (value: number) => String(value).padStart(2, '0')
+  return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:00`
+}
+function reset() {
+  time.value = nowText()
+  photos.value = []
+  issue.value = ''
+  process.value = ''
+}
+function close() {
+  if (!submitting.value) emit('update:modelValue', false)
+}
+async function submit() {
+  if (submitting.value || !props.taskId) return
+  if (!time.value) return showError('请选择实际巡检时间')
+  const timestamp = Date.parse(time.value.replace(' ', 'T'))
+  if (!Number.isFinite(timestamp) || timestamp > Date.now()) return showError('实际巡检时间不能晚于当前时间')
+  if (!photos.value.length) return showError('请上传现场照片')
+  submitting.value = true
+  uni.showLoading({ title: '上传并提交...' })
+  try {
+    const paths = await Promise.all(photos.value.map(uploadInspectTaskPhoto))
+    await completeMobileInspectTask({
+      inspectTaskId: props.taskId,
+      realTime: time.value,
+      problem: issue.value.trim() || undefined,
+      process: process.value.trim() || undefined,
+      photoUrl: paths.join(','),
+    })
+    emit('update:modelValue', false)
+    emit('completed')
+    uni.showToast({ title: '完成巡检成功', icon: 'success' })
+  } catch (error) {
+    showError(error instanceof Error ? error.message : '完成巡检失败')
+  } finally {
+    uni.hideLoading()
+    submitting.value = false
+  }
+}
+function showError(title: string) { uni.showToast({ title, icon: 'none' }) }
+</script>
+
+<template>
+  <view v-if="modelValue" class="drawer-root">
+    <view class="mask" @tap="close"></view>
+    <view class="drawer">
+      <view class="drawer-head"><text>完成巡检</text><text class="close" @tap="close">×</text></view>
+      <scroll-view class="drawer-body" scroll-y>
+        <FormField v-model="time" label="实际巡检时间" type="datetime" past-only required placeholder="请选择实际巡检时间" />
+        <view class="upload-field"><text class="field-label"><text class="required-mark">*</text>现场照片</text><UploadPanel v-model="photos" :max-size-mb="10" /><text class="upload-tip">支持 png / jpg / jpeg,单个文件不超过 10MB</text></view>
+        <FormField v-model="issue" label="巡检发现问题" type="textarea" placeholder="请输入巡检发现问题" />
+        <FormField v-model="process" label="问题处理过程" type="textarea" placeholder="请输入问题处理过程" />
+      </scroll-view>
+      <view class="drawer-actions"><button class="cancel" :disabled="submitting" @tap="close">取消</button><button class="submit" :disabled="submitting" @tap="submit">{{ submitting ? '正在提交...' : '确认提交' }}</button></view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.drawer-root{position:fixed;inset:0;z-index:100}.mask{position:absolute;inset:0;background:rgba(5,18,35,.55);animation:mask-in .24s ease-out both}.drawer{position:absolute;right:0;bottom:0;left:0;overflow:hidden;border-radius:32rpx 32rpx 0 0;background:#fff;box-shadow:0 -12rpx 40rpx rgba(4,20,38,.2);animation:drawer-in .28s cubic-bezier(.22,.78,.28,1) both}.drawer-head{display:flex;align-items:center;justify-content:space-between;height:96rpx;padding:0 30rpx;color:#122b48;border-bottom:1rpx solid #edf1f5;font-size:31rpx;font-weight:700}.close{display:flex;align-items:center;justify-content:center;width:58rpx;height:58rpx;color:#7f8c9b;border-radius:50%;background:#f2f5f8;font-size:42rpx;font-weight:300}.drawer-body{max-height:64vh;padding:5rpx 30rpx 25rpx}.upload-field{padding:23rpx 0;border-bottom:1rpx solid #edf1f5}.field-label{display:block;margin-bottom:16rpx;color:#34485f;font-size:27rpx}.required-mark{margin-right:6rpx;color:#e34d59}.upload-tip{display:block;margin-top:14rpx;color:#97a3b1;font-size:21rpx}.drawer-actions{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;padding:18rpx 26rpx calc(18rpx + env(safe-area-inset-bottom));border-top:1rpx solid #edf1f5;background:#fff}.drawer-actions button{height:80rpx;margin:0;border-radius:999rpx;font-size:27rpx;line-height:80rpx}.cancel{color:#43566d;border:1rpx solid #d7e0e9;background:#fff}.submit{color:#fff;background:#08264c}.drawer-actions button[disabled]{opacity:.65}@keyframes drawer-in{from{transform:translateY(105%)}to{transform:translateY(0)}}@keyframes mask-in{from{opacity:0}to{opacity:1}}
+</style>

+ 109 - 0
src/components/PhotoPreview.vue

@@ -0,0 +1,109 @@
+<script setup lang="ts">
+import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
+
+const visible = ref(false)
+const images = ref<string[]>([])
+const current = ref(0)
+const scale = ref(1)
+
+function open(url: string, urls: string[]) {
+  const group = urls.filter(Boolean)
+  if (!group.length) return
+  const index = Math.max(0, group.indexOf(url))
+  // #ifndef H5
+  uni.previewImage({ current: index, urls: group })
+  return
+  // #endif
+  // #ifdef H5
+  images.value = group
+  current.value = index
+  scale.value = 1
+  visible.value = true
+  // #endif
+}
+
+function close() { visible.value = false }
+function move(offset: number) {
+  const index = current.value + offset
+  if (index >= 0 && index < images.value.length) {
+    scale.value = 1
+    current.value = index
+  }
+}
+function change(event: { detail: { current: number } }) {
+  current.value = event.detail.current
+  scale.value = 1
+}
+function updateScale(event: { detail: { scale: number } }) { scale.value = event.detail.scale }
+function stopWhenZoomed(event: Event) {
+  if (scale.value > 1) event.stopPropagation()
+}
+
+// #ifdef H5
+let previousOverflow = ''
+watch(visible, value => {
+  if (value) {
+    previousOverflow = document.body.style.overflow
+    document.body.style.overflow = 'hidden'
+  } else {
+    document.body.style.overflow = previousOverflow
+  }
+}, { flush: 'sync' })
+function onKeydown(event: KeyboardEvent) {
+  if (!visible.value) return
+  if (event.key === 'Escape') close()
+  else if (event.key === 'ArrowLeft') move(-1)
+  else if (event.key === 'ArrowRight') move(1)
+  else return
+  event.preventDefault()
+}
+onMounted(() => document.addEventListener('keydown', onKeydown))
+onBeforeUnmount(() => {
+  document.removeEventListener('keydown', onKeydown)
+  close()
+})
+// #endif
+
+defineExpose({ open })
+</script>
+
+<template>
+  <!-- #ifdef H5 -->
+  <Teleport to="body">
+    <view v-if="visible" class="photo-preview" role="dialog" aria-modal="true" aria-label="照片预览" @touchmove.stop.prevent>
+      <swiper class="photo-swiper" :current="current" :duration="200" @change="change">
+        <swiper-item v-for="(url, index) in images" :key="`${index}-${url}`">
+          <movable-area class="photo-area" @touchstart="stopWhenZoomed" @touchmove="stopWhenZoomed" @touchend="stopWhenZoomed">
+            <movable-view class="photo-view" :direction="scale > 1 ? 'all' : 'none'" :scale="true" :scale-min="1" :scale-max="4" :scale-value="index === current ? scale : 1" @scale="updateScale">
+              <image class="photo-image" :src="url" mode="aspectFit" />
+            </movable-view>
+          </movable-area>
+        </swiper-item>
+      </swiper>
+      <view class="preview-toolbar">
+        <text class="photo-count">{{ current + 1 }} / {{ images.length }}</text>
+        <button class="preview-close" aria-label="关闭照片预览" @tap.stop="close">×</button>
+      </view>
+      <view v-if="images.length > 1" class="preview-navigation">
+        <button class="preview-prev" :disabled="current === 0" @tap.stop="move(-1)">‹ 上一张</button>
+        <text>左右滑动切换</text>
+        <button class="preview-next" :disabled="current === images.length - 1" @tap.stop="move(1)">下一张 ›</button>
+      </view>
+    </view>
+  </Teleport>
+  <!-- #endif -->
+</template>
+
+<style scoped lang="scss">
+.photo-preview{position:fixed;inset:0;z-index:10000;background:#101318;color:#fff;overscroll-behavior:contain}
+.photo-swiper{position:absolute;top:calc(100rpx + env(safe-area-inset-top));right:0;bottom:calc(130rpx + env(safe-area-inset-bottom));left:0;height:auto}
+.photo-area,.photo-view,.photo-image{width:100%;height:100%}
+.preview-toolbar{position:absolute;top:0;right:0;left:0;display:flex;align-items:center;justify-content:space-between;padding:calc(16rpx + env(safe-area-inset-top)) 28rpx 16rpx}
+.photo-count{font-size:28rpx;font-variant-numeric:tabular-nums}
+.preview-close{display:flex;align-items:center;justify-content:center;width:68rpx;height:68rpx;margin:0;padding:0;color:#fff;border:0;border-radius:50%;background:rgba(255,255,255,.12);font-size:48rpx;line-height:1}
+.preview-close::after,.preview-navigation button::after{border:0}
+.preview-navigation{position:absolute;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:space-between;gap:14rpx;padding:20rpx 24rpx calc(24rpx + env(safe-area-inset-bottom))}
+.preview-navigation button{flex-shrink:0;display:flex;align-items:center;justify-content:center;height:72rpx;margin:0;padding:0 24rpx;color:#fff;border:1rpx solid rgba(255,255,255,.25);border-radius:999rpx;background:rgba(255,255,255,.1);font-size:26rpx;line-height:1}
+.preview-navigation button[disabled]{color:rgba(255,255,255,.3);border-color:rgba(255,255,255,.08);background:transparent}
+.preview-navigation text{color:#aeb7c4;font-size:22rpx}
+</style>

+ 34 - 0
src/components/SearchBar.vue

@@ -0,0 +1,34 @@
+<script setup lang="ts">
+withDefaults(defineProps<{ modelValue: string; placeholder?: string; attached?: boolean }>(), { placeholder: '请输入关键词搜索', attached: false })
+const emit = defineEmits<{ 'update:modelValue': [value: string]; search: [] }>()
+
+function onInput(event: Event) {
+  emit('update:modelValue', (event as CustomEvent<{ value: string }>).detail.value)
+}
+</script>
+
+<template>
+  <view class="search-wrap" :class="{ attached }">
+    <slot name="prefix" />
+    <view class="search-controls">
+      <view class="search-box">
+        <text v-if="!attached" class="search-icon">⌕</text>
+        <input :value="modelValue" :placeholder="placeholder" confirm-type="search" @input="onInput" @confirm="$emit('search')" />
+      </view>
+      <button class="search-btn" @tap="$emit('search')">查询</button>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.search-wrap { display: flex; gap: 16rpx; padding: 20rpx 24rpx; background: #fff; }
+.search-controls { display: flex; flex: 1; min-width: 0; gap: 16rpx; }
+.search-box { display: flex; flex: 1; min-width: 0; align-items: center; height: 70rpx; padding: 0 22rpx; border-radius: 12rpx; background: #f2f5f8; }
+.search-icon { margin-right: 12rpx; color: #8c99aa; font-size: 34rpx; }
+input { flex: 1; min-width: 0; height: 70rpx; font-size: 26rpx; }
+.search-btn { flex-shrink: 0; width: 118rpx; height: 70rpx; margin: 0; padding: 0; color: #fff; border-radius: 999rpx; background: #08264c; font-size: 26rpx; line-height: 70rpx; white-space: nowrap; }
+.attached .search-controls { gap: 0; }
+.attached .search-box { height: 72rpx; padding: 0 17rpx; border: 1rpx solid #dbe4ea; border-radius: 10rpx 0 0 10rpx; background: #f8fbfd; }
+.attached input { height: 70rpx; font-size: 24rpx; }
+.attached .search-btn { width: 94rpx; height: 72rpx; border-radius: 0; font-size: 24rpx; line-height: 72rpx; }
+</style>

+ 22 - 0
src/components/SegmentTabs.vue

@@ -0,0 +1,22 @@
+<script setup lang="ts">
+withDefaults(defineProps<{ items: string[]; modelValue: number; actionLabel?: string }>(), { actionLabel: '' })
+defineEmits<{ 'update:modelValue': [value: number]; action: [] }>()
+</script>
+
+<template>
+  <scroll-view class="tabs" scroll-x :show-scrollbar="false">
+    <view class="tabs-inner">
+      <view v-for="(item, index) in items" :key="item" class="tab" :class="{ active: modelValue === index }" @tap="$emit('update:modelValue', index)">{{ item }}</view>
+      <view v-if="actionLabel" class="tabs-action" @tap.stop="$emit('action')">{{ actionLabel }} ›</view>
+    </view>
+  </scroll-view>
+</template>
+
+<style scoped lang="scss">
+.tabs { width: 100%; background: #fff; white-space: nowrap; border-bottom: 1rpx solid #e8edf2; }
+.tabs-inner { display: flex; min-width: 100%; height: 86rpx; }
+.tab { position: relative; display: flex; flex: 1 0 auto; align-items: center; justify-content: center; min-width: 150rpx; padding: 0 25rpx; color: #718096; font-size: 27rpx; }
+.tab.active { color: #08264c; font-weight: 650; }
+.tab.active::after { content: ''; position: absolute; bottom: 0; left: 50%; width: 44rpx; height: 5rpx; transform: translateX(-50%); border-radius: 5rpx; background: #08264c; }
+.tabs-action { display: flex; flex: 0 0 auto; align-items: center; padding: 0 26rpx 0 18rpx; color: #8290a1; font-size: 23rpx; }
+</style>

+ 47 - 0
src/components/UploadPanel.vue

@@ -0,0 +1,47 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import PhotoPreview from './PhotoPreview.vue'
+
+const props = withDefaults(defineProps<{ modelValue?: string[]; maxCount?: number; maxSizeMb?: number }>(), { modelValue: () => [], maxCount: 3, maxSizeMb: 10 })
+const emit = defineEmits<{ 'update:modelValue': [value: string[]] }>()
+const photoPreview = ref<InstanceType<typeof PhotoPreview>>()
+
+function choose() {
+  uni.chooseImage({ count: props.maxCount - props.modelValue.length, sizeType: ['original'], success: (res) => {
+    const paths = Array.isArray(res.tempFilePaths) ? res.tempFilePaths : [res.tempFilePaths]
+    const files = Array.isArray(res.tempFiles) ? res.tempFiles : [res.tempFiles]
+    const accepted: string[] = []
+    let rejected = false
+    paths.slice(0, props.maxCount - props.modelValue.length).forEach((path, index) => {
+      const size = Number((files[index] as { size?: number } | undefined)?.size)
+      if (Number.isFinite(size) && size > props.maxSizeMb * 1024 * 1024) {
+        rejected = true
+        return
+      }
+      accepted.push(path)
+    })
+    if (rejected) uni.showToast({ title: `请选择不超过${props.maxSizeMb}MB的图片`, icon: 'none' })
+    if (accepted.length) emit('update:modelValue', [...props.modelValue, ...accepted].slice(0, props.maxCount))
+  } })
+}
+
+function remove(index: number) {
+  emit('update:modelValue', props.modelValue.filter((_, itemIndex) => itemIndex !== index))
+}
+</script>
+
+<template>
+  <view class="upload-row">
+    <view v-for="(src,index) in modelValue" :key="src" class="preview-wrap"><image class="preview" :src="src" mode="aspectFill" @tap="photoPreview?.open(src, modelValue)" /><text class="remove" @tap.stop="remove(index)">×</text></view>
+    <view v-if="modelValue.length < maxCount" class="upload" @tap="choose"><text class="plus">+</text><text>上传照片</text></view>
+  </view>
+  <PhotoPreview ref="photoPreview" />
+</template>
+
+<style scoped lang="scss">
+.upload-row { display: flex; flex-wrap: wrap; gap: 16rpx; }
+.upload, .preview, .preview-wrap { width: 150rpx; height: 150rpx; border-radius: 12rpx; }
+.preview-wrap{position:relative}.remove{position:absolute;right:-8rpx;top:-8rpx;display:flex;align-items:center;justify-content:center;width:36rpx;height:36rpx;color:#fff;border-radius:50%;background:#e05258;font-size:28rpx}
+.upload { display: flex; flex-direction: column; align-items: center; justify-content: center; color: #8d9aaa; border: 2rpx dashed #cbd6e2; background: #f8fafc; font-size: 23rpx; }
+.plus { margin-bottom: 4rpx; color: #9ca9b8; font-size: 58rpx; font-weight: 200; line-height: 1; }
+</style>

+ 68 - 0
src/data/mock.ts

@@ -0,0 +1,68 @@
+export type Tone = 'red' | 'orange' | 'green' | 'gray' | 'purple' | ''
+
+export interface Field { label: string; value: string }
+export interface ListItem { id: string; title: string; status: string; tone?: Tone; secondaryStatus?: string; secondaryTone?: Tone; fields: Field[]; actionLabel?: string }
+
+export const workOrders: ListItem[] = [
+  { id: 'GD202609291256557016', title: '井盖异常开启告警', status: '待派单', tone: 'orange', fields: [
+    { label: '工单描述', value: '长江路07号智能窨井盖检测到异常开启告警,疑似外力破坏或非法开启,需立即派单处置。' },
+    { label: '设备信息', value: '21119740(测试环境监测设备01)' },
+    { label: '安装位置', value: '湖南省怀化市沅陵县沅陵镇辰州东街35号' },
+  ]},
+  { id: 'GD202609281019350328', title: '排水井液位持续超标', status: '待接单', fields: [
+    { label: '工单描述', value: '建设路03号排水井液位持续超标,已超过警戒值,需现场人员到场处置。' },
+    { label: '设备信息', value: '860147865467927(井盖监测设备)' },
+    { label: '安装位置', value: '沅陵县建设路03号排水井' },
+  ]},
+  { id: 'GD202609271455120915', title: '设备低电量告警', status: '处理中', tone: 'purple', fields: [
+    { label: '工单描述', value: '人民中路多台监测设备电池电量低于20%,巡检人员正在现场更换电池。' },
+    { label: '设备信息', value: 'TEST-CBYL5432168(压力计)' },
+    { label: '安装位置', value: '沅陵县人民中路56号' },
+  ]},
+  { id: 'GD202609260842136623', title: '通信中断恢复', status: '待验收', tone: 'green', fields: [
+    { label: '工单描述', value: '公园路02号供水流量监测点通信中断,现场已完成处置并恢复,等待调度验收。' },
+    { label: '设备信息', value: 'TEST-TQJLJ000215(流量计)' },
+    { label: '安装位置', value: '沅陵县公园路02号' },
+  ]},
+]
+
+export const warnings: ListItem[] = [
+  { id: 'YJ202609290001', title: '燃气浓度波动异常', status: '已接收', tone: 'orange', fields: [
+    { label: '预警级别', value: '黄色预警(二级)' }, { label: '预警描述', value: '辰州中街燃气阀井甲烷浓度波动异常,超过安全预警阈值。' }, { label: '预警位置', value: '沅陵县辰州中街18号' },
+  ]},
+  { id: 'YJ202609280012', title: '悬浮物浓度偏高', status: '处理中', tone: 'purple', fields: [
+    { label: '预警级别', value: '蓝色预警(三级)' }, { label: '预警描述', value: '五强溪路排水管网悬浮物浓度持续偏高,疑似上游施工泥浆入网。' }, { label: '预警位置', value: '沅陵县五强溪路56号' },
+  ]},
+  { id: 'YJ202609260008', title: '供水电导率轻微升高', status: '已处置', tone: 'green', fields: [
+    { label: '预警级别', value: '绿色预警(四级)' }, { label: '预警描述', value: '经排查为季节性水质波动,现已完成处置。' }, { label: '预警位置', value: '苦藤铺社区2栋' },
+  ]},
+  { id: 'YJ202609250003', title: '隧道积水水位上涨', status: '已解除', tone: 'gray', fields: [
+    { label: '预警级别', value: '红色预警(一级)' }, { label: '预警描述', value: '强降雨后水位已回落至安全范围,预警解除。' }, { label: '预警位置', value: '沅陵大道下穿隧道' },
+  ]},
+]
+
+export const devices: ListItem[] = [
+  { id: '21111747', title: '测试环境监测设备01', status: '离线', tone: 'gray', fields: [{ label: '设备类型', value: '环境监测' }, { label: '报警状态', value: '报警' }, { label: '安装位置', value: '辰州东街35号' }] },
+  { id: '860147865467927', title: '测试井盖设备01', status: '离线', tone: 'gray', fields: [{ label: '设备类型', value: '井盖监测' }, { label: '报警状态', value: '正常' }, { label: '安装位置', value: '长江路07号' }] },
+  { id: 'TEST-CNXHFS0000001', title: '测试消火栓', status: '离线', tone: 'gray', fields: [{ label: '设备类型', value: '消火栓' }, { label: '报警状态', value: '正常' }, { label: '安装位置', value: '建设路消防站' }] },
+  { id: 'TEST-TQJLJ000215', title: '测试流量计', status: '在线', tone: 'green', fields: [{ label: '设备类型', value: '流量计' }, { label: '报警状态', value: '正常' }, { label: '安装位置', value: '公园路02号' }] },
+]
+
+export const events: ListItem[] = [
+  { id: 'SJ20260929001', title: '排水管网检查井冒溢', status: '核实中', tone: 'orange', fields: [{ label: '事件等级', value: '较大' }, { label: '来源', value: '呼叫中心' }, { label: '发生地点', value: '徐汇区·漕溪北路' }, { label: '事件描述', value: '检查井发生冒溢,污水漫溢至人行步道,需现场排查处置。' }] },
+  { id: 'SJ20260928006', title: '供水管网爆管', status: '核实中', tone: 'red', fields: [{ label: '事件等级', value: '紧急' }, { label: '来源', value: '巡查上报' }, { label: '发生地点', value: '黄浦区·中山东路' }, { label: '事件描述', value: '路面大量积水,影响周边居民用水及交通。' }] },
+  { id: 'SJ20260927008', title: '雨水管网堵塞', status: '处置中', tone: 'purple', fields: [{ label: '事件等级', value: '一般' }, { label: '来源', value: '呼叫中心' }, { label: '发生地点', value: '静安区·南京西路' }, { label: '事件描述', value: '强降雨后路面积水严重,需排涝处置。' }] },
+]
+
+export const plans: ListItem[] = [
+  { id: 'YA2026001', title: '供水管网爆管专项预案', status: 'Ⅰ级', tone: 'red', fields: [{ label: '类型', value: '专项' }, { label: '编制单位', value: '市水务局' }] },
+  { id: 'YA2026002', title: '燃气管网泄漏专项预案', status: 'Ⅰ级', tone: 'red', fields: [{ label: '类型', value: '专项' }, { label: '编制单位', value: '市燃气集团' }] },
+  { id: 'YA2026003', title: '排水管网溢流处置预案', status: 'Ⅱ级', tone: 'orange', fields: [{ label: '类型', value: '专项' }, { label: '编制单位', value: '区水务所' }] },
+]
+
+export const notices = [
+  { title: '关于开展城市地下管网安全专项检查的通知', date: '2026-09-29', tag: '通知' },
+  { title: '国庆期间地下管网安全保障工作安排', date: '2026-09-28', tag: '通知' },
+  { title: '第三季度监测设备维护计划', date: '2026-09-26', tag: '公告' },
+  { title: '燃气泄漏应急处置演练通知', date: '2026-09-25', tag: '公告' },
+]

+ 7 - 0
src/env.d.ts

@@ -0,0 +1,7 @@
+/// <reference types="vite/client" />
+
+declare module '*.vue' {
+  import type { DefineComponent } from 'vue'
+  const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>
+  export default component
+}

+ 7 - 0
src/main.ts

@@ -0,0 +1,7 @@
+import { createSSRApp } from 'vue'
+import App from './App.vue'
+
+export function createApp() {
+  const app = createSSRApp(App)
+  return { app }
+}

+ 17 - 0
src/manifest.json

@@ -0,0 +1,17 @@
+{
+  "name": "城市地下管网管控平台",
+  "appid": "__UNI__CITYLIFELINE",
+  "description": "城市地下管网管控平台移动端",
+  "versionName": "0.1.0",
+  "versionCode": "100",
+  "transformPx": false,
+  "app-plus": {
+    "usingComponents": true,
+    "nvueStyleCompiler": "uni-app",
+    "compilerVersion": 3,
+    "splashscreen": { "alwaysShowBeforeRender": true, "waiting": true, "autoclose": true }
+  },
+  "h5": { "title": "城市地下管网管控平台", "router": { "mode": "hash" } },
+  "mp-weixin": { "appid": "", "setting": { "urlCheck": false }, "usingComponents": true },
+  "vueVersion": "3"
+}

+ 54 - 0
src/pages.json

@@ -0,0 +1,54 @@
+{
+  "globalStyle": {
+    "navigationStyle": "custom",
+    "navigationBarTextStyle": "black",
+    "navigationBarBackgroundColor": "#ffffff",
+    "backgroundColor": "#f3f6fa",
+    "h5": {}
+  },
+  "pages": [
+    { "path": "pages/login/index", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/message/index", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true } },
+    { "path": "pages/office/index", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true } },
+    { "path": "pages/emergency/index", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/contacts/index", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true } },
+    { "path": "pages/profile/index", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/message/workorder-detail", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true } },
+    { "path": "pages/message/warning-detail", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/message/alarm-detail", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true } },
+    { "path": "pages/message/notice-detail", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/message/notices", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true, "onReachBottomDistance": 80 } },
+    { "path": "pages/office/devices", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true, "onReachBottomDistance": 80 } },
+    { "path": "pages/office/device-detail", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/office/alarms", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true, "onReachBottomDistance": 80 } },
+    { "path": "pages/office/patrol", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true, "onReachBottomDistance": 80 } },
+    { "path": "pages/office/patrol-detail", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/office/daily-patrol", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/office/event-report", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/emergency/events", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/emergency/plans", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/emergency/plan-detail", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/emergency/dispatch", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/emergency/audit", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/profile/workorders", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true, "onReachBottomDistance": 80 } },
+    { "path": "pages/profile/warnings", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/profile/basic", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/profile/password", "style": { "navigationStyle": "custom" } },
+    { "path": "pages/profile/login-log", "style": { "navigationStyle": "custom", "enablePullDownRefresh": true, "onReachBottomDistance": 80 } }
+  ],
+  "tabBar": {
+    "color": "#7f8c9e",
+    "selectedColor": "#08264c",
+    "backgroundColor": "#ffffff",
+    "borderStyle": "white",
+    "height": "56px",
+    "fontSize": "12px",
+    "list": [
+      { "pagePath": "pages/message/index", "text": "消息", "iconPath": "static/tabbar/message.png", "selectedIconPath": "static/tabbar/message-active.png" },
+      { "pagePath": "pages/office/index", "text": "日常", "iconPath": "static/tabbar/office.png", "selectedIconPath": "static/tabbar/office-active.png" },
+      { "pagePath": "pages/emergency/index", "text": "应急", "iconPath": "static/tabbar/emergency.png", "selectedIconPath": "static/tabbar/emergency-active.png" },
+      { "pagePath": "pages/contacts/index", "text": "通讯录", "iconPath": "static/tabbar/contacts.png", "selectedIconPath": "static/tabbar/contacts-active.png" },
+      { "pagePath": "pages/profile/index", "text": "我的", "iconPath": "static/tabbar/profile.png", "selectedIconPath": "static/tabbar/profile-active.png" }
+    ]
+  }
+}

+ 109 - 0
src/pages/contacts/index.vue

@@ -0,0 +1,109 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
+import { pinyin } from 'pinyin-pro'
+import { getContacts, type ContactUser } from '@/services/contacts'
+
+const keyword = ref('')
+const contacts = ref<ContactUser[]>([])
+const loading = ref(false)
+const loaded = ref(false)
+const loadError = ref('')
+const contactCount = computed(() => Array.isArray(contacts.value) ? contacts.value.length : 0)
+
+const colors = ['#397ddd', '#16a075', '#8b62d2', '#d66b42', '#2b91ad', '#c35c86']
+
+function getName(item: ContactUser) {
+  return item.nickName || '未命名用户'
+}
+
+function getRole(item: ContactUser) {
+  return item.postNames?.filter(Boolean).join('、') || '未设置职位'
+}
+
+function getInitial(name: string) {
+  const first = pinyin(name.slice(0, 1), { pattern: 'first', toneType: 'none', nonZh: 'removed' })
+  const letter = first.slice(0, 1).toUpperCase()
+  return /^[A-Z]$/.test(letter) ? letter : '#'
+}
+
+function getColor(item: ContactUser) {
+  const value = item.userId || getName(item).charCodeAt(0)
+  return colors[Math.abs(value) % colors.length]
+}
+
+const visible = computed(() => {
+  const value = keyword.value.trim().toLowerCase()
+  if (!value) return contacts.value
+  return contacts.value.filter(item => {
+    const searchText = [getName(item), item.deptName || '', getRole(item), item.phonenumber || ''].join(' ').toLowerCase()
+    const pinyinText = pinyin(searchText, { toneType: 'none', nonZh: 'consecutive' }).toLowerCase()
+    return searchText.includes(value) || pinyinText.includes(value)
+  })
+})
+
+const grouped = computed(() => {
+  const groups = new Map<string, ContactUser[]>()
+  const source = Array.isArray(visible.value) ? visible.value : []
+  source.forEach(item => {
+    const letter = getInitial(getName(item))
+    const group = groups.get(letter) || []
+    group.push(item)
+    groups.set(letter, group)
+  })
+  return Array.from(groups.entries())
+    .sort(([left], [right]) => left.localeCompare(right))
+    .map(([letter, items]) => ({
+      letter,
+      items: items.sort((left, right) => pinyin(getName(left), { toneType: 'none' }).localeCompare(pinyin(getName(right), { toneType: 'none' }))),
+    }))
+})
+
+async function loadContacts() {
+  if (loading.value) return
+  loading.value = true
+  loadError.value = ''
+  try {
+    const result = await getContacts()
+    contacts.value = Array.isArray(result) ? result : []
+  } catch (error) {
+    loadError.value = error instanceof Error ? error.message : '通讯录获取失败'
+  } finally {
+    loading.value = false
+    loaded.value = true
+  }
+}
+
+async function refreshContacts() {
+  await loadContacts()
+  uni.stopPullDownRefresh()
+}
+
+function call(phone?: string) {
+  if (!phone) {
+    uni.showToast({ title: '该联系人未设置手机号', icon: 'none' })
+    return
+  }
+  uni.makePhoneCall({ phoneNumber: phone.replace(/\s/g, '') })
+}
+
+onLoad(loadContacts)
+onPullDownRefresh(refreshContacts)
+</script>
+
+<template>
+  <view class="page">
+    <view class="contact-head"><text class="title">通讯录</text><view class="search"><text>⌕</text><input v-model="keyword" placeholder="搜索联系人" /></view></view>
+    <view v-if="loaded && loadError && !contactCount" class="state error" @tap="loadContacts">{{ loadError }},点击重试</view>
+    <view v-else class="contact-list">
+      <view v-for="group in grouped" :key="group.letter" class="group"><view class="letter">{{ group.letter }}</view><view v-for="item in group.items" :key="item.userId" class="contact"><view class="avatar" :style="{ background: getColor(item) }">{{ getName(item).slice(0, 1) }}</view><view class="info"><text class="name">{{ getName(item) }}</text><text class="meta">{{ item.deptName || '未设置部门' }} · {{ getRole(item) }}</text><text v-if="item.phonenumber" class="number">{{ item.phonenumber }}</text></view><view class="phone" @tap.stop="call(item.phonenumber)">☎</view></view></view>
+      <view v-if="loaded && !grouped.length && !loading" class="empty">{{ keyword ? '未找到联系人' : '暂无可查看的联系人' }}</view>
+      <view v-else-if="loading" class="state load-state">正在加载通讯录...</view>
+      <view v-else-if="loadError" class="state error" @tap="loadContacts">{{ loadError }},点击重试</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.contact-head{padding:calc(40rpx + env(safe-area-inset-top)) 26rpx 28rpx;color:#fff;background:linear-gradient(135deg,#061b34,#174e76)}.title{display:block;margin:0 4rpx 27rpx;font-size:38rpx;font-weight:650}.search{display:flex;align-items:center;height:76rpx;padding:0 23rpx;border-radius:16rpx;background:rgba(255,255,255,.95);color:#8190a2}.search text{margin-right:13rpx;font-size:34rpx}.search input{flex:1;color:#33465d;font-size:26rpx}.contact-list{padding-bottom:calc(25rpx + env(safe-area-inset-bottom))}.letter{height:68rpx;padding:0 28rpx;color:#8b99aa;background:#f3f6fa;font-size:25rpx;font-weight:700;line-height:68rpx}.contact{display:flex;align-items:center;padding:23rpx 28rpx;background:#fff;border-bottom:1rpx solid #edf1f5}.avatar{display:flex;align-items:center;justify-content:center;width:82rpx;height:82rpx;margin-right:21rpx;color:#fff;border-radius:50%;font-size:31rpx;font-weight:650}.info{display:flex;flex:1;flex-direction:column;min-width:0}.name{color:#293d55;font-size:29rpx;font-weight:650}.meta{margin-top:10rpx;color:#8997a8;font-size:23rpx;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.number{margin-top:7rpx;color:#60758b;font-size:22rpx}.phone{display:flex;align-items:center;justify-content:center;width:65rpx;height:65rpx;margin-left:14rpx;color:#08264c;border-radius:50%;background:#e7edf3;font-family:Arial,sans-serif;font-size:33rpx}.state,.empty{padding:120rpx 28rpx;color:#98a4b2;text-align:center}.state.error{color:#c35c60}.state.load-state{padding:28rpx}.empty{padding-top:100rpx}
+</style>

+ 12 - 0
src/pages/emergency/audit.vue

@@ -0,0 +1,12 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import AppHeader from '@/components/AppHeader.vue'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import { plans } from '@/data/mock'
+import { showStaticToast } from '@/utils/navigation'
+const active=ref(0)
+</script>
+
+<template><view class="page"><AppHeader title="信息审核" /><SegmentTabs v-model="active" :items="['待审核','已通过','已驳回']" /><view class="page-content"><view v-for="(item,index) in plans" :key="item.id" class="audit card"><view class="head"><view><text class="name">{{ item.title }}</text><text class="no">{{ item.id }}</text></view><text class="status-pill" :class="index===0?'orange':index===1?'green':'red'">{{ index===0?'待审核':index===1?'已通过':'已驳回' }}</text></view><view class="row"><text>预案类型</text><text>{{ item.fields[0].value }}</text></view><view class="row"><text>编制单位</text><text>{{ item.fields[1].value }}</text></view><view class="row"><text>提交时间</text><text>2026-09-28 10:25</text></view><view v-if="index===0" class="actions"><button @tap="showStaticToast('审核意见静态演示')">驳回</button><button @tap="showStaticToast('审核通过静态演示')">通过</button></view></view></view></view></template>
+
+<style scoped lang="scss">.audit{padding:25rpx;margin-bottom:20rpx}.head{display:flex;align-items:flex-start;justify-content:space-between;padding-bottom:19rpx;margin-bottom:7rpx;border-bottom:1rpx solid #edf1f5}.head view{display:flex;flex:1;flex-direction:column;min-width:0}.name{overflow:hidden;color:#283c54;font-size:29rpx;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.no{margin-top:9rpx;color:#929eac;font-size:22rpx}.row{display:flex;justify-content:space-between;padding-top:15rpx;color:#495b70;font-size:24rpx}.row text:first-child{color:#8d99a8}.actions{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;padding-top:20rpx;margin-top:19rpx;border-top:1rpx solid #edf1f5}.actions button{height:62rpx;margin:0;color:#e05258;border:1rpx solid #f1c8ca;border-radius:999rpx;background:#fff;font-size:24rpx;line-height:60rpx}.actions button:last-child{color:#fff;border-color:#08264c;background:#08264c}</style>

+ 13 - 0
src/pages/emergency/dispatch.vue

@@ -0,0 +1,13 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import AppHeader from '@/components/AppHeader.vue'
+import FormField from '@/components/FormField.vue'
+import UploadPanel from '@/components/UploadPanel.vue'
+import { navigateBack, showStaticToast } from '@/utils/navigation'
+const receiver=ref('应急处置一组'); const content=ref('')
+function selectReceiver(){uni.showActionSheet({itemList:['应急处置一组','应急处置二组','市水务局','市燃气集团'],success:r=>receiver.value=['应急处置一组','应急处置二组','市水务局','市燃气集团'][r.tapIndex]})}
+</script>
+
+<template><view class="page"><AppHeader title="调度指挥" /><view class="page-content"><view class="dispatch-tip card"><text class="tip-icon">!</text><view><text>应急调度指令</text><text>指令下发后将通知相关处置人员,请确认信息准确。</text></view></view><view class="section-title">调度信息</view><view class="form card"><FormField v-model="receiver" label="接收对象" type="select" required @select="selectReceiver" /><FormField v-model="content" label="调度内容" type="textarea" required placeholder="请输入明确的调度指令和处置要求" /><view class="upload-field"><view class="label">附件</view><UploadPanel /></view></view><view class="two-actions"><button class="ghost-btn" @tap="navigateBack">取消</button><button class="primary-btn" @tap="showStaticToast('调度指令静态演示已完成')">下发指令</button></view></view></view></template>
+
+<style scoped lang="scss">.dispatch-tip{display:flex;align-items:center;padding:24rpx;background:#fff8e9}.tip-icon{display:flex;align-items:center;justify-content:center;width:66rpx;height:66rpx;margin-right:18rpx;color:#e38a19;border-radius:50%;background:#ffebbe;font-size:35rpx;font-weight:700}.dispatch-tip view{display:flex;flex:1;flex-direction:column;color:#805e2f;font-weight:600}.dispatch-tip view text:last-child{margin-top:8rpx;color:#9b7a4a;font-size:22rpx;font-weight:400}.form{padding:0 25rpx}.upload-field{padding:22rpx 0}.label{margin-bottom:16rpx;color:#34485f;font-size:27rpx}</style>

+ 5 - 0
src/pages/emergency/events.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts">
+import BusinessListPage from '@/components/BusinessListPage.vue'
+import { events } from '@/data/mock'
+</script>
+<template><BusinessListPage title="事件信息" :items="events" :tabs="['全部','核实中','已核实','处置中','已解除']" detail-path="/pages/message/alarm-detail" id-label="事件编号" placeholder="请输入事件编号或描述" /></template>

+ 29 - 0
src/pages/emergency/index.vue

@@ -0,0 +1,29 @@
+<script setup lang="ts">
+import { navigateTo } from '@/utils/navigation'
+
+const menus = [
+  { title: '事件信息', sub: '查看突发事件动态', icon: '⚑', path: '/pages/emergency/events' },
+  { title: '处置方案', sub: '查询应急处置预案', icon: '▤', path: '/pages/emergency/plans' },
+  { title: '调度指挥', sub: '下发应急调度指令', icon: '⌁', path: '/pages/emergency/dispatch' },
+  { title: '信息审核', sub: '审核预案与信息', icon: '✓', path: '/pages/emergency/audit' },
+]
+</script>
+
+<template>
+  <view class="page emergency-page">
+    <view class="emergency-head"><view class="shield">◇</view><text class="head-title">应急处置</text><text class="head-sub">统一指挥 · 快速响应 · 协同处置</text></view>
+    <view class="page-content emergency-content">
+      <view class="summary card"><view><text class="num red">2</text><text>待核实事件</text></view><view><text class="num orange">3</text><text>处置中事件</text></view><view><text class="num green">18</text><text>本月办结事件</text></view></view>
+      <view class="section-title">应急应用</view>
+      <view class="menu-grid"><view v-for="item in menus" :key="item.title" class="menu card" @tap="navigateTo(item.path)"><view class="menu-icon">{{ item.icon }}</view><text class="menu-title">{{ item.title }}</text><text class="menu-sub">{{ item.sub }}</text></view></view>
+      <view class="section-title">应急动态</view>
+      <view class="dynamic card"><view class="dynamic-icon">!</view><view class="dynamic-main"><text class="dynamic-title">供水管网爆管事件正在处置</text><text class="dynamic-sub">黄浦区·中山东路 · 10分钟前</text></view><text class="arrow">›</text></view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.emergency-head{display:flex;flex-direction:column;align-items:center;height:330rpx;padding-top:calc(47rpx + env(safe-area-inset-top));color:#fff;background:linear-gradient(145deg,#061b34,#0b3156 55%,#155376)}.shield{display:flex;align-items:center;justify-content:center;width:90rpx;height:90rpx;border:2rpx solid rgba(255,255,255,.42);border-radius:24rpx;background:rgba(255,255,255,.11);font-size:55rpx}.head-title{margin-top:19rpx;font-size:38rpx;font-weight:650}.head-sub{margin-top:10rpx;color:rgba(255,255,255,.72);font-size:23rpx}
+.emergency-content{position:relative;margin-top:-45rpx}.summary{display:grid;grid-template-columns:repeat(3,1fr);padding:27rpx 0}.summary view{display:flex;flex-direction:column;align-items:center;color:#7b899a;font-size:22rpx;border-right:1rpx solid #eef1f5}.summary view:last-child{border:0}.num{margin-bottom:8rpx;font-size:40rpx;font-weight:700}.red{color:#e95157}.orange{color:#eb8b2c}.green{color:#15a36c}
+.menu-grid{display:grid;grid-template-columns:1fr 1fr;gap:20rpx}.menu{display:flex;flex-direction:column;align-items:center;padding:30rpx 15rpx;border:1rpx solid #e1e9ea}.menu-icon{display:flex;align-items:center;justify-content:center;width:86rpx;height:86rpx;color:#fff;border-radius:22rpx;background:#08264c;font-size:42rpx}.menu-title{margin-top:18rpx;color:#263a51;font-size:28rpx;font-weight:650}.menu-sub{margin-top:7rpx;color:#929ead;font-size:21rpx}.dynamic{display:flex;align-items:center;padding:24rpx}.dynamic-icon{display:flex;align-items:center;justify-content:center;width:70rpx;height:70rpx;margin-right:18rpx;color:#fff;border-radius:18rpx;background:#08264c;font-size:36rpx;font-weight:700}.dynamic-main{display:flex;flex:1;flex-direction:column}.dynamic-title{color:#314359;font-size:27rpx}.dynamic-sub{margin-top:9rpx;color:#95a0ae;font-size:22rpx}.arrow{color:#a9b3c0;font-size:48rpx}
+</style>

+ 10 - 0
src/pages/emergency/plan-detail.vue

@@ -0,0 +1,10 @@
+<script setup lang="ts">
+import AppHeader from '@/components/AppHeader.vue'
+import FieldList from '@/components/FieldList.vue'
+const fields=[{label:'预案编号',value:'PA-2026-018'},{label:'预案名称',value:'供水管网爆管专项预案'},{label:'预案等级',value:'Ⅰ级'},{label:'预案类型',value:'专项'},{label:'编制单位',value:'市水务局'},{label:'版本',value:'v3.0'}]
+const chapters=[['一、总则','为规范供水管网爆管突发事件应急处置,保障城市供水安全,制定本预案。'],['二、组织机构与职责','成立现场指挥部,设抢修、疏散、保障三个工作组。'],['三、响应分级','Ⅰ级(全市停水)/ Ⅱ级(区域停水)/ Ⅲ级(局部停水)。'],['四、处置程序','关阀止水 → 抢修 → 冲洗排气 → 恢复供水。']]
+</script>
+
+<template><view class="page"><AppHeader title="预案预览" /><view class="page-content"><view class="plan-cover card"><view class="file-icon">▤</view><text class="title">供水管网爆管专项预案</text><text class="version">版本 v3.0 · 专项 · Ⅰ级 · 市水务局</text></view><view class="section-title">预案信息</view><FieldList :fields="fields" /><view class="section-title">预案正文</view><view class="article card"><view v-for="chapter in chapters" :key="chapter[0]" class="chapter"><text>{{ chapter[0] }}</text><text>{{ chapter[1] }}</text></view></view></view></view></template>
+
+<style scoped lang="scss">.plan-cover{display:flex;flex-direction:column;align-items:center;padding:40rpx 25rpx;background:linear-gradient(145deg,#f8fbff,#edf5ff)}.file-icon{display:flex;align-items:center;justify-content:center;width:100rpx;height:100rpx;color:#08264c;border-radius:25rpx;background:#fff;box-shadow:0 8rpx 25rpx rgba(8,38,76,.12);font-size:50rpx}.title{margin-top:22rpx;color:#263b52;font-size:32rpx;font-weight:650}.version{margin-top:9rpx;color:#8795a6;font-size:23rpx}.article{padding:7rpx 27rpx;color:#46586d;font-size:26rpx;line-height:1.85}.chapter{padding:20rpx 0;border-bottom:1rpx solid #edf1f5}.chapter:last-child{border-bottom:0}.chapter text{display:block}.chapter text:first-child{margin-bottom:8rpx;color:#2e435a;font-weight:700}.chapter text:last-child{color:#52647a}</style>

+ 5 - 0
src/pages/emergency/plans.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts">
+import BusinessListPage from '@/components/BusinessListPage.vue'
+import { plans } from '@/data/mock'
+</script>
+<template><BusinessListPage title="处置方案" :items="plans" :tabs="['全部','综合预案','专项预案']" detail-path="/pages/emergency/plan-detail" id-label="预案编号" placeholder="请输入预案名称或编号" /></template>

+ 138 - 0
src/pages/login/index.vue

@@ -0,0 +1,138 @@
+<script setup lang="ts">
+import { onLoad } from '@dcloudio/uni-app'
+import { ref } from 'vue'
+import { getCaptcha, loginAccount } from '@/services/auth'
+import { setToken } from '@/utils/auth'
+
+const username = ref('')
+const password = ref('')
+const captcha = ref('')
+const showPassword = ref(false)
+const remember = ref(false)
+const captchaEnabled = ref(true)
+const captchaUrl = ref('')
+const captchaUuid = ref('')
+const captchaLoading = ref(false)
+const loggingIn = ref(false)
+
+async function loadCaptcha() {
+  if (captchaLoading.value) return
+  captchaLoading.value = true
+  try {
+    const response = await getCaptcha()
+    captchaEnabled.value = response.captchaEnabled ?? true
+    captchaUrl.value = response.img ? `data:image/gif;base64,${response.img}` : ''
+    captchaUuid.value = response.uuid || ''
+    captcha.value = ''
+  } catch (error) {
+    captchaUrl.value = ''
+    uni.showToast({ title: error instanceof Error ? error.message : '验证码获取失败', icon: 'none' })
+  } finally {
+    captchaLoading.value = false
+  }
+}
+
+async function login() {
+  if (loggingIn.value) return
+  if (!username.value || !password.value) {
+    uni.showToast({ title: '请输入账号和密码', icon: 'none' })
+    return
+  }
+  if (captchaEnabled.value && !captcha.value) {
+    uni.showToast({ title: '请输入验证码', icon: 'none' })
+    return
+  }
+
+  loggingIn.value = true
+  try {
+    const response = await loginAccount({
+      username: username.value.trim(),
+      password: password.value,
+      code: captcha.value.trim(),
+      uuid: captchaUuid.value,
+    })
+    if (!response.token) throw new Error('登录成功但未返回访问令牌')
+
+    setToken(response.token)
+    if (remember.value) uni.setStorageSync('remembered-username', username.value.trim())
+    else uni.removeStorageSync('remembered-username')
+    uni.switchTab({ url: '/pages/message/index' })
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '登录失败', icon: 'none' })
+    if (captchaEnabled.value) await loadCaptcha()
+  } finally {
+    loggingIn.value = false
+  }
+}
+
+onLoad(() => {
+  const rememberedUsername = uni.getStorageSync('remembered-username')
+  if (rememberedUsername) {
+    username.value = rememberedUsername
+    remember.value = true
+  }
+  loadCaptcha()
+})
+</script>
+
+<template>
+  <view class="login-page">
+    <view class="network-lines"><view v-for="i in 8" :key="i" class="line" :style="{ top: `${i * 11}%`, transform: `rotate(${i % 2 ? -8 : 9}deg)` }"></view></view>
+    <view class="login-wrap">
+      <view class="brand">
+        <view class="brand-icon"><view class="pipe-mark">⌁</view></view>
+        <view class="brand-title">沅陵太常片区城市地下管网</view>
+        <view class="brand-title">管控平台</view>
+      </view>
+      <view class="login-card">
+        <view class="welcome">欢迎登录 <text>管网管控平台</text></view>
+        <view class="input-row"><view class="icon user-icon" aria-hidden="true"></view><input v-model="username" placeholder="请输入账号" /></view>
+        <view class="input-row"><view class="icon lock-icon" aria-hidden="true"></view><input v-model="password" placeholder="请输入密码" :password="!showPassword" /><text class="eye" @tap="showPassword = !showPassword">{{ showPassword ? '◉' : '◌' }}</text></view>
+        <view v-if="captchaEnabled" class="captcha-row">
+          <view class="input-row"><view class="icon verify-icon" aria-hidden="true"></view><input v-model="captcha" maxlength="4" placeholder="验证码" /></view>
+          <view class="captcha" @tap="loadCaptcha">
+            <image v-if="captchaUrl" class="captcha-image" :src="captchaUrl" mode="scaleToFill" />
+            <text v-else>{{ captchaLoading ? '加载中...' : '点击刷新' }}</text>
+          </view>
+        </view>
+        <view class="remember" @tap="remember = !remember"><view class="check" :class="{ checked: remember }">{{ remember ? '✓' : '' }}</view><text>记住账号</text></view>
+        <button class="login-btn" :class="{ disabled: loggingIn }" :loading="loggingIn" :disabled="loggingIn" @tap="login">{{ loggingIn ? '登录中...' : '登 录' }}</button>
+      </view>
+      <text class="copyright">城市地下管网安全运行 · 智慧守护</text>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.login-page, .login-wrap, .login-card, .input-row, .captcha-row { box-sizing: border-box; }
+.login-page { position: relative; width: 100%; min-height: 100vh; overflow: hidden; color: #fff; background: linear-gradient(160deg, #16324f 0%, #1f4e79 48%, #2b6ca3 100%); }
+.network-lines { position: absolute; inset: 0; opacity: .12; }
+.line { position: absolute; left: -20%; width: 140%; height: 1rpx; background: repeating-linear-gradient(90deg, #fff 0, #fff 35rpx, transparent 35rpx, transparent 62rpx); }
+.login-wrap { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; width: 100%; min-height: 100vh; padding: calc(120rpx + env(safe-area-inset-top)) 55rpx 40rpx; }
+.brand { width: 100%; text-align: center; text-shadow: 0 4rpx 16rpx rgba(10,30,50,.45); }
+.brand-icon { display: flex; align-items: center; justify-content: center; width: 128rpx; height: 128rpx; margin: 0 auto 28rpx; border-radius: 34rpx; background: rgba(255,255,255,.96); box-shadow: 0 16rpx 40rpx rgba(8,26,44,.35); }
+.pipe-mark { color: #2563eb; font-size: 82rpx; font-weight: 600; transform: rotate(-18deg); }
+.brand-title { font-size: 38rpx; font-weight: 600; letter-spacing: 2rpx; line-height: 1.55; }
+.login-card { width: 100%; max-width: 640rpx; margin-top: 70rpx; padding: 50rpx 40rpx 56rpx; border-radius: 28rpx; background: #fff; box-shadow: 0 28rpx 70rpx rgba(6,22,38,.4); }
+.welcome { margin-bottom: 40rpx; color: #26374e; font-size: 31rpx; font-weight: 600; text-align: center; }
+.welcome text { color: #2563eb; }
+.input-row { display: flex; flex: 1; align-items: center; height: 94rpx; padding: 0 24rpx; margin-bottom: 24rpx; border: 1rpx solid #dfe7ef; border-radius: 18rpx; background: #f8fafc; }
+.icon { position: relative; display: flex; flex: 0 0 54rpx; align-items: center; justify-content: center; width: 54rpx; height: 54rpx; margin-right: 17rpx; border: 1rpx solid #c8dced; border-radius: 16rpx; background: linear-gradient(145deg, #edf6ff, #dcecff); color: #164c7f; }
+.user-icon::before { content: ''; position: absolute; top: 11rpx; width: 15rpx; height: 15rpx; border: 3rpx solid #164c7f; border-radius: 50%; }
+.user-icon::after { content: ''; position: absolute; bottom: 10rpx; width: 29rpx; height: 15rpx; border: 3rpx solid #164c7f; border-bottom: 0; border-radius: 18rpx 18rpx 0 0; }
+.lock-icon::before { content: ''; position: absolute; bottom: 11rpx; width: 26rpx; height: 21rpx; border: 3rpx solid #164c7f; border-radius: 5rpx; background: rgba(255,255,255,.3); }
+.lock-icon::after { content: ''; position: absolute; top: 12rpx; width: 17rpx; height: 18rpx; border: 3rpx solid #164c7f; border-bottom: 0; border-radius: 12rpx 12rpx 0 0; }
+.verify-icon::before { content: ''; position: absolute; width: 27rpx; height: 27rpx; border: 3rpx solid #164c7f; border-radius: 50%; }
+.verify-icon::after { content: ''; position: absolute; width: 13rpx; height: 7rpx; border-bottom: 3rpx solid #164c7f; border-left: 3rpx solid #164c7f; transform: translate(1rpx, -2rpx) rotate(-45deg); }
+input { flex: 1; color: #293a50; font-size: 28rpx; }
+.eye { padding: 18rpx 0 18rpx 20rpx; color: #8596a9; }
+.captcha-row { display: grid; grid-template-columns: 1fr 190rpx; gap: 18rpx; }
+.captcha { display: flex; align-items: center; justify-content: center; height: 94rpx; color: #1d4f88; border-radius: 16rpx; background: repeating-linear-gradient(15deg,#e9f3ff,#e9f3ff 7rpx,#d7e9fb 8rpx,#d7e9fb 10rpx); font-size: 31rpx; font-weight: 700; letter-spacing: 6rpx; font-style: italic; }
+.captcha-image { width: 100%; height: 100%; border-radius: 16rpx; }
+.remember { display: flex; align-items: center; width: max-content; margin: 2rpx 0 35rpx; color: #697b90; font-size: 25rpx; }
+.check { display: flex; align-items: center; justify-content: center; width: 31rpx; height: 31rpx; margin-right: 12rpx; border: 1rpx solid #b8c3d0; border-radius: 6rpx; }
+.check.checked { color: #fff; border-color: #2563eb; background: #2563eb; }
+.login-btn { height: 92rpx; color: #fff; border-radius: 16rpx; background: linear-gradient(135deg,#2479ec,#1858cc); box-shadow: 0 12rpx 26rpx rgba(37,99,235,.3); font-size: 31rpx; line-height: 92rpx; letter-spacing: 12rpx; }
+.login-btn.disabled { opacity: .7; }
+.copyright { margin-top: auto; padding-top: 40rpx; color: rgba(255,255,255,.68); font-size: 23rpx; }
+</style>

Файловите разлики са ограничени, защото са твърде много
+ 121 - 0
src/pages/message/alarm-detail.vue


+ 131 - 0
src/pages/message/index.vue

@@ -0,0 +1,131 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import BusinessCard from '@/components/BusinessCard.vue'
+import { warnings, type ListItem } from '@/data/mock'
+import { getNoticeList, getNoticeTypeLabel, type SystemNotice } from '@/services/notices'
+import { getMobilePendingWorkOrders, workOrderStatusText, workOrderTone, type WorkOrder } from '@/services/workorders'
+import { navigateTo } from '@/utils/navigation'
+
+const active = ref(0)
+const notices = ref<SystemNotice[]>([])
+const pendingOrders = ref<WorkOrder[]>([])
+const pendingTotal = ref(0)
+const pendingPageNum = ref(1)
+const pendingLoading = ref(false)
+const pendingLoaded = ref(false)
+const pendingHasMore = computed(() => pendingOrders.value.length < pendingTotal.value)
+const list = computed<ListItem[]>(() => active.value === 0 ? pendingOrders.value.map(toCard) : warnings.slice(0, 4))
+const pendingCount = computed(() => pendingTotal.value + warnings.filter(item => item.status !== '已解除').length)
+
+async function refresh() {
+  await Promise.all([loadPendingOrders(true), loadNotices()])
+}
+
+onLoad(refresh)
+onPullDownRefresh(async () => {
+  await refresh()
+  uni.stopPullDownRefresh()
+})
+onReachBottom(() => {
+  if (active.value === 0) loadPendingOrders()
+})
+
+function toCard(order: WorkOrder): ListItem {
+  const delayPending = Number(order.orderStatus) === 3 && Number(order.delayApplyStatus) === 1
+  return { id: order.orderNo, title: order.orderDesc || '故障工单', status: workOrderStatusText(order.orderStatus), tone: workOrderTone(order.orderStatus), secondaryStatus: delayPending ? '延期待审核' : undefined, secondaryTone: delayPending ? 'orange' : undefined, fields: [
+    ...(delayPending ? [{ label: '延期申请', value: `待审核${order.delayedDeadline ? `(延期至 ${order.delayedDeadline})` : ''}` }] : []),
+    { label: '工单描述', value: order.orderDesc || '—' },
+    { label: '设备信息', value: order.deviceId ? `${order.deviceCode || '—'}${order.deviceName ? `(${order.deviceName})` : ''}` : '未关联设备' },
+    { label: '安装位置', value: order.deviceLocation || '—' },
+  ] }
+}
+
+async function loadPendingOrders(reset = false) {
+  if (pendingLoading.value || (!reset && !pendingHasMore.value)) return
+  if (reset) {
+    pendingPageNum.value = 1
+    pendingOrders.value = []
+    pendingTotal.value = 0
+  }
+  pendingLoading.value = true
+  try {
+    const page = await getMobilePendingWorkOrders({ pageNum: pendingPageNum.value, pageSize: 10 })
+    pendingOrders.value = reset ? page.records : pendingOrders.value.concat(page.records)
+    pendingTotal.value = Number(page.total) || 0
+    if (pendingOrders.value.length < pendingTotal.value) pendingPageNum.value += 1
+    const count = pendingCount.value
+    if (count > 0) uni.setTabBarBadge({ index: 0, text: String(Math.min(count, 99)) })
+    else uni.removeTabBarBadge({ index: 0 })
+  } catch (error) {
+    if (reset) {
+      pendingOrders.value = []
+      pendingTotal.value = 0
+    }
+    uni.showToast({ title: error instanceof Error ? error.message : '待办工单获取失败', icon: 'none' })
+  } finally {
+    pendingLoading.value = false
+    pendingLoaded.value = true
+  }
+}
+
+async function loadNotices() {
+  try {
+    const result = await getNoticeList({ pageNum: 1, pageSize: 10 })
+    notices.value = result.rows.filter(item => item.status !== '1')
+  } catch (error) {
+    notices.value = []
+    uni.showToast({ title: error instanceof Error ? error.message : '通知公告获取失败', icon: 'none' })
+  }
+}
+
+function openNotice(item?: SystemNotice) {
+  if (item?.noticeId == null) return
+  navigateTo(`/pages/message/notice-detail?id=${item.noticeId}`)
+}
+
+function openItem(index: number, status: string) {
+  if (active.value === 0) navigateTo(`/pages/message/workorder-detail?id=${pendingOrders.value[index]?.orderId}`)
+  else navigateTo(`/pages/message/warning-detail?status=${encodeURIComponent(status)}`)
+}
+
+function openAll() {
+  navigateTo(active.value === 0 ? '/pages/profile/workorders' : '/pages/profile/warnings')
+}
+</script>
+
+<template>
+  <view class="page">
+    <view class="hero">
+      <view class="hero-top"><view><text class="hello">早上好,管理员</text><text class="sub">城市管网运行总体平稳</text></view></view>
+      <view class="notice">
+        <view class="bell-icon"></view>
+        <swiper v-if="notices.length" class="notice-swiper" vertical circular :autoplay="notices.length > 1" :interval="3500" :duration="450">
+          <swiper-item v-for="item in notices" :key="item.noticeId" @tap="openNotice(item)">
+            <view class="notice-main"><text class="notice-label">{{ getNoticeTypeLabel(item.noticeType) }}</text><text class="notice-text">{{ item.noticeTitle }}</text></view>
+          </swiper-item>
+        </swiper>
+        <view v-else class="notice-main"><text class="notice-text empty-notice">暂无通知公告</text></view>
+        <text class="more">›</text>
+      </view>
+    </view>
+    <SegmentTabs v-model="active" :items="['待办工单', '待办预警']" action-label="查看全部" @action="openAll" />
+    <view class="page-content with-tabs message-list">
+      <BusinessCard v-for="(item,index) in list" :key="item.id" :item="item" :id-label="active === 0 ? '工单编号' : '预警编号'" @open="openItem(index, item.status)" />
+      <view v-if="pendingLoaded && !list.length" class="empty-list">暂无待办数据</view>
+      <view v-else-if="active === 0 && pendingLoading" class="load-tip">正在加载...</view>
+      <view v-else-if="active === 0 && pendingOrders.length && !pendingHasMore" class="load-tip">已加载全部</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.hero { padding: calc(36rpx + env(safe-area-inset-top)) 26rpx 28rpx; color: #fff; background: linear-gradient(135deg,#061b34,#174e76); }
+.hero-top { display: flex; align-items: center; justify-content: space-between; padding: 4rpx 5rpx 30rpx; }
+.hello,.sub { display: block; }.hello{font-size:36rpx;font-weight:650}.sub{margin-top:10rpx;color:rgba(255,255,255,.78);font-size:24rpx}
+.notice{display:flex;align-items:center;height:82rpx;padding:0 22rpx;border-radius:16rpx;background:rgba(255,255,255,.16);backdrop-filter:blur(8px)}.bell-icon{flex-shrink:0;width:34rpx;height:34rpx;margin-right:16rpx;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9'/%3E%3Cpath d='M13.7 21a2 2 0 0 1-3.4 0'/%3E%3C/svg%3E") center/contain no-repeat}.notice-swiper{flex:1;height:82rpx;min-width:0}.notice-swiper swiper-item{display:flex;align-items:center}.notice-main{display:flex;flex:1;align-items:center;min-width:0}.notice-label{flex-shrink:0;margin-right:16rpx;padding:4rpx 13rpx;color:#9be2f6;border-radius:99rpx;background:rgba(102,215,248,.14);font-size:22rpx;font-weight:600}.notice-text{overflow:hidden;color:rgba(255,255,255,.9);font-size:24rpx;text-overflow:ellipsis;white-space:nowrap}.empty-notice{color:rgba(255,255,255,.68)}.more{font-size:45rpx}
+.message-list{padding-top:22rpx}
+.empty-list{padding:100rpx 0;color:#94a0ae;text-align:center;font-size:24rpx}
+.load-tip{padding:28rpx;color:#98a4b2;text-align:center;font-size:23rpx}
+</style>

+ 68 - 0
src/pages/message/notice-detail.vue

@@ -0,0 +1,68 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import { getNoticeDetail, getNoticeTypeLabel, type SystemNotice } from '@/services/notices'
+
+const notice = ref<SystemNotice>()
+const loading = ref(false)
+const errorMessage = ref('')
+let noticeId = ''
+
+function normalizeSpaces(value: string) {
+  return value.replace(/&amp;nbsp;|&nbsp;|&#0*160;|&#x0*a0;/gi, '\u00a0')
+}
+
+const content = computed(() => {
+  const source = normalizeSpaces(notice.value?.noticeContent || '暂无内容')
+  if (/<\/?[a-z][\s\S]*>/i.test(source)) return source
+  return source
+    .replace(/&/g, '&amp;')
+    .replace(/</g, '&lt;')
+    .replace(/>/g, '&gt;')
+    .replace(/\r?\n/g, '<br>')
+})
+
+async function loadNotice() {
+  if (!noticeId || loading.value) return
+  loading.value = true
+  errorMessage.value = ''
+  try {
+    notice.value = await getNoticeDetail(noticeId)
+    if (!notice.value) errorMessage.value = '通知公告不存在'
+  } catch (error) {
+    errorMessage.value = error instanceof Error ? error.message : '通知详情获取失败'
+  } finally {
+    loading.value = false
+  }
+}
+
+onLoad(options => {
+  noticeId = String(options?.id || '')
+  if (!noticeId) {
+    errorMessage.value = '缺少通知公告编号'
+    return
+  }
+  loadNotice()
+})
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="通知详情" />
+    <view class="page-content">
+      <view v-if="loading" class="state">正在加载通知详情...</view>
+      <view v-else-if="errorMessage" class="state error" @tap="loadNotice">{{ errorMessage }}<text v-if="noticeId">,点击重试</text></view>
+      <view v-else-if="notice" class="article card">
+        <text class="article-title">{{ notice.noticeTitle }}</text>
+        <view class="meta"><text>{{ getNoticeTypeLabel(notice.noticeType) }}</text><text>发布时间:{{ notice.createTime || '--' }}</text><text v-if="notice.createBy">发布人:{{ notice.createBy }}</text></view>
+        <view class="divider"></view>
+        <rich-text class="article-content" :nodes="content" />
+      </view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.article{padding:38rpx 30rpx}.article-title{display:block;color:#1e3149;font-size:37rpx;font-weight:650;line-height:1.45}.meta{display:flex;flex-wrap:wrap;gap:10rpx 24rpx;margin-top:22rpx;color:#97a2af;font-size:22rpx}.meta text:first-child{padding:3rpx 10rpx;color:#3b76d2;border-radius:6rpx;background:#e8f1fd}.divider{height:1rpx;margin:28rpx 0;background:#edf1f5}.article-content{display:block;color:#43546a;font-size:27rpx;line-height:1.9;word-break:break-word}.state{padding:160rpx 20rpx;color:#98a4b2;text-align:center;font-size:25rpx}.state.error{color:#c35c60}
+</style>

+ 93 - 0
src/pages/message/notices.vue

@@ -0,0 +1,93 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import { getNoticeList, getNoticeTypeLabel, type SystemNotice } from '@/services/notices'
+import { navigateTo } from '@/utils/navigation'
+
+const pageSize = 20
+const notices = ref<SystemNotice[]>([])
+const loading = ref(false)
+const finished = ref(false)
+const errorMessage = ref('')
+let pageNum = 1
+
+function formatDate(value?: string) {
+  const date = value?.slice(0, 10) || ''
+  return {
+    day: date.slice(8, 10) || '--',
+    month: date.slice(0, 7) || '---- --',
+  }
+}
+
+function getSummary(content?: string) {
+  return (content || '暂无内容')
+    .replace(/<style[\s\S]*?<\/style>/gi, '')
+    .replace(/<[^>]+>/g, ' ')
+    .replace(/&nbsp;/gi, ' ')
+    .replace(/&amp;/gi, '&')
+    .replace(/&lt;/gi, '<')
+    .replace(/&gt;/gi, '>')
+    .replace(/\s+/g, ' ')
+    .trim() || '暂无内容'
+}
+
+function openNotice(item: SystemNotice) {
+  navigateTo(`/pages/message/notice-detail?id=${item.noticeId}`)
+}
+
+async function loadNotices(reset = false) {
+  if (loading.value || (!reset && finished.value)) return
+  if (reset) {
+    pageNum = 1
+    finished.value = false
+    errorMessage.value = ''
+  }
+
+  loading.value = true
+  try {
+    const result = await getNoticeList({ pageNum, pageSize })
+    const rows = result.rows.filter(item => item.status !== '1')
+    notices.value = reset ? rows : notices.value.concat(rows)
+    finished.value = result.rows.length < pageSize || notices.value.length >= result.total
+    pageNum += 1
+  } catch (error) {
+    errorMessage.value = error instanceof Error ? error.message : '通知公告获取失败'
+    if (reset) notices.value = []
+  } finally {
+    loading.value = false
+  }
+}
+
+async function refreshNotices() {
+  await loadNotices(true)
+  uni.stopPullDownRefresh()
+}
+
+onLoad(() => loadNotices(true))
+onPullDownRefresh(refreshNotices)
+onReachBottom(() => loadNotices())
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="全部通知公告" />
+    <view class="page-content notice-content">
+      <view v-for="item in notices" :key="item.noticeId" class="notice-card card" @tap="openNotice(item)">
+        <view class="date"><text>{{ formatDate(item.createTime).day }}</text><text>{{ formatDate(item.createTime).month }}</text></view>
+        <view class="main">
+          <text class="title">{{ item.noticeTitle }}</text>
+          <view><text class="tag" :class="{ announce: item.noticeType === '2' }">{{ getNoticeTypeLabel(item.noticeType) }}</text><text class="summary">{{ getSummary(item.noticeContent) }}</text></view>
+        </view>
+      </view>
+      <view v-if="loading" class="state">正在加载通知公告...</view>
+      <view v-else-if="errorMessage" class="state error" @tap="loadNotices(!notices.length)">{{ errorMessage }},点击重试</view>
+      <view v-else-if="!notices.length" class="state">暂无通知公告</view>
+      <view v-else-if="finished" class="state end">没有更多了</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.notice-content{padding-top:22rpx}.notice-card{position:relative;display:flex;align-items:center;padding:24rpx;margin-bottom:18rpx}.date{display:flex;flex-direction:column;align-items:center;justify-content:center;width:105rpx;height:105rpx;margin-right:22rpx;border-radius:17rpx;background:#edf3f8;color:#6b7d92;font-size:20rpx}.date text:first-child{margin-bottom:5rpx;color:#08264c;font-size:34rpx;font-weight:700}.main{display:flex;flex:1;flex-direction:column;min-width:0}.title{overflow:hidden;color:#2b3f56;font-size:28rpx;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.main view{display:flex;align-items:center;margin-top:14rpx}.tag{flex-shrink:0;margin-right:10rpx;padding:4rpx 10rpx;border-radius:6rpx;background:#e8f1fd;color:#3b76d2;font-size:20rpx}.tag.announce{color:#2e9e5b;background:#e6f6ec}.summary{overflow:hidden;color:#909cab;font-size:22rpx;text-overflow:ellipsis;white-space:nowrap}.state{padding:65rpx 20rpx;color:#98a4b2;text-align:center;font-size:24rpx}.state.error{color:#c35c60}.state.end{padding:22rpx}
+</style>

+ 28 - 0
src/pages/message/warning-detail.vue

@@ -0,0 +1,28 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import ActionFormDrawer from '@/components/ActionFormDrawer.vue'
+import { showStaticToast } from '@/utils/navigation'
+
+type WarningState = 'draft' | 'recv_wait' | 'recv' | 'doing' | 'done' | 'rel'
+const configs: Record<WarningState,{label:string;tone:string;actions:string[]}> = {
+  draft:{label:'草稿',tone:'gray',actions:['发布']}, recv_wait:{label:'待接收',tone:'orange',actions:['接收']}, recv:{label:'已接收',tone:'',actions:['开始处置']},
+  doing:{label:'处置中',tone:'purple',actions:['提交处置']}, done:{label:'已处置',tone:'green',actions:['核查']}, rel:{label:'已解除',tone:'gray',actions:[]},
+}
+const labelState:Record<string,WarningState>={'草稿':'draft','待接收':'recv_wait','已接收':'recv','处理中':'doing','处置中':'doing','已处置':'done','已解除':'rel'}
+const currentKey=ref<WarningState>('draft')
+const current=computed(()=>configs[currentKey.value])
+const activeTab=ref(0)
+const drawerOpen=ref(false)
+const activeAction=ref('')
+onLoad(options=>{const label=decodeURIComponent(String(options?.status||'草稿'));currentKey.value=labelState[label]||'draft'})
+function openAction(action:string){activeAction.value=action;drawerOpen.value=true}
+function submitted(action:string){showStaticToast(`${action}表单已提交(静态演示)`)}
+const fields=[['预警名称','窨井盖异常开启预警'],['预警级别','一级'],['预警专项','井盖监测专项'],['预警类型','异常开启'],['预警编号','YJ20260710001'],['报警编号','BJ20260710001'],['报警位置','长江东路215号'],['处置人','张伟'],['核查人','赵敏'],['发布人','系统自动'],['权属单位','市政设施管理处'],['发布时间','2026-07-10 10:15:32']]
+</script>
+
+<template><view class="page warning-page"><AppHeader title="预警详情" /><view class="warn-top card"><text class="number">YJ20260710001</text><text class="status-pill" :class="current.tone">{{ current.label }}</text></view><view class="warn-card card"><SegmentTabs v-model="activeTab" :items="['预警信息','处置日志']" /><view v-if="activeTab===0" class="warn-grid"><view v-for="(field,index) in fields" :key="field[0]" :class="{full:[0,6].includes(index)}"><text>{{ field[0] }}</text><text :class="{level:index===1}">{{ field[1] }}</text></view></view><view v-else class="logs"><view class="tip">按时间倒序排列 · 滑动即可回溯</view><view class="day">7月10日</view><view class="log"><text>10:16:08</text><view><text>张伟</text><text>接收预警并开始现场核实</text></view></view><view class="log"><text>10:15:32</text><view><text>系统自动</text><text>预警发布,推送至处置人员待办</text></view></view></view></view><view v-if="current.actions.length" class="actions"><button v-for="action in current.actions" :key="action" @tap="openAction(action)">{{ action }}</button></view><view v-else class="no-action">该预警已解除,无后续操作</view><ActionFormDrawer v-model="drawerOpen" :action="activeAction" domain="warning" @submitted="submitted" /></view></template>
+
+<style scoped lang="scss">.warning-page{padding-bottom:130rpx}.warn-top{display:flex;align-items:center;justify-content:space-between;margin:20rpx 24rpx;padding:26rpx}.number{color:#263b52;font-size:29rpx;font-weight:700}.warn-card{margin:0 24rpx;overflow:hidden}.warn-grid{display:grid;grid-template-columns:1fr 1fr;gap:25rpx 20rpx;padding:28rpx}.warn-grid>view{display:flex;flex-direction:column;min-width:0}.warn-grid .full{grid-column:1/-1}.warn-grid view text:first-child{margin-bottom:9rpx;color:#909cab;font-size:22rpx}.warn-grid view text:last-child{color:#405269;font-size:25rpx;line-height:1.5;word-break:break-all}.warn-grid .level{color:#e34d59;font-weight:700}.logs{padding:24rpx}.tip{padding:13rpx 18rpx;color:#8592a2;border-radius:10rpx;background:#f4f7fa;font-size:22rpx}.day{margin:24rpx 0 8rpx;color:#8592a2;font-size:23rpx;font-weight:600}.log{display:grid;grid-template-columns:110rpx 1fr;gap:15rpx;padding:20rpx 0;border-bottom:1rpx solid #edf1f5;color:#8a97a7;font-size:22rpx}.log>view{display:flex;flex-direction:column;color:#68788c}.log>view text:first-child{margin-bottom:7rpx;color:#33475d;font-size:25rpx;font-weight:600}.actions,.no-action{position:fixed;right:0;bottom:0;left:0;z-index:30;padding:16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));background:#fff;box-shadow:0 -5rpx 20rpx rgba(38,59,83,.08)}.actions button{height:78rpx;margin:0;color:#fff;border-radius:999rpx;background:#08264c;font-size:27rpx;line-height:78rpx}.no-action{color:#8a97a7;text-align:center;font-size:24rpx}</style>

Файловите разлики са ограничени, защото са твърде много
+ 165 - 0
src/pages/message/workorder-detail.vue


+ 75 - 0
src/pages/office/alarms.vue

@@ -0,0 +1,75 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom, onUnload } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import SearchBar from '@/components/SearchBar.vue'
+import { getMobileAlarms, alarmAuditText, alarmAuditTone, alarmLevelTone, alarmTime, type Alarm } from '@/services/alarms'
+import { navigateTo } from '@/utils/navigation'
+const active = ref(0), keyword = ref(''), levelFilter = ref(0)
+const alarms = ref<Alarm[]>([]), total = ref(0), pageNum = ref(0)
+const loading = ref(false), loaded = ref(false), error = ref(''), retryReset = ref(true)
+const hasMore = computed(() => alarms.value.length < total.value)
+const tabs = ['全部', '待核实', '确认报警', '误报警']
+const levelOptions = ['全部等级', '一级报警', '二级报警', '三级报警', '四级报警']
+let requestId = 0
+async function load(reset = false) {
+  if (!reset && (loading.value || !hasMore.value)) return
+  const request = ++requestId, next = reset ? 1 : pageNum.value + 1
+  loading.value = true; error.value = ''; retryReset.value = reset
+  try {
+    const result = await getMobileAlarms({ pageNum: next, pageSize: 10, keyword: keyword.value.trim() || undefined,
+      alarmLevel: levelFilter.value || undefined, auditStatus: active.value ? active.value - 1 : undefined })
+    if (request !== requestId) return
+    alarms.value = reset ? result.records : alarms.value.concat(result.records)
+    total.value = Number(result.total); pageNum.value = next; loaded.value = true
+  } catch (e) { if (request === requestId) error.value = e instanceof Error ? e.message : '故障通知加载失败' }
+  finally { if (request === requestId) loading.value = false }
+}
+function selectTab(index: number) { if (index !== active.value) { active.value = index; load(true) } }
+function chooseLevel(event: { detail: { value: string | number } }) {
+  const index = Number(event.detail.value)
+  if (index !== levelFilter.value) { levelFilter.value = index; load(true) }
+}
+function openDetail(item: Alarm) { navigateTo(`/pages/message/alarm-detail?id=${encodeURIComponent(item.id)}`) }
+onLoad(() => load(true))
+onUnload(() => { ++requestId })
+onPullDownRefresh(async () => { try { await load(true) } finally { uni.stopPullDownRefresh() } })
+onReachBottom(() => load())
+</script>
+<template>
+  <view class="page">
+    <AppHeader title="故障通知" />
+    <SegmentTabs :model-value="active" :items="tabs" @update:model-value="selectTab" />
+    <SearchBar v-model="keyword" attached placeholder="设备名称、编码或报警编号" @search="load(true)">
+      <template #prefix>
+        <picker class="level-picker" :range="levelOptions" :value="levelFilter" @change="chooseLevel">
+          <view class="level-select"><text>{{ levelOptions[levelFilter] }}</text><text class="level-arrow">⌄</text></view>
+        </picker>
+      </template>
+    </SearchBar>
+    <view class="filter-row"><text>共 {{ total }} 条故障通知</text></view>
+    <view class="page-content">
+      <view v-for="item in alarms" :key="item.id" class="alarm-card card" @tap="openDetail(item)">
+        <view class="head"><text class="name">{{ item.deviceName || item.deviceCode || '设备名称未记录' }}</text><text class="status-pill" :class="alarmAuditTone(item.auditStatus)">{{ alarmAuditText(item) }}</text></view>
+        <view class="row"><text>报警编号</text><text>{{ item.alarmNo || '—' }}</text></view>
+        <view class="row"><text>报警等级</text><text class="status-pill" :class="alarmLevelTone(item.alarmLevel)">{{ item.alarmLevelName || '—' }}</text></view>
+        <view class="row"><text>报警内容</text><text>{{ item.alarmContent || '—' }}</text></view>
+        <view class="row"><text>安装位置</text><text>{{ item.equipmentLocation || '—' }}</text></view>
+        <view class="row"><text>报警时间</text><text>{{ alarmTime(item.createTime) }}</text></view>
+        <view class="foot"><text>查看详情 ›</text></view>
+      </view>
+      <view v-if="loading" class="load-tip">正在加载...</view>
+      <view v-else-if="error" class="load-tip retry" @tap="load(retryReset)">{{ error }},点击重试</view>
+      <view v-else-if="loaded && !alarms.length" class="load-tip">暂无匹配的故障通知</view>
+      <view v-else-if="alarms.length && !hasMore" class="load-tip">已加载全部</view>
+    </view>
+  </view>
+</template>
+<style scoped lang="scss">
+.level-picker { flex-shrink: 0; width: 170rpx; }
+.level-select { display: flex; align-items: center; justify-content: space-between; gap: 10rpx; height: 72rpx; padding: 0 18rpx; border-radius: 12rpx; background: #f2f5f8; color: #405874; font-size: 25rpx; white-space: nowrap; }
+.level-arrow { color: #8c99aa; font-size: 26rpx; }
+.filter-row { display: flex; align-items: center; justify-content: space-between; padding: 0 26rpx 16rpx; background: #fff; color: #8a97a7; font-size: 23rpx; }
+.alarm-card{padding:25rpx;margin-bottom:20rpx}.head{display:flex;align-items:center;justify-content:space-between;gap:16rpx;padding-bottom:19rpx;margin-bottom:8rpx;border-bottom:1rpx solid #edf1f5}.name{flex:1;min-width:0;color:#263b52;font-size:30rpx;font-weight:650;overflow-wrap:anywhere}.head .status-pill{flex-shrink:0}.row{display:grid;grid-template-columns:140rpx 1fr;gap:14rpx;align-items:start;padding-top:16rpx;color:#46576b;font-size:24rpx;line-height:1.6}.row>text:first-child{color:#8c99a8}.row>text:last-child{text-align:right;overflow-wrap:anywhere}.row .status-pill{justify-self:end}.foot{display:flex;justify-content:flex-end;padding-top:20rpx;margin-top:18rpx;border-top:1rpx solid #edf1f5;color:#3b5bdb;font-size:25rpx}.load-tip{padding:40rpx 20rpx;color:#98a4b2;text-align:center;font-size:23rpx}.retry{color:#3b5bdb}
+</style>

+ 9 - 0
src/pages/office/daily-patrol.vue

@@ -0,0 +1,9 @@
+<script setup lang="ts">
+import AppHeader from '@/components/AppHeader.vue'
+import { navigateTo, showStaticToast } from '@/utils/navigation'
+const types=[{name:'管线巡查',icon:'⌁',color:'#267ce8'},{name:'井盖巡查',icon:'◉',color:'#18a273'},{name:'设备巡查',icon:'⚙',color:'#8b62d5'},{name:'道路巡查',icon:'⌖',color:'#ef8b25'}]
+</script>
+
+<template><view class="page"><AppHeader title="日常巡查" /><view class="page-content"><view class="checkin card"><view class="location"><text class="pin">⌖</text><view><text class="loc-title">当前位置</text><text class="loc-sub">湖南省怀化市沅陵县辰州东街</text></view></view><button @tap="showStaticToast('定位签到成功')">巡查签到</button></view><view class="section-title">巡查类型</view><view class="type-grid"><view v-for="item in types" :key="item.name" class="type card" @tap="navigateTo('/pages/office/event-report')"><view class="type-icon" :style="{color:item.color,background:`${item.color}14`}">{{ item.icon }}</view><text>{{ item.name }}</text></view></view><view class="section-title">今日巡查</view><view class="progress card"><view><text class="count">3</text><text>已巡查点位</text></view><view><text class="count orange">1</text><text>发现问题</text></view><view><text class="count green">6.2km</text><text>巡查里程</text></view></view></view></view></template>
+
+<style scoped lang="scss">.checkin{padding:28rpx}.location{display:flex;align-items:center}.pin{display:flex;align-items:center;justify-content:center;width:77rpx;height:77rpx;margin-right:20rpx;color:#08264c;border-radius:19rpx;background:#e8eff6;font-size:39rpx}.location view{display:flex;flex:1;flex-direction:column}.loc-title{color:#31455c;font-size:28rpx;font-weight:650}.loc-sub{margin-top:8rpx;color:#8e9aa9;font-size:23rpx}.checkin button{height:76rpx;margin-top:25rpx;color:#fff;border-radius:999rpx;background:#08264c;font-size:27rpx;line-height:76rpx}.type-grid{display:grid;grid-template-columns:1fr 1fr;gap:19rpx}.type{display:flex;align-items:center;padding:24rpx;color:#35495f;font-size:27rpx;font-weight:600}.type-icon{display:flex;align-items:center;justify-content:center;width:70rpx;height:70rpx;margin-right:17rpx;border-radius:18rpx;font-size:36rpx}.progress{display:grid;grid-template-columns:repeat(3,1fr);padding:29rpx 0}.progress view{display:flex;flex-direction:column;align-items:center;color:#8996a6;font-size:22rpx;border-right:1rpx solid #edf1f5}.progress view:last-child{border:0}.count{margin-bottom:8rpx;color:#08264c;font-size:37rpx;font-weight:700}.orange{color:#ed8a26}.green{color:#16a16a}</style>

+ 51 - 0
src/pages/office/device-detail.vue

@@ -0,0 +1,51 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import { getMobileEquipmentDetail, type Equipment, type EquipmentDetail } from '@/services/equipment'
+
+const detail = ref<EquipmentDetail>()
+const loading = ref(true)
+const equipment = computed<Equipment | undefined>(() => detail.value?.equipmentInfo)
+const status = computed(() => detail.value?.statusInfo)
+const typeName = computed(() => detail.value?.typeInfo?.typeName || equipment.value?.equipmentTypeName || '—')
+
+onLoad(async options => {
+  const id = String(options?.id || '')
+  if (!id) { loading.value = false; uni.showToast({ title: '设备参数无效', icon: 'none' }); return }
+  try {
+    detail.value = await getMobileEquipmentDetail(id)
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '设备详情获取失败', icon: 'none' })
+  } finally {
+    loading.value = false
+  }
+})
+
+function statusLabel(value?: number) { return Number(value) === 1 ? '在线' : '离线' }
+function assetStatusLabel(value?: number) { return ['在用', '维修', '报废'][Number(value)] || '—' }
+function districtLabel(value?: number) { return ['城南', '城北', '太常'][Number(value)] || '—' }
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="设备详情" />
+    <view v-if="loading" class="state-tip">正在加载...</view>
+    <template v-else-if="equipment">
+      <view class="device-hero">
+        <text class="name">{{ equipment.equipmentName || '未命名设备' }}</text>
+        <view class="meta"><text>{{ equipment.equipmentCode || '—' }}</text><text>{{ typeName }}</text><text class="online" :class="Number(status?.onlineStatus) === 1 ? 'online-on' : 'online-off'"><i></i>{{ statusLabel(status?.onlineStatus) }}</text><text v-if="Number(status?.alarmStatus) === 1" class="alarm">报警</text></view>
+      </view>
+      <view class="page-content detail-content">
+        <view class="section card"><view class="section-heading">基础信息</view><view class="field-grid"><view><text>设备编码</text><text>{{ equipment.equipmentCode || '—' }}</text></view><view><text>设备名称</text><text>{{ equipment.equipmentName || '—' }}</text></view><view><text>设备类型</text><text>{{ typeName }}</text></view><view><text>所属片区</text><text>{{ districtLabel(equipment.district) }}</text></view><view><text>设备型号</text><text>{{ equipment.equipmentModel || '—' }}</text></view><view><text>制造商</text><text>{{ equipment.manufacturer || '—' }}</text></view><view><text>生产日期</text><text>{{ equipment.productionDate || '—' }}</text></view><view><text>规格参数</text><text>{{ equipment.equipmentSpec || '—' }}</text></view></view></view>
+        <view class="section card"><view class="section-heading">资产信息</view><view class="field-grid"><view><text>资产状态</text><text>{{ assetStatusLabel(status?.currentStatus) }}</text></view><view><text>资产价值(元)</text><text>{{ equipment.assetValue ?? '—' }}</text></view><view><text>使用年限(年)</text><text>{{ equipment.useLife ?? '—' }}</text></view><view><text>权属单位</text><text>{{ equipment.ownershipUnit || '—' }}</text></view></view></view>
+        <view class="section card"><view class="section-heading">部署运维</view><view class="field-grid"><view class="full"><text>安装位置</text><text>{{ equipment.equipmentLocation || '—' }}</text></view><view><text>经度</text><text>{{ equipment.longitude ?? '—' }}</text></view><view><text>纬度</text><text>{{ equipment.latitude ?? '—' }}</text></view><view><text>安装时间</text><text>{{ equipment.installTime || '—' }}</text></view><view><text>维护人员</text><text>{{ equipment.maintainer || '—' }}</text></view><view><text>联系电话</text><text>{{ equipment.maintainerPhone || '—' }}</text></view><view class="full"><text>备注</text><text>{{ equipment.remark || '—' }}</text></view></view></view>
+      </view>
+    </template>
+    <view v-else class="state-tip">设备不存在或无权查看</view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.state-tip{padding:180rpx 30rpx;color:#8c99a8;text-align:center}.device-hero{padding:30rpx 28rpx;color:#fff;background:linear-gradient(135deg,#061b34,#174e76)}.name{display:block;font-size:32rpx;font-weight:700}.meta{display:flex;flex-wrap:wrap;gap:12rpx;margin-top:18rpx}.meta>text{padding:7rpx 13rpx;border-radius:8rpx;background:rgba(255,255,255,.13);font-size:21rpx}.online{display:flex;align-items:center;gap:7rpx}.online i{width:11rpx;height:11rpx;border-radius:50%}.online-on{color:#baf2d2}.online-on i{background:#44c887}.online-off{color:#ffd3d3}.online-off i{background:#ee6b6b}.meta .alarm{color:#ffd5d5;background:rgba(226,75,84,.24)}.detail-content{padding-top:22rpx}.section{padding:26rpx;margin-bottom:20rpx}.section-heading{margin-bottom:23rpx;padding-left:15rpx;color:#263b52;border-left:7rpx solid #08264c;font-size:29rpx;font-weight:700}.field-grid{display:grid;grid-template-columns:1fr 1fr;gap:24rpx 20rpx}.field-grid>view{display:flex;flex-direction:column;min-width:0}.field-grid .full{grid-column:1/-1}.field-grid view text:first-child{margin-bottom:9rpx;color:#909cab;font-size:22rpx}.field-grid view text:last-child{color:#405269;font-size:25rpx;line-height:1.55;word-break:break-all}
+</style>

+ 104 - 0
src/pages/office/devices.vue

@@ -0,0 +1,104 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import SearchBar from '@/components/SearchBar.vue'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import { getMobileEquipmentPage, type Equipment } from '@/services/equipment'
+import { navigateTo } from '@/utils/navigation'
+
+const keyword = ref('')
+const activeStatus = ref(0)
+const alarmOnly = ref(false)
+const devices = ref<Equipment[]>([])
+const total = ref(0)
+const pageNum = ref(1)
+const loading = ref(false)
+const loaded = ref(false)
+const hasMore = computed(() => devices.value.length < total.value)
+const statusTabs = [{ label: '全部', value: '' }, { label: '在线', value: '1' }, { label: '离线', value: '0' }]
+
+onLoad(() => loadDevices(true))
+onPullDownRefresh(async () => {
+  await loadDevices(true)
+  uni.stopPullDownRefresh()
+})
+onReachBottom(() => loadDevices())
+
+async function loadDevices(reset = false) {
+  if (loading.value || (!reset && !hasMore.value)) return
+  if (reset) {
+    pageNum.value = 1
+    devices.value = []
+    total.value = 0
+  }
+  loading.value = true
+  try {
+    const result = await getMobileEquipmentPage({
+      pageNum: pageNum.value,
+      pageSize: 10,
+      keyword: keyword.value.trim() || undefined,
+      onlineStatus: statusTabs[activeStatus.value].value === '' ? undefined : Number(statusTabs[activeStatus.value].value),
+      alarmStatus: alarmOnly.value ? 1 : undefined,
+    })
+    devices.value = reset ? result.records : devices.value.concat(result.records)
+    total.value = Number(result.total) || 0
+    pageNum.value += 1
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '设备列表获取失败', icon: 'none' })
+  } finally {
+    loading.value = false
+    loaded.value = true
+  }
+}
+
+function selectStatus(value: number) {
+  if (activeStatus.value === value) return
+  activeStatus.value = value
+  loadDevices(true)
+}
+
+function search() { loadDevices(true) }
+function toggleAlarm() { alarmOnly.value = !alarmOnly.value; loadDevices(true) }
+function openDetail(item: Equipment) {
+  navigateTo(`/pages/office/device-detail?id=${encodeURIComponent(item.equipmentId)}`)
+}
+function onlineLabel(status?: number) { return Number(status) === 1 ? '在线' : '离线' }
+function districtLabel(district?: number) { return ['城南', '城北', '太常'][Number(district)] || '—' }
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="设备信息查询" />
+    <SegmentTabs :model-value="activeStatus" :items="statusTabs.map(item => item.label)" @update:model-value="selectStatus" />
+    <SearchBar v-model="keyword" attached placeholder="请输入设备编码、名称" @search="search">
+      <template #prefix>
+        <view class="alarm-prefix" @tap="toggleAlarm">
+          <view class="checkbox" :class="{ checked: alarmOnly }">{{ alarmOnly ? '✓' : '' }}</view>
+          <text>报警</text>
+        </view>
+      </template>
+    </SearchBar>
+    <view class="result-count">共 {{ total }} 条设备</view>
+    <view class="page-content device-list">
+      <view v-for="item in devices" :key="item.equipmentId" class="device-card card" @tap="openDetail(item)">
+        <view class="device-head">
+          <text class="device-name">{{ item.equipmentName || '未命名设备' }}</text>
+          <text class="online" :class="Number(item.onlineStatus) === 1 ? 'online-on' : 'online-off'"><i></i>{{ onlineLabel(item.onlineStatus) }}</text>
+          <text v-if="Number(item.alarmStatus) === 1" class="alarm-tag">报警</text>
+        </view>
+        <text class="device-meta">编码:{{ item.equipmentCode || '—' }}</text>
+        <text class="device-meta">类型:{{ item.equipmentTypeName || '—' }}</text>
+        <text class="device-meta">片区:{{ districtLabel(item.district) }}</text>
+        <view class="device-foot"><text class="location">{{ item.equipmentLocation || '未填写安装位置' }}</text><text class="detail-link">详情 ›</text></view>
+      </view>
+      <view v-if="loaded && !devices.length" class="empty">暂无匹配设备</view>
+      <view v-else-if="loading" class="load-tip">正在加载...</view>
+      <view v-else-if="devices.length && !hasMore" class="load-tip">已加载全部</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.alarm-prefix{display:flex;flex-shrink:0;align-items:center;gap:8rpx;padding-left:24rpx;color:#25364b;font-size:23rpx}.checkbox{display:flex;align-items:center;justify-content:center;width:30rpx;height:30rpx;border:2rpx solid #aab6c3;border-radius:5rpx;color:#fff;font-size:22rpx}.checkbox.checked{border-color:#3b5bdb;background:#3b5bdb}.result-count{padding:14rpx 26rpx 0;color:#8a9aa5;background:#fff;font-size:22rpx}.device-list{padding-top:18rpx}.device-card{padding:23rpx 24rpx;margin-bottom:16rpx}.device-head{display:flex;align-items:center;gap:12rpx;margin-bottom:12rpx}.device-name{flex:1;min-width:0;overflow:hidden;color:#0b1119;font-size:28rpx;font-weight:700;text-overflow:ellipsis;white-space:nowrap}.online{display:flex;flex-shrink:0;align-items:center;gap:7rpx;font-size:21rpx;font-weight:600}.online i{width:12rpx;height:12rpx;border-radius:50%}.online-on{color:#1a9e6b}.online-on i{background:#1a9e6b}.online-off{color:#e02020}.online-off i{background:#e02020}.alarm-tag{flex-shrink:0;padding:4rpx 13rpx;color:#e02020;border-radius:99rpx;background:#fdecec;font-size:20rpx;font-weight:600}.device-meta{display:block;margin-top:7rpx;color:#5a6b73;font-size:23rpx;line-height:1.5}.device-foot{display:flex;align-items:center;justify-content:space-between;gap:12rpx;margin-top:14rpx;padding-top:13rpx;border-top:1rpx dashed #e8eef3}.location{flex:1;min-width:0;overflow:hidden;color:#3b5bdb;font-size:22rpx;text-overflow:ellipsis;white-space:nowrap}.detail-link{flex-shrink:0;color:#3b5bdb;font-size:23rpx;font-weight:600}.empty,.load-tip{padding:56rpx 0;color:#98a4b2;text-align:center;font-size:23rpx}
+</style>

+ 14 - 0
src/pages/office/event-report.vue

@@ -0,0 +1,14 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import AppHeader from '@/components/AppHeader.vue'
+import FormField from '@/components/FormField.vue'
+import UploadPanel from '@/components/UploadPanel.vue'
+import { navigateBack, showStaticToast } from '@/utils/navigation'
+const type = ref('管网破损'); const location = ref('湖南省怀化市沅陵县辰州东街'); const desc = ref(''); const level = ref('一般')
+function selectType() { uni.showActionSheet({ itemList:['管网破损','井盖异常','道路积水','燃气泄漏','其他'], success:r => type.value=['管网破损','井盖异常','道路积水','燃气泄漏','其他'][r.tapIndex] }) }
+function selectLevel() { uni.showActionSheet({ itemList:['一般','较大','重大','特别重大'], success:r => level.value=['一般','较大','重大','特别重大'][r.tapIndex] }) }
+</script>
+
+<template><view class="page"><AppHeader title="事件上报" /><view class="page-content"><view class="form card"><FormField v-model="type" label="事件类型" type="select" required @select="selectType" /><FormField v-model="location" label="事发位置" required placeholder="请输入或选择位置" /><FormField v-model="desc" label="事件描述" type="textarea" required placeholder="请详细描述现场情况" /><view class="upload-field"><view class="label">现场附件</view><UploadPanel /></view><FormField v-model="level" label="紧急程度" type="select" required @select="selectLevel" /></view><view class="two-actions"><button class="ghost-btn" @tap="navigateBack">取消</button><button class="primary-btn" @tap="showStaticToast('事件静态表单已提交')">提交上报</button></view></view></view></template>
+
+<style scoped lang="scss">.form{padding:0 25rpx}.upload-field{padding:22rpx 0;border-bottom:1rpx solid #edf1f5}.label{margin-bottom:16rpx;color:#34485f;font-size:27rpx}</style>

Файловите разлики са ограничени, защото са твърде много
+ 58 - 0
src/pages/office/index.vue


+ 62 - 0
src/pages/office/patrol-detail.vue

@@ -0,0 +1,62 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad, onShow } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import InspectCompleteDrawer from '@/components/InspectCompleteDrawer.vue'
+import PhotoPreview from '@/components/PhotoPreview.vue'
+import { getMobileInspectTaskDetail, resolveInspectTaskPhoto, type InspectTask } from '@/services/inspect-tasks'
+
+const taskId = ref(0)
+const task = ref<InspectTask>()
+const loading = ref(true)
+const drawerOpen = ref(false)
+const photoPreview = ref<InstanceType<typeof PhotoPreview>>()
+const photos = computed(() => (task.value?.photoList || []).map(path => resolveInspectTaskPhoto(path, task.value?.attachmentBaseUrl)))
+const base = computed(() => [
+  ['巡检内容', task.value?.inspectContent || '—'],
+  ['巡检人', task.value?.assignUserName || '—'],
+  ['计划巡检时间', formatTime(task.value?.planTime)],
+  ['实际巡检时间', formatTime(task.value?.realTime)],
+])
+
+onLoad(options => { taskId.value = Number(options?.id) })
+onShow(() => loadDetail())
+
+async function loadDetail() {
+  if (!taskId.value) { loading.value = false; return }
+  loading.value = true
+  try {
+    task.value = await getMobileInspectTaskDetail(taskId.value)
+  } catch (error) {
+    task.value = undefined
+    uni.showToast({ title: error instanceof Error ? error.message : '巡检详情获取失败', icon: 'none' })
+  } finally {
+    loading.value = false
+  }
+}
+function formatTime(value?: string) { return value ? value.replace('T', ' ') : '—' }
+function complete() { drawerOpen.value = true }
+function preview(current: string) { photoPreview.value?.open(current, photos.value) }
+</script>
+
+<template>
+  <view class="page detail-page">
+    <AppHeader title="巡检任务详情" />
+    <view v-if="loading" class="state-tip">正在加载...</view>
+    <template v-else-if="task">
+      <view class="patrol-head"><text>{{ task.inspectTaskNo || '—' }}</text><text class="status-pill" :class="Number(task.status) === 1 ? 'green' : ''">{{ Number(task.status) === 1 ? '已完成' : '待巡检' }}</text></view>
+      <view class="page-content">
+        <view class="section card"><view class="section-heading">基本信息</view><view v-for="field in base" :key="field[0]" class="field"><text>{{ field[0] }}</text><text>{{ field[1] }}</text></view></view>
+        <view class="section card"><view class="section-heading">执行结果</view><view class="field"><text>巡检发现问题</text><text>{{ task.problem || '—' }}</text></view><view class="field"><text>处理过程</text><text>{{ task.process || '—' }}</text></view><view class="field photo-field"><text>现场照片</text><view v-if="photos.length" class="photos"><image v-for="url in photos" :key="url" :src="url" mode="aspectFill" @tap="preview(url)" /></view><text v-else class="no-photo">暂无现场照片</text></view></view>
+      </view>
+      <view v-if="Number(task.status) === 0" class="detail-actions"><button @tap="complete">完成巡检</button></view>
+      <InspectCompleteDrawer v-model="drawerOpen" :task-id="taskId" @completed="loadDetail" />
+    </template>
+    <view v-else class="state-tip">巡检任务不存在或无权查看</view>
+    <PhotoPreview ref="photoPreview" />
+  </view>
+</template>
+
+<style scoped lang="scss">
+.detail-page{padding-bottom:125rpx}.state-tip{padding:180rpx 30rpx;color:#8c99a8;text-align:center}.patrol-head{display:flex;align-items:center;justify-content:space-between;gap:18rpx;margin:20rpx 24rpx 0;padding:27rpx;color:#fff;border-radius:18rpx;background:#174e76;font-size:26rpx;font-weight:600}.patrol-head>text:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.section{padding:26rpx;margin-bottom:20rpx}.section-heading{margin-bottom:10rpx;padding:0 0 17rpx 14rpx;color:#263b52;border-bottom:1rpx solid #edf1f5;border-left:7rpx solid #3b5bdb;font-size:29rpx;font-weight:700}.field{display:flex;flex-direction:column;padding:18rpx 0;border-bottom:1rpx solid #edf1f5}.field:last-child{border-bottom:0}.field>text:first-child{margin-bottom:9rpx;color:#909cab;font-size:22rpx}.field>text:last-child{color:#405269;font-size:25rpx;line-height:1.55;word-break:break-all}.photos{display:flex;gap:14rpx;margin-top:6rpx;flex-wrap:wrap}.photos image{width:180rpx;height:150rpx;border-radius:10rpx}.no-photo{color:#9aa6b4!important}.detail-actions{position:fixed;right:0;bottom:0;left:0;z-index:30;padding:16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));background:#fff;box-shadow:0 -5rpx 20rpx rgba(38,59,83,.08)}.detail-actions button{height:82rpx;margin:0;color:#fff;border-radius:999rpx;background:#08264c;font-size:28rpx;line-height:82rpx}
+</style>

+ 86 - 0
src/pages/office/patrol.vue

@@ -0,0 +1,86 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onPullDownRefresh, onReachBottom, onShow } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import { getMobileInspectTaskPage, type InspectTask } from '@/services/inspect-tasks'
+import { navigateTo } from '@/utils/navigation'
+
+const active = ref(0)
+const tasks = ref<InspectTask[]>([])
+const total = ref(0)
+const pageNum = ref(1)
+const loading = ref(false)
+const loaded = ref(false)
+const hasMore = computed(() => tasks.value.length < total.value)
+const tabs = ['全部', '待巡检', '已完成']
+
+onShow(() => loadTasks(true))
+onPullDownRefresh(async () => {
+  await loadTasks(true)
+  uni.stopPullDownRefresh()
+})
+onReachBottom(() => loadTasks())
+
+async function loadTasks(reset = false) {
+  if (loading.value || (!reset && !hasMore.value)) return
+  if (reset) {
+    pageNum.value = 1
+    tasks.value = []
+    total.value = 0
+  }
+  loading.value = true
+  try {
+    const result = await getMobileInspectTaskPage({
+      pageNum: pageNum.value,
+      pageSize: 10,
+      status: active.value === 0 ? undefined : active.value - 1,
+    })
+    tasks.value = reset ? result.records : tasks.value.concat(result.records)
+    total.value = Number(result.total) || 0
+    pageNum.value += 1
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '巡检任务获取失败', icon: 'none' })
+  } finally {
+    loading.value = false
+    loaded.value = true
+  }
+}
+
+function selectTab(index: number) {
+  if (active.value === index) return
+  active.value = index
+  loadTasks(true)
+}
+function statusText(status?: number) { return Number(status) === 1 ? '已完成' : '待巡检' }
+function statusTone(status?: number) { return Number(status) === 1 ? 'green' : '' }
+function formatTime(value?: string) { return value ? value.replace('T', ' ') : '—' }
+function openDetail(item: InspectTask) {
+  navigateTo(`/pages/office/patrol-detail?id=${encodeURIComponent(String(item.inspectTaskId))}`)
+}
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="巡查管理" />
+    <SegmentTabs :model-value="active" :items="tabs" @update:model-value="selectTab" />
+    <view class="result-count">共 {{ total }} 条巡检任务</view>
+    <view class="page-content">
+      <view v-for="item in tasks" :key="item.inspectTaskId" class="task card" @tap="openDetail(item)">
+        <view class="head"><text class="name">{{ item.inspectContent || '未填写巡检内容' }}</text><text class="status-pill" :class="statusTone(item.status)">{{ statusText(item.status) }}</text></view>
+        <view class="row"><text>巡检编号</text><text>{{ item.inspectTaskNo || '—' }}</text></view>
+        <view class="row"><text>巡检人</text><text>{{ item.assignUserName || '—' }}</text></view>
+        <view class="row"><text>计划巡检时间</text><text>{{ formatTime(item.planTime) }}</text></view>
+        <view class="row"><text>实际巡检时间</text><text>{{ formatTime(item.realTime) }}</text></view>
+        <view class="foot"><text class="link">查看详情</text></view>
+      </view>
+      <view v-if="loaded && !tasks.length" class="empty">暂无巡检任务</view>
+      <view v-else-if="loading" class="load-tip">正在加载...</view>
+      <view v-else-if="tasks.length && !hasMore" class="load-tip">已加载全部</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.result-count{padding:14rpx 26rpx 0;color:#8a9aa5;background:#fff;font-size:22rpx}.task{padding:25rpx;margin-bottom:20rpx}.head{display:flex;align-items:center;justify-content:space-between;padding-bottom:19rpx;margin-bottom:8rpx;border-bottom:1rpx solid #edf1f5}.name{flex:1;min-width:0;overflow:hidden;color:#263b52;font-size:30rpx;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.row{display:grid;grid-template-columns:190rpx 1fr;gap:10rpx;padding-top:15rpx;color:#46576b;font-size:24rpx}.row text:first-child{color:#8c99a8}.row text:last-child{text-align:right}.foot{display:flex;align-items:center;justify-content:flex-end;padding-top:20rpx;margin-top:18rpx;border-top:1rpx solid #edf1f5;font-size:25rpx}.link{color:#3b5bdb}.empty,.load-tip{padding:56rpx 0;color:#98a4b2;text-align:center;font-size:23rpx}
+</style>

+ 126 - 0
src/pages/profile/basic.vue

@@ -0,0 +1,126 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import { onShow } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import FormField from '@/components/FormField.vue'
+import { updateUserProfile } from '@/services/profile'
+import { useUserStore } from '@/stores/user'
+
+const userStore = useUserStore()
+const nickname = ref('')
+const phone = ref('')
+const email = ref('')
+const gender = ref('')
+const loading = ref(false)
+const saving = ref(false)
+
+const genderOptions = [
+  { label: '男', value: '0' },
+  { label: '女', value: '1' },
+]
+
+function fillForm() {
+  const user = userStore.profile
+  if (!user) return
+  nickname.value = user.nickName || ''
+  phone.value = user.phonenumber || ''
+  email.value = user.email || ''
+  gender.value = genderOptions.find(item => item.value === user.sex)?.value || ''
+}
+
+async function loadProfile() {
+  if (loading.value) return
+  loading.value = true
+  try {
+    await userStore.fetchProfile()
+    fillForm()
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '个人资料获取失败', icon: 'none' })
+  } finally {
+    loading.value = false
+  }
+}
+
+function changeGender(event: { detail: { value: string } }) {
+  gender.value = event.detail.value
+}
+
+async function save() {
+  if (saving.value) return
+  const trimmedNickname = nickname.value.trim()
+  const trimmedPhone = phone.value.trim()
+  const trimmedEmail = email.value.trim()
+  if (!trimmedNickname || !trimmedPhone || !trimmedEmail) {
+    uni.showToast({ title: '请完整填写个人资料', icon: 'none' })
+    return
+  }
+  if (!/^1[3-9]\d{9}$/.test(trimmedPhone)) {
+    uni.showToast({ title: '请输入正确的手机号码', icon: 'none' })
+    return
+  }
+  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmedEmail)) {
+    uni.showToast({ title: '请输入正确的邮箱地址', icon: 'none' })
+    return
+  }
+
+  if (!genderOptions.some(item => item.value === gender.value)) {
+    uni.showToast({ title: '请选择性别', icon: 'none' })
+    return
+  }
+
+  saving.value = true
+  try {
+    await updateUserProfile({
+      nickName: trimmedNickname,
+      phonenumber: trimmedPhone,
+      email: trimmedEmail,
+      sex: gender.value,
+    })
+    await userStore.fetchProfile()
+    fillForm()
+    uni.showToast({ title: '修改成功', icon: 'success' })
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '修改失败', icon: 'none' })
+  } finally {
+    saving.value = false
+  }
+}
+
+onShow(loadProfile)
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="基本资料" />
+    <view class="page-content">
+      <view class="section-title first-title">个人信息</view>
+      <view class="form card">
+        <FormField v-model="nickname" label="用户昵称" required />
+        <FormField v-model="phone" label="手机号码" required />
+        <FormField v-model="email" label="邮箱" required />
+        <view class="gender-field">
+          <view class="gender-title"><text class="required">*</text>性别</view>
+          <radio-group class="gender-options" @change="changeGender">
+            <label v-for="item in genderOptions" :key="item.value" class="gender-option">
+              <radio :value="item.value" :checked="gender === item.value" :disabled="saving || loading" color="#08264c" />
+              <text>{{ item.label }}</text>
+            </label>
+          </radio-group>
+        </view>
+      </view>
+      <button class="primary-btn save" :loading="saving" :disabled="saving || loading" @tap="save">{{ saving ? '保存中...' : '保存' }}</button>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.first-title{margin-top:6rpx}
+.form{padding:0 25rpx}
+.gender-field{padding:22rpx 0}
+.gender-title{margin-bottom:16rpx;color:#34485f;font-size:27rpx}
+.required{margin-right:6rpx;color:#e34d59}
+.gender-options{display:flex;align-items:center;gap:48rpx}
+.gender-option{display:flex;align-items:center;gap:12rpx;min-height:64rpx;color:#34485f;font-size:28rpx}
+.save{width:100%;margin-top:30rpx}
+.save[disabled]{opacity:.65}
+</style>

Файловите разлики са ограничени, защото са твърде много
+ 110 - 0
src/pages/profile/index.vue


+ 64 - 0
src/pages/profile/login-log.vue

@@ -0,0 +1,64 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import { getMyLoginLogs, type LoginLog } from '@/services/login-logs'
+
+const logs = ref<LoginLog[]>([])
+const total = ref(0)
+const pageNum = ref(0)
+const loading = ref(false)
+const loaded = ref(false)
+const failed = ref(false)
+const retryReset = ref(true)
+const hasMore = computed(() => logs.value.length < total.value)
+
+async function load(reset = false) {
+  if (loading.value || (!reset && !hasMore.value)) return
+  loading.value = true
+  failed.value = false
+  retryReset.value = reset
+  const nextPage = reset ? 1 : pageNum.value + 1
+  try {
+    const result = await getMyLoginLogs(nextPage)
+    logs.value = reset ? result.rows : logs.value.concat(result.rows)
+    total.value = result.total
+    pageNum.value = nextPage
+    loaded.value = true
+  } catch (error) {
+    failed.value = true
+    uni.showToast({ title: error instanceof Error ? error.message : '登录日志获取失败', icon: 'none' })
+  } finally {
+    loading.value = false
+  }
+}
+
+onLoad(() => load(true))
+onPullDownRefresh(async () => {
+  try { await load(true) }
+  finally { uni.stopPullDownRefresh() }
+})
+onReachBottom(() => load())
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="登录日志" />
+    <view class="page-content log-list">
+      <view v-for="item in logs" :key="item.infoId" class="log-card card">
+        <view class="field"><text>IP</text><text class="ip">{{ item.ipaddr || '—' }}</text></view>
+        <view class="field"><text>描述</text><text class="description" :class="{ error: String(item.status) === '1' }">{{ item.msg || (String(item.status) === '0' ? '登录成功' : String(item.status) === '1' ? '登录失败' : '—') }}</text></view>
+        <view class="field"><text>登录时间</text><text>{{ item.loginTime || '—' }}</text></view>
+      </view>
+      <view v-if="loading" class="load-tip">正在加载...</view>
+      <view v-else-if="failed" class="load-tip retry" @tap="load(retryReset)">加载失败,点击重试</view>
+      <view v-else-if="loaded && !logs.length" class="load-tip">暂无登录日志</view>
+      <view v-else-if="logs.length && !hasMore" class="load-tip">已加载全部</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.log-list{padding-top:22rpx}.log-card{padding:7rpx 25rpx;margin-bottom:18rpx}.field{display:grid;grid-template-columns:130rpx 1fr;gap:18rpx;padding:19rpx 0;border-bottom:1rpx solid #edf1f5;color:#43566d;font-size:25rpx}.field:last-child{border-bottom:0}.field>text:first-child{color:#8a97a7}.field>text:last-child{text-align:right}.ip{color:#08264c;font-weight:650}.description{color:#17875b}.description.error{color:#d9363e}
+.field>text:last-child{min-width:0;overflow-wrap:anywhere}.load-tip{padding:32rpx;color:#98a4b2;text-align:center;font-size:23rpx}.retry{color:#3b5bdb}
+</style>

+ 56 - 0
src/pages/profile/password.vue

@@ -0,0 +1,56 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+import AppHeader from '@/components/AppHeader.vue'
+import FormField from '@/components/FormField.vue'
+import { logoutAccount } from '@/services/auth'
+import { updatePassword } from '@/services/profile'
+import { removeToken } from '@/utils/auth'
+import { useUserStore } from '@/stores/user'
+
+const userStore = useUserStore()
+const oldPwd = ref('')
+const newPwd = ref('')
+const confirmPwd = ref('')
+const saving = ref(false)
+
+async function save() {
+  if (saving.value) return
+  if (!oldPwd.value || !newPwd.value || !confirmPwd.value) {
+    uni.showToast({ title: '请完整填写密码信息', icon: 'none' })
+    return
+  }
+  if (newPwd.value.length < 6 || newPwd.value.length > 20) {
+    uni.showToast({ title: '新密码长度应为 6 到 20 个字符', icon: 'none' })
+    return
+  }
+  if (/[<>"'|\\]/.test(newPwd.value)) {
+    uni.showToast({ title: '新密码包含不允许的字符', icon: 'none' })
+    return
+  }
+  if (newPwd.value !== confirmPwd.value) {
+    uni.showToast({ title: '两次输入的新密码不一致', icon: 'none' })
+    return
+  }
+
+  saving.value = true
+  try {
+    await updatePassword(oldPwd.value, newPwd.value)
+    try {
+      await logoutAccount()
+    } catch {
+      // 密码已经修改成功,本地仍应退出并要求重新认证。
+    }
+    removeToken()
+    userStore.clearProfile()
+    uni.showToast({ title: '密码修改成功,请重新登录', icon: 'success' })
+    setTimeout(() => uni.reLaunch({ url: '/pages/login/index' }), 800)
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '密码修改失败', icon: 'none' })
+    saving.value = false
+  }
+}
+</script>
+
+<template><view class="page"><AppHeader title="修改密码" /><view class="page-content"><view class="safe-tip card"><view class="lock">⌑</view><view><text>账号安全提醒</text><text>密码长度为 6–20 位,建议包含字母和数字。</text></view></view><view class="section-title">密码设置</view><view class="form card"><FormField v-model="oldPwd" label="旧密码" required password placeholder="请输入当前登录密码" /><FormField v-model="newPwd" label="新密码" required password placeholder="请输入新密码" /><FormField v-model="confirmPwd" label="确认密码" required password placeholder="请再次输入新密码" /></view><button class="primary-btn save" :loading="saving" :disabled="saving" @tap="save">{{ saving ? '修改中...' : '确认修改' }}</button></view></view></template>
+
+<style scoped lang="scss">.safe-tip{display:flex;align-items:center;padding:24rpx;background:#edf6ff}.lock{display:flex;align-items:center;justify-content:center;width:67rpx;height:67rpx;margin-right:18rpx;color:#257ce5;border-radius:18rpx;background:#dcecff;font-size:36rpx}.safe-tip>view:last-child{display:flex;flex:1;flex-direction:column;color:#355e8c;font-weight:600}.safe-tip view text:last-child{margin-top:8rpx;color:#6886a7;font-size:22rpx;font-weight:400}.form{padding:0 25rpx}.save{width:100%;margin-top:30rpx}.save[disabled]{opacity:.65}</style>

+ 5 - 0
src/pages/profile/warnings.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts">
+import BusinessListPage from '@/components/BusinessListPage.vue'
+import { warnings } from '@/data/mock'
+</script>
+<template><BusinessListPage title="预警管理" :items="warnings" :tabs="['全部','已接收','处理中','已处置','已解除']" detail-path="/pages/message/warning-detail" id-label="预警编号" placeholder="请输入预警编号或描述" /></template>

+ 75 - 0
src/pages/profile/workorders.vue

@@ -0,0 +1,75 @@
+<script setup lang="ts">
+import { computed, ref, watch } from 'vue'
+import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
+import AppHeader from '@/components/AppHeader.vue'
+import SearchBar from '@/components/SearchBar.vue'
+import SegmentTabs from '@/components/SegmentTabs.vue'
+import BusinessCard from '@/components/BusinessCard.vue'
+import { getMobileWorkOrders, workOrderStatusText, workOrderTone, type WorkOrder } from '@/services/workorders'
+import type { ListItem } from '@/data/mock'
+import { navigateTo } from '@/utils/navigation'
+
+const tabs = [
+  { label: '全部', status: '' }, { label: '待派单', status: '0' }, { label: '待接单', status: '1' },
+  { label: '处理中', status: '2,3,6' }, { label: '待验收', status: '4' }, { label: '已结案', status: '5' }, { label: '已取消', status: '7' },
+]
+const active = ref(0)
+const keyword = ref('')
+const records = ref<WorkOrder[]>([])
+const total = ref(0)
+const pageNum = ref(1)
+const loading = ref(false)
+const loaded = ref(false)
+const hasMore = computed(() => records.value.length < total.value)
+
+function card(order: WorkOrder): ListItem {
+  const device = order.deviceId ? `${order.deviceCode || '—'}${order.deviceName ? `(${order.deviceName})` : ''}` : '未关联设备'
+  return { id: order.orderNo, title: order.orderDesc || '故障工单', status: workOrderStatusText(order.orderStatus), tone: workOrderTone(order.orderStatus), fields: [
+    { label: '工单描述', value: order.orderDesc || '—' }, { label: '设备信息', value: device }, { label: '安装位置', value: order.deviceLocation || '—' },
+  ] }
+}
+
+async function load(reset = false) {
+  if (loading.value || (!reset && !hasMore.value)) return
+  if (reset) { pageNum.value = 1; records.value = [] }
+  loading.value = true
+  try {
+    const page = await getMobileWorkOrders({ pageNum: pageNum.value, pageSize: 10, keyword: keyword.value.trim() || undefined, orderStatus: tabs[active.value].status || undefined })
+    records.value = reset ? page.records : [...records.value, ...page.records]
+    total.value = Number(page.total) || 0
+    if (records.value.length < total.value) pageNum.value += 1
+  } catch (error) {
+    uni.showToast({ title: error instanceof Error ? error.message : '工单获取失败', icon: 'none' })
+  } finally { loading.value = false; loaded.value = true }
+}
+
+function openDetail(orderId: number) { navigateTo(`/pages/message/workorder-detail?id=${orderId}`) }
+
+async function refresh() {
+  await load(true)
+  uni.stopPullDownRefresh()
+}
+
+watch(active, () => load(true))
+onLoad(() => load(true))
+onPullDownRefresh(refresh)
+onReachBottom(() => load())
+</script>
+
+<template>
+  <view class="page">
+    <AppHeader title="工单管理" />
+    <scroll-view class="tabs-scroll" scroll-x><SegmentTabs v-model="active" :items="tabs.map(item => item.label)" /></scroll-view>
+    <SearchBar v-model="keyword" attached placeholder="请输入工单编号、设备编码或描述" @search="load(true)" />
+    <view class="filter-bar"><text>共 {{ total }} 条</text></view>
+    <view class="page-content list-content">
+      <BusinessCard v-for="order in records" :key="order.orderId" :item="card(order)" id-label="工单编号" @open="openDetail(order.orderId)" />
+      <view v-if="loaded && !records.length" class="empty"><text class="empty-icon">⌕</text><text>暂无工单</text></view>
+      <view v-else-if="loading" class="load-tip">正在加载...</view><view v-else-if="records.length && !hasMore" class="load-tip">已加载全部</view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.tabs-scroll{width:100%;white-space:nowrap;background:#fff}.filter-bar{display:flex;align-items:center;justify-content:space-between;padding:0 26rpx 16rpx;color:#8a97a7;background:#fff;font-size:23rpx}.list-content{padding-top:22rpx}.empty{display:flex;flex-direction:column;align-items:center;padding:120rpx 0;color:#9aa6b4}.empty-icon{margin-bottom:15rpx;font-size:70rpx}.load-tip{padding:28rpx;color:#98a4b2;text-align:center;font-size:23rpx}
+</style>

+ 70 - 0
src/services/alarms.ts

@@ -0,0 +1,70 @@
+import { ApiError, getApiUrl, requestApi, type ApiResponse } from './api'
+import { getToken } from '@/utils/auth'
+
+export interface Alarm {
+  id: string
+  alarmNo?: string
+  deviceName?: string
+  deviceCode?: string
+  alarmContent?: string
+  alarmLevel?: number
+  alarmLevelName?: string
+  auditStatus?: number
+  auditStatusName?: string
+  alarmStatus?: number
+  monitorStatusName?: string
+  orderStatusName?: string
+  equipmentLocation?: string
+  equipmentImage?: string
+  actualValue?: number | string
+  minValue?: number | string
+  maxValue?: number | string
+  warningUnit?: string
+  createTime?: string
+  workOrderId?: string | number
+  orderNo?: string
+  receiveUserName?: string
+  planFinishTime?: string
+}
+export interface AlarmLog {
+  logId: string | number
+  operTime?: string
+  operUserName?: string
+  operTypeName?: string
+  operDesc?: string
+  attachUrl?: string
+}
+interface DataResponse<T> extends ApiResponse { data: T }
+const BASE = '/api/mobile/alarm'
+export function getMobileAlarms(params: { pageNum: number; pageSize: number; keyword?: string; alarmLevel?: number; auditStatus?: number }) {
+  return requestApi<DataResponse<{ records: Alarm[]; total: number }>>(BASE, { data: params }).then(r => r.data)
+}
+export const getMobileAlarm = (id: string) => requestApi<DataResponse<Alarm>>(`${BASE}/${encodeURIComponent(id)}`).then(r => r.data)
+export const getMobileAlarmLogs = (id: string) => requestApi<DataResponse<AlarmLog[]>>(`${BASE}/${encodeURIComponent(id)}/logs`).then(r => r.data)
+export function reviewMobileAlarm(id: string, data: { auditStatus: number; opinion: string; attachmentTokens: string[] }) {
+  return requestApi<DataResponse<Alarm>>(`${BASE}/${encodeURIComponent(id)}/reviews`, { method: 'POST', data }).then(r => r.data)
+}
+export function uploadAlarmAttachment(id: string, path: string): Promise<string> {
+  return new Promise((resolve, reject) => {
+    uni.uploadFile({
+      url: getApiUrl(`${BASE}/${encodeURIComponent(id)}/attachments`), filePath: path, name: 'file',
+      header: { Authorization: `Bearer ${getToken()}` }, timeout: 60000,
+      success(response) {
+        try {
+          const result = JSON.parse(response.data) as DataResponse<{ token: string }>
+          if (response.statusCode >= 200 && response.statusCode < 300 && (result.code ?? 200) === 200 && result.data?.token) resolve(result.data.token)
+          else reject(new ApiError(result.msg || '图片上传失败', result.code))
+        } catch { reject(new ApiError('图片上传响应异常')) }
+      },
+      fail() { reject(new ApiError('图片上传失败,请重试')) },
+    })
+  })
+}
+export function alarmPhotos(value?: string) {
+  return (value || '').split(',').map(v => v.trim()).filter(Boolean)
+    .map(path => /^(https?:|data:|blob:)/.test(path) ? path : getApiUrl(path))
+}
+export const alarmAuditText = (alarm: Alarm) => alarm.auditStatus === 0 ? '待核实' : alarm.auditStatusName || ({ 1: '确认报警', 2: '误报警' }[Number(alarm.auditStatus)] || '未知结果')
+export const alarmAuditTone = (status?: number) => status === 0 ? 'orange' : status === 1 ? '' : 'gray'
+export const alarmLevelTone = (level?: number) => ({ 1: 'red', 2: 'orange', 3: '', 4: 'green' }[Number(level)] || '')
+export const alarmTime = (value?: string) => value?.replace('T', ' ') || '—'

+ 81 - 0
src/services/api.ts

@@ -0,0 +1,81 @@
+import { getToken, removeToken } from '@/utils/auth'
+
+export interface ApiResponse {
+  code?: number
+  msg?: string
+  message?: string
+  [key: string]: unknown
+}
+
+export interface RequestConfig {
+  method?: UniApp.RequestOptions['method']
+  data?: UniApp.RequestOptions['data']
+  header?: UniApp.RequestOptions['header']
+  timeout?: number
+  auth?: boolean
+}
+
+export class ApiError extends Error {
+  code?: number
+
+  constructor(message: string, code?: number) {
+    super(message)
+    this.name = 'ApiError'
+    this.code = code
+  }
+}
+
+const baseApi = import.meta.env.VITE_APP_BASE_API || '/dev-api'
+const apiOrigin = (import.meta.env.VITE_APP_API_ORIGIN || '').replace(/\/$/, '')
+const baseUrl = `${apiOrigin}${baseApi.startsWith('/') ? baseApi : `/${baseApi}`}`.replace(/\/$/, '')
+
+export function getApiUrl(url: string) {
+  return `${baseUrl}${url.startsWith('/') ? url : `/${url}`}`
+}
+
+function getErrorMessage(error: UniApp.GeneralCallbackResult) {
+  const detail = error.errMsg || ''
+  if (detail.includes('timeout')) return '系统接口请求超时'
+  return '后端接口连接异常'
+}
+
+export function requestApi<T extends ApiResponse>(url: string, config: RequestConfig = {}): Promise<T> {
+  const token = getToken()
+  const header: Record<string, string> = {
+    'Content-Type': 'application/json;charset=utf-8',
+    ...(config.header as Record<string, string> | undefined),
+  }
+
+  if (config.auth !== false && token) {
+    header.Authorization = `Bearer ${token}`
+  }
+
+  return new Promise((resolve, reject) => {
+    uni.request({
+      url: getApiUrl(url),
+      method: config.method || 'GET',
+      data: config.data,
+      header,
+      timeout: config.timeout || 10000,
+      success(response) {
+        if (response.statusCode < 200 || response.statusCode >= 300) {
+          reject(new ApiError(`系统接口 ${response.statusCode} 异常`, response.statusCode))
+          return
+        }
+
+        const result = response.data as T
+        const code = result.code ?? 200
+        if (code === 200) {
+          resolve(result)
+          return
+        }
+
+        if (code === 401) removeToken()
+        reject(new ApiError(result.msg || result.message || '系统接口请求失败', code))
+      },
+      fail(error) {
+        reject(new ApiError(getErrorMessage(error)))
+      },
+    })
+  })
+}

+ 71 - 0
src/services/auth.ts

@@ -0,0 +1,71 @@
+import { requestApi, type ApiResponse } from './api'
+
+export interface CaptchaResponse extends ApiResponse {
+  captchaEnabled?: boolean
+  img?: string
+  uuid?: string
+}
+
+export interface LoginPayload {
+  username: string
+  password: string
+  code: string
+  uuid: string
+}
+
+export interface LoginResponse extends ApiResponse {
+  token?: string
+}
+
+export interface UserRole {
+  roleId?: number
+  roleKey?: string
+  roleName?: string
+}
+
+export interface UserDepartment {
+  deptId?: number
+  deptName?: string
+}
+
+export interface UserProfile {
+  userId?: number
+  deptId?: number
+  userName?: string
+  nickName?: string
+  email?: string
+  phonenumber?: string
+  sex?: string
+  avatar?: string
+  dept?: UserDepartment
+  roles?: UserRole[]
+}
+
+export interface UserInfoResponse extends ApiResponse {
+  user: UserProfile
+  roles?: string[]
+  permissions?: string[]
+}
+
+export function getCaptcha() {
+  return requestApi<CaptchaResponse>('/captchaImage', {
+    auth: false,
+    timeout: 20000,
+  })
+}
+
+export function loginAccount(payload: LoginPayload) {
+  return requestApi<LoginResponse>('/login', {
+    method: 'POST',
+    data: payload,
+    auth: false,
+  })
+}
+
+export function logoutAccount() {
+  return requestApi<ApiResponse>('/logout', { method: 'POST' })
+}
+
+export function getInfo() {
+  return requestApi<UserInfoResponse>('/getInfo')
+}

+ 20 - 0
src/services/contacts.ts

@@ -0,0 +1,20 @@
+import { requestApi, type ApiResponse } from './api'
+
+export interface ContactUser {
+  userId?: number
+  nickName?: string
+  phonenumber?: string
+  deptId?: number
+  deptName?: string
+  postIds?: number[]
+  postNames?: string[]
+}
+
+interface ContactsResponse extends ApiResponse {
+  data?: ContactUser[]
+}
+
+export async function getContacts() {
+  const response = await requestApi<ContactsResponse>('/api/mobile/contacts')
+  return Array.isArray(response.data) ? response.data : []
+}

+ 77 - 0
src/services/equipment.ts

@@ -0,0 +1,77 @@
+import { requestApi } from './api'
+import type { ApiResponse } from './api'
+
+export interface Equipment {
+  equipmentId: string
+  equipmentCode?: string
+  equipmentName?: string
+  equipmentModel?: string
+  equipmentSpec?: string
+  manufacturer?: string
+  district?: number
+  productionDate?: string
+  equipmentTypeId?: string | number
+  equipmentTypeName?: string
+  assetValue?: number
+  useLife?: number
+  longitude?: number
+  latitude?: number
+  equipmentLocation?: string
+  installTime?: string
+  maintainer?: string
+  maintainerPhone?: string
+  ownershipUnit?: string
+  remark?: string
+  equipmentImage?: string
+  currentStatus?: number
+  alarmStatus?: number
+  onlineStatus?: number
+}
+
+export interface EquipmentPage {
+  records: Equipment[]
+  total: number
+  current: number
+  size: number
+}
+
+export interface EquipmentStatus {
+  currentStatus?: number
+  alarmStatus?: number
+  onlineStatus?: number
+  statusUpdateTime?: string
+}
+
+export interface EquipmentType {
+  id?: number
+  typeName?: string
+  parentId?: number
+}
+
+export interface EquipmentDetail {
+  equipmentInfo: Equipment
+  typeInfo?: EquipmentType
+  statusInfo?: EquipmentStatus
+  thresholdList?: unknown[]
+}
+
+interface DataResponse<T> extends ApiResponse {
+  data: T
+}
+
+const BASE = '/api/mobile/equipment-base'
+
+export function getMobileEquipmentPage(params: {
+  pageNum: number
+  pageSize: number
+  keyword?: string
+    rootTypeId?: number
+  onlineStatus?: number
+  alarmStatus?: number
+}) {
+  return requestApi<DataResponse<EquipmentPage>>(`${BASE}`, { data: params }).then(result => result.data)
+}
+
+export function getMobileEquipmentDetail(id: string) {
+  return requestApi<DataResponse<EquipmentDetail>>(`${BASE}/${encodeURIComponent(id)}`).then(result => result.data)
+}

+ 89 - 0
src/services/inspect-tasks.ts

@@ -0,0 +1,89 @@
+import { ApiError, getApiUrl, requestApi, type ApiResponse } from './api'
+import { getToken } from '@/utils/auth'
+
+export interface InspectTask {
+  inspectTaskId: number
+  inspectTaskNo?: string
+  inspectContent?: string
+  assignUserId?: number
+  assignUserName?: string
+  planTime?: string
+  realTime?: string
+  problem?: string
+  process?: string
+  photoUrl?: string
+  photoList?: string[]
+  attachmentBaseUrl?: string
+  status?: number
+}
+
+export interface InspectTaskPage {
+  records: InspectTask[]
+  total: number
+  current?: number
+  size?: number
+  pages?: number
+}
+
+export interface InspectTaskQuery {
+  pageNum: number
+  pageSize: number
+  keyword?: string
+  status?: number
+}
+
+interface DataResponse<T> extends ApiResponse { data: T }
+interface UploadResponse extends ApiResponse { relativePath?: string; url?: string }
+
+const BASE = '/api/mobile/ops/inspectTask'
+
+export function getMobileInspectTaskPage(params: InspectTaskQuery) {
+  return requestApi<DataResponse<InspectTaskPage>>(`${BASE}/findByPage`, { data: params })
+    .then(result => result.data)
+}
+
+export function getMobileInspectTaskDetail(id: number) {
+  return requestApi<DataResponse<InspectTask>>(`${BASE}/${id}`).then(result => result.data)
+}
+
+export function completeMobileInspectTask(data: {
+  inspectTaskId: number
+  realTime: string
+  problem?: string
+  process?: string
+  photoUrl: string
+}) {
+  return requestApi<ApiResponse>(`${BASE}/complete`, { method: 'PUT', data })
+}
+
+export function uploadInspectTaskPhoto(filePath: string): Promise<string> {
+  return new Promise((resolve, reject) => {
+    uni.uploadFile({
+      url: `${getApiUrl('/minio/upload')}?dir=inspectTask`,
+      filePath,
+      name: 'file',
+      header: { Authorization: `Bearer ${getToken()}` },
+      timeout: 30000,
+      success(response) {
+        try {
+          const result = JSON.parse(response.data) as UploadResponse
+          if (response.statusCode >= 200 && response.statusCode < 300 && (result.code ?? 200) === 200 && result.relativePath) {
+            resolve(result.relativePath)
+          } else {
+            reject(new ApiError(result.msg || result.message || '现场照片上传失败', result.code))
+          }
+        } catch {
+          reject(new ApiError('现场照片上传响应格式异常'))
+        }
+      },
+      fail(error) {
+        reject(new ApiError(error.errMsg?.includes('timeout') ? '现场照片上传超时' : '现场照片上传失败'))
+      },
+    })
+  })
+}
+
+export function resolveInspectTaskPhoto(path: string, baseUrl?: string) {
+  if (/^(https?:|data:|blob:)/.test(path)) return path
+  return `${(baseUrl || '').replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`
+}

+ 21 - 0
src/services/login-logs.ts

@@ -0,0 +1,21 @@
+import { requestApi, type ApiResponse } from './api'
+
+export interface LoginLog {
+  infoId: number | string
+  ipaddr?: string
+  status?: string
+  msg?: string
+  loginTime?: string
+}
+
+interface LoginLogListResponse extends ApiResponse {
+  rows?: LoginLog[]
+  total?: number
+}
+
+export async function getMyLoginLogs(pageNum = 1, pageSize = 10) {
+  const response = await requestApi<LoginLogListResponse>('/api/mobile/monitor/logininfor/list', {
+    data: { pageNum, pageSize },
+  })
+  return { rows: response.rows || [], total: Number(response.total) || 0 }
+}

+ 56 - 0
src/services/notices.ts

@@ -0,0 +1,56 @@
+import { requestApi, type ApiResponse } from './api'
+
+export interface SystemNotice {
+  noticeId: number
+  noticeTitle: string
+  noticeType?: string
+  noticeContent?: string
+  status?: string
+  createBy?: string
+  createTime?: string
+  updateTime?: string
+  remark?: string
+}
+
+export interface NoticeListParams {
+  pageNum?: number
+  pageSize?: number
+  noticeType?: string
+  noticeTitle?: string
+  status?: string
+}
+
+interface NoticeListResponse extends ApiResponse {
+  rows?: SystemNotice[]
+  total?: number
+}
+
+interface NoticeDetailResponse extends ApiResponse {
+  data?: SystemNotice
+}
+
+export async function getNoticeList(params: NoticeListParams = {}) {
+  const response = await requestApi<NoticeListResponse>('/api/mobile/notice/list', {
+    data: {
+      pageNum: params.pageNum || 1,
+      pageSize: params.pageSize || 20,
+      status: params.status ?? '0',
+      noticeType: params.noticeType,
+      noticeTitle: params.noticeTitle,
+    },
+  })
+
+  return {
+    rows: response.rows || [],
+    total: response.total || 0,
+  }
+}
+
+export async function getNoticeDetail(noticeId: number | string) {
+  const response = await requestApi<NoticeDetailResponse>(`/api/mobile/notice/${encodeURIComponent(noticeId)}`)
+  return response.data
+}
+
+export function getNoticeTypeLabel(noticeType?: string) {
+  return noticeType === '2' ? '公告' : '通知'
+}

+ 14 - 0
src/services/office.ts

@@ -0,0 +1,14 @@
+import { requestApi, type ApiResponse } from './api'
+
+export interface OfficeSummary {
+  equipmentTotal: number
+  equipmentOffline: number
+  equipmentAlarming: number
+  alarmPending: number
+  alarmAddedToday: number
+  inspectPending: number
+}
+
+export function getMobileOfficeSummary() {
+  return requestApi<ApiResponse & { data: OfficeSummary }>('/api/mobile/office/summary').then(result => result.data)
+}

+ 65 - 0
src/services/profile.ts

@@ -0,0 +1,65 @@
+import { ApiError, getApiUrl, requestApi, type ApiResponse } from './api'
+import type { UserProfile } from './auth'
+import { getToken } from '@/utils/auth'
+
+export interface UpdateProfilePayload {
+  nickName: string
+  phonenumber: string
+  email: string
+  sex: string
+}
+
+export interface AvatarResponse extends ApiResponse {
+  imgUrl?: string
+}
+
+export function updateUserProfile(payload: UpdateProfilePayload) {
+  return requestApi<ApiResponse>('/system/user/profile', {
+    method: 'PUT',
+    data: payload,
+  })
+}
+
+export function updatePassword(oldPassword: string, newPassword: string) {
+  return requestApi<ApiResponse>('/system/user/profile/updatePwd', {
+    method: 'PUT',
+    data: { oldPassword, newPassword },
+  })
+}
+
+export function uploadAvatar(filePath: string): Promise<AvatarResponse> {
+  return new Promise((resolve, reject) => {
+    uni.uploadFile({
+      url: getApiUrl('/system/user/profile/avatar'),
+      filePath,
+      name: 'avatarfile',
+      header: { Authorization: `Bearer ${getToken()}` },
+      timeout: 20000,
+      success(response) {
+        if (response.statusCode < 200 || response.statusCode >= 300) {
+          reject(new ApiError(`系统接口 ${response.statusCode} 异常`, response.statusCode))
+          return
+        }
+
+        try {
+          const result = JSON.parse(response.data) as AvatarResponse
+          const code = result.code ?? 200
+          if (code === 200) resolve(result)
+          else reject(new ApiError(result.msg || result.message || '头像上传失败', code))
+        } catch {
+          reject(new ApiError('头像上传响应格式异常'))
+        }
+      },
+      fail(error) {
+        const message = error.errMsg?.includes('timeout') ? '头像上传超时' : '头像上传失败'
+        reject(new ApiError(message))
+      },
+    })
+  })
+}
+
+export function resolveAvatarUrl(avatar?: UserProfile['avatar']) {
+  if (!avatar) return ''
+  if (/^(https?:|data:|blob:)/.test(avatar)) return avatar
+  return getApiUrl(avatar)
+}

+ 141 - 0
src/services/workorders.ts

@@ -0,0 +1,141 @@
+import { ApiError, getApiUrl, requestApi, type ApiResponse } from './api'
+import { getToken } from '@/utils/auth'
+
+export interface WorkOrder {
+  orderId: number
+  orderNo: string
+  deviceId?: string
+  deviceCode?: string
+  deviceName?: string
+  deviceTypeName?: string
+  deviceLocation?: string
+  orderLevel?: number
+  orderDesc?: string
+  orderStatus: number
+  delayApplyStatus?: number
+  delayedReason?: string
+  delayedDeadline?: string
+  faultTime?: string
+  planFinishTime?: string
+  realFinishTime?: string
+  repairResult?: string
+  maintenanceBeforeImg?: string
+  maintenanceAfterImg?: string
+  receiveUser?: number
+  receiveUserName?: string
+  verifyUser?: number
+  createBy?: number
+  createTime?: string
+}
+
+export interface WorkOrderLog {
+  logId: number
+  operType?: number
+  operTypeDesc?: string
+  operDesc?: string
+  operUserName?: string
+  operTime?: string
+  attachList?: string[]
+}
+
+export interface WorkOrderDetail {
+  order: WorkOrder
+  logs: WorkOrderLog[]
+  attachmentBaseUrl?: string
+}
+
+export interface PageResult<T> {
+  records: T[]
+  total: number
+  current: number
+  size: number
+  pages?: number
+}
+
+export interface WorkOrderQuery {
+  pageNum?: number
+  pageSize?: number
+  orderStatus?: string
+  keyword?: string
+  orderLevel?: number
+}
+
+export interface AssignableUser {
+  userId: number
+  nickName: string
+  deptId?: number
+  deptName?: string
+}
+
+interface DataResponse<T> extends ApiResponse { data: T }
+interface UploadResponse extends ApiResponse { relativePath?: string; url?: string }
+
+const BASE = '/api/ops/workOrder'
+const MOBILE_BASE = '/api/mobile/ops/workOrder'
+
+export const workOrderStatusText = (status?: number) => ['待派单', '待接单', '已接单', '处理中', '待验收', '已结案', '延期中', '已取消'][Number(status)] || '未知'
+export const workOrderLevelText = (level?: number) => ['紧急', '一般', '低'][Number(level)] || '—'
+export const workOrderTone = (status?: number) => status === 0 ? 'orange' : status === 3 || status === 6 ? 'purple' : status === 4 || status === 5 ? 'green' : status === 7 ? 'gray' : ''
+
+export function getMobileWorkOrders(query: WorkOrderQuery = {}) {
+  return requestApi<DataResponse<PageResult<WorkOrder>>>(`${MOBILE_BASE}`, { data: query }).then(result => result.data)
+}
+
+export function getMobilePendingWorkOrders(query: WorkOrderQuery = {}) {
+  return requestApi<DataResponse<PageResult<WorkOrder>>>(`${MOBILE_BASE}/pending`, { data: query }).then(result => result.data)
+}
+
+export function getMobileWorkOrderDetail(orderId: number) {
+  return requestApi<DataResponse<WorkOrderDetail>>(`${MOBILE_BASE}/${orderId}`).then(result => result.data)
+}
+
+export function getAssignableUsers(type: 'handler' | 'reviewer') {
+  return requestApi<DataResponse<AssignableUser[]>>(`${MOBILE_BASE}/assignable/users`, { data: { type } }).then(result => result.data)
+}
+
+function operate(orderId: number, action: string, data: Record<string, unknown>) {
+  return requestApi<ApiResponse>(`${BASE}/${orderId}/${action}`, { method: 'PUT', data })
+}
+
+export const dispatchWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'dispatch', data)
+export const acceptWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'accept', data)
+export const processWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'process', data)
+export const submitVerifyWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'submitVerify', data)
+export const verifyWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'verify', data)
+export const cancelWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'cancel', data)
+export const applyDelayWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'delay/apply', data)
+export const auditDelayWorkOrder = (id: number, data: Record<string, unknown>) => operate(id, 'delay/audit', data)
+
+export function uploadWorkOrderFile(filePath: string): Promise<string> {
+  return new Promise((resolve, reject) => {
+    uni.uploadFile({
+      url: `${getApiUrl('/minio/upload')}?dir=workOrder`,
+      filePath,
+      name: 'file',
+      header: { Authorization: `Bearer ${getToken()}` },
+      timeout: 30000,
+      success(response) {
+        try {
+          const result = JSON.parse(response.data) as UploadResponse
+          if (response.statusCode >= 200 && response.statusCode < 300 && (result.code ?? 200) === 200 && result.relativePath) {
+            resolve(result.relativePath)
+          } else {
+            reject(new ApiError(result.msg || result.message || '附件上传失败', result.code))
+          }
+        } catch {
+          reject(new ApiError('附件上传响应格式异常'))
+        }
+      },
+      fail(error) { reject(new ApiError(error.errMsg?.includes('timeout') ? '附件上传超时' : '附件上传失败')) },
+    })
+  })
+}
+
+export function splitAttachments(value?: string) {
+  return value ? value.split(',').map(item => item.trim()).filter(Boolean) : []
+}
+
+export function resolveAttachmentUrl(path: string, baseUrl?: string) {
+  if (/^(https?:|data:|blob:)/.test(path)) return path
+  return `${(baseUrl || '').replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`
+}

BIN
src/static/tabbar/contacts-active.png


+ 1 - 0
src/static/tabbar/contacts-active.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#08264c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2.5"/><circle cx="9" cy="10.5" r="2"/><path d="M6 15.8c.7-1.3 1.8-1.9 3-1.9s2.3.6 3 1.9M15 9.5h3.5M15 13.5h3.5"/></svg>

BIN
src/static/tabbar/contacts.png


+ 1 - 0
src/static/tabbar/contacts.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#7f8c9e" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2.5"/><circle cx="9" cy="10.5" r="2"/><path d="M6 15.8c.7-1.3 1.8-1.9 3-1.9s2.3.6 3 1.9M15 9.5h3.5M15 13.5h3.5"/></svg>

BIN
src/static/tabbar/emergency-active.png


+ 1 - 0
src/static/tabbar/emergency-active.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#08264c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><path d="M12 9v4M12 17h.01"/></svg>

BIN
src/static/tabbar/emergency.png


+ 1 - 0
src/static/tabbar/emergency.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#7f8c9e" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><path d="M12 9v4M12 17h.01"/></svg>

BIN
src/static/tabbar/message-active.png


+ 1 - 0
src/static/tabbar/message-active.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#08264c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>

BIN
src/static/tabbar/message.png


+ 1 - 0
src/static/tabbar/message.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#7f8c9e" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>

BIN
src/static/tabbar/office-active.png


+ 1 - 0
src/static/tabbar/office-active.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#08264c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1.2"/><path d="M9 12h6M9 16h4"/></svg>

BIN
src/static/tabbar/office.png


+ 1 - 0
src/static/tabbar/office.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#7f8c9e" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1.2"/><path d="M9 12h6M9 16h4"/></svg>

BIN
src/static/tabbar/profile-active.png


+ 1 - 0
src/static/tabbar/profile-active.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#08264c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="3.6"/><path d="M5.5 20a6.5 6.5 0 0 1 13 0"/></svg>

BIN
src/static/tabbar/profile.png


+ 1 - 0
src/static/tabbar/profile.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="81" height="81" viewBox="0 0 24 24" fill="none" stroke="#7f8c9e" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="3.6"/><path d="M5.5 20a6.5 6.5 0 0 1 13 0"/></svg>

+ 24 - 0
src/stores/user.ts

@@ -0,0 +1,24 @@
+import { reactive } from 'vue'
+import { getInfo, type UserProfile } from '@/services/auth'
+
+const userStore = reactive({
+  profile: null as UserProfile | null,
+  roles: [] as string[],
+  permissions: [] as string[],
+  async fetchProfile() {
+    const response = await getInfo()
+    userStore.profile = response.user
+    userStore.roles = response.roles || []
+    userStore.permissions = response.permissions || []
+    return response.user
+  },
+  clearProfile() {
+    userStore.profile = null
+    userStore.roles = []
+    userStore.permissions = []
+  },
+})
+
+export function useUserStore() {
+  return userStore
+}

+ 76 - 0
src/styles/global.scss

@@ -0,0 +1,76 @@
+$primary: #08264c;
+
+*, *::before, *::after { box-sizing: border-box; }
+
+// clip 限制横向溢出,同时保留页面纵向滚动,避免 H5 页面触底事件失效。
+html, body, #app, uni-app, uni-page, uni-page-wrapper, uni-page-body {
+  width: 100%;
+  max-width: 100%;
+  margin: 0;
+  overflow-x: clip;
+}
+
+page {
+  min-height: 100%;
+  background: #f3f6fa;
+  color: #26364d;
+  font-size: 28rpx;
+}
+
+view, text, input, textarea, button, scroll-view { box-sizing: border-box; }
+button { border-radius: 999rpx; }
+button::after { border: 0; }
+
+.page { min-height: 100vh; background: #f3f6fa; }
+.page-content { padding: 24rpx 24rpx calc(34rpx + env(safe-area-inset-bottom)); }
+.page-content.with-tabs { padding-top: 0; }
+.card {
+  background: #fff;
+  border-radius: 20rpx;
+  box-shadow: 0 5rpx 22rpx rgba(37, 65, 96, 0.07);
+}
+.section-title {
+  display: flex;
+  align-items: center;
+  margin: 30rpx 0 20rpx;
+  font-size: 31rpx;
+  font-weight: 650;
+  color: #20324a;
+}
+.section-title::before {
+  content: '';
+  width: 7rpx;
+  height: 30rpx;
+  margin-right: 13rpx;
+  border-radius: 7rpx;
+  background: linear-gradient(180deg, #123f68, #08264c);
+}
+.muted { color: #8b99ab; }
+.link { color: $primary; }
+.primary-btn, .ghost-btn {
+  height: 84rpx;
+  border-radius: 999rpx;
+  font-size: 30rpx;
+  line-height: 84rpx;
+}
+.primary-btn { color: #fff; background: linear-gradient(135deg, #123f68, #08264c); box-shadow: 0 10rpx 24rpx rgba(8, 38, 76, .22); }
+.ghost-btn { color: #4e6075; background: #fff; border: 1rpx solid #dbe3ec; }
+.two-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 20rpx; margin-top: 30rpx; }
+.status-pill {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  min-width: 90rpx;
+  padding: 7rpx 17rpx;
+  border-radius: 999rpx;
+  color: #0d4c7d;
+  background: #e8eff6;
+  font-size: 23rpx;
+  white-space: nowrap;
+}
+.status-pill.red { color: #d9363e; background: #fff0f0; }
+.status-pill.orange { color: #d66a06; background: #fff5e6; }
+.status-pill.green { color: #17875b; background: #e8f8ef; }
+.status-pill.gray { color: #718096; background: #eef2f6; }
+.status-pill.purple { color: #7057c7; background: #f0edff; }
+.empty-safe { height: env(safe-area-inset-bottom); }

+ 13 - 0
src/utils/auth.ts

@@ -0,0 +1,13 @@
+const TOKEN_KEY = 'Admin-Token'
+
+export function getToken(): string {
+  return uni.getStorageSync(TOKEN_KEY) || ''
+}
+
+export function setToken(token: string) {
+  uni.setStorageSync(TOKEN_KEY, token)
+}
+
+export function removeToken() {
+  uni.removeStorageSync(TOKEN_KEY)
+}

+ 13 - 0
src/utils/navigation.ts

@@ -0,0 +1,13 @@
+export function navigateTo(url: string) {
+  uni.navigateTo({ url })
+}
+
+export function navigateBack() {
+  const pages = getCurrentPages()
+  if (pages.length > 1) uni.navigateBack()
+  else uni.switchTab({ url: '/pages/message/index' })
+}
+
+export function showStaticToast(title = '静态演示,接口将在下一阶段接入') {
+  uni.showToast({ title, icon: 'none' })
+}

+ 17 - 0
tsconfig.json

@@ -0,0 +1,17 @@
+{
+  "compilerOptions": {
+    "target": "ESNext",
+    "module": "ESNext",
+    "moduleResolution": "Bundler",
+    "strict": true,
+    "jsx": "preserve",
+    "resolveJsonModule": true,
+    "esModuleInterop": true,
+    "allowSyntheticDefaultImports": true,
+    "lib": ["ESNext", "DOM"],
+    "types": ["@dcloudio/types", "vite/client"],
+    "baseUrl": ".",
+    "paths": { "@/*": ["src/*"] }
+  },
+  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
+}

+ 19 - 0
vite.config.ts

@@ -0,0 +1,19 @@
+import { defineConfig } from 'vite'
+import uni from '@dcloudio/vite-plugin-uni'
+
+export default defineConfig({
+  plugins: [uni()],
+  server: {
+    host: '0.0.0.0',
+    port: 5174,
+    strictPort: true,
+    watch: { ignored: ['**/.edge-preview*/**'] },
+    proxy: {
+      '/dev-api': {
+        target: 'http://127.0.0.1:8301',
+        changeOrigin: true,
+        rewrite: path => path.replace(/^\/dev-api/, ''),
+      },
+    },
+  },
+})

Някои файлове не бяха показани, защото твърде много файлове са промени