commit 89960b1cb8225459cbbbf5cbdf05b5ae431abf6c
Author: Yvan <8574526@qq,com>
Date: Thu Apr 9 09:40:45 2026 +0800
Initial commit: 全友米项目完整代码
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..b975227
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,55 @@
+# Node modules
+node_modules
+*/node_modules
+
+# 前端构建产物
+frontend/dist
+
+# 环境变量文件(保留 .env 用于构建)
+.env.local
+.env.*.local
+
+# Git
+.git
+.gitignore
+
+# IDE
+.vscode
+.idea
+*.swp
+*.swo
+
+# 日志
+logs
+*.log
+npm-debug.log*
+
+# 操作系统
+.DS_Store
+Thumbs.db
+
+# 临时文件
+*.tmp
+*.temp
+
+# 上传文件
+backend/uploads/*
+!backend/uploads/.gitkeep
+
+# 测试
+coverage
+.nyc_output
+
+# 文档
+*.md
+!README.md
+
+# Docker 相关
+Dockerfile
+docker-compose.yml
+.dockerignore
+*.tar
+
+# 构建脚本
+build.sh
+build.bat
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6b4db38
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.env
+.env.local
+backend/uploads/*
+!backend/uploads/.gitkeep
+dist/
+.DS_Store
+*.log
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..7a73a41
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,2 @@
+{
+}
\ No newline at end of file
diff --git a/CHECKIN-FEATURE.md b/CHECKIN-FEATURE.md
new file mode 100644
index 0000000..e69de29
diff --git a/DEPLOY.md b/DEPLOY.md
new file mode 100644
index 0000000..81233cb
--- /dev/null
+++ b/DEPLOY.md
@@ -0,0 +1,279 @@
+# 泉友米车友会 - 部署说明
+
+版本: 0.0.1
+
+## 🚀 快速部署(推荐)
+
+### Windows 用户
+
+```cmd
+# 1. 构建镜像
+build.bat
+
+# 2. 启动服务
+docker-compose up -d
+
+# 3. 初始化管理员
+docker exec -it quanyoumi-app sh
+node init-admin.js
+```
+
+### Linux/Mac 用户
+
+```bash
+# 1. 构建镜像
+chmod +x build.sh
+./build.sh
+
+# 2. 启动服务
+docker-compose up -d
+
+# 3. 初始化管理员
+docker exec -it quanyoumi-app sh
+node init-admin.js
+```
+
+## 📝 部署前准备
+
+### 1. 修改配置文件
+
+编辑 `docker-compose.yml`,修改以下配置:
+
+```yaml
+environment:
+ - DB_PASSWORD=your_mysql_password # 修改数据库密码
+ - JWT_SECRET=your_jwt_secret_key # 修改JWT密钥(随机字符串)
+ - AMAP_KEY=your_amap_key # 填入高德地图Key
+```
+
+同时修改 MySQL 服务的密码:
+
+```yaml
+db:
+ environment:
+ - MYSQL_ROOT_PASSWORD=your_mysql_password # 与上面保持一致
+```
+
+### 2. 获取高德地图 Key
+
+1. 访问 https://console.amap.com/
+2. 注册/登录账号
+3. 创建应用,选择 Web 端(JS API)
+4. 复制 Key 填入配置
+
+## 🔧 详细步骤
+
+### 步骤 1: 构建 Docker 镜像
+
+镜像包含前端(Vue3)和后端(Node.js),版本号 0.0.1。
+
+**Windows:**
+```cmd
+build.bat
+```
+
+**Linux/Mac:**
+```bash
+chmod +x build.sh
+./build.sh
+```
+
+### 步骤 2: 启动服务
+
+使用 docker-compose 启动完整环境(应用+MySQL+MinIO):
+
+```bash
+docker-compose up -d
+```
+
+查看启动状态:
+```bash
+docker-compose ps
+```
+
+查看日志:
+```bash
+docker-compose logs -f app
+```
+
+### 步骤 3: 初始化数据库
+
+数据库会自动初始化(使用 database.sql),等待约 30 秒。
+
+检查数据库是否就绪:
+```bash
+docker-compose logs db | grep "ready for connections"
+```
+
+### 步骤 4: 创建管理员账号
+
+进入应用容器:
+```bash
+docker exec -it quanyoumi-app sh
+```
+
+运行初始化脚本:
+```bash
+node init-admin.js
+```
+
+按提示输入:
+- 用户名(例如:admin)
+- 密码(至少6位)
+- 确认密码
+
+退出容器:
+```bash
+exit
+```
+
+### 步骤 5: 访问应用
+
+- **前端页面**: http://localhost:3000
+- **后台管理**: http://localhost:3000/admin/login
+- **MinIO 控制台**: http://localhost:9001 (minioadmin/minioadmin)
+
+## 📦 镜像信息
+
+- **镜像名称**: quanyoumi-app
+- **版本**: 0.0.1
+- **基础镜像**: node:18-alpine
+- **大小**: 约 200MB
+- **包含内容**:
+ - 前端构建产物(Vue3 + Vant4)
+ - 后端服务(Node.js + Express)
+ - 依赖包(仅生产环境)
+
+## 🔍 验证部署
+
+### 1. 检查服务状态
+
+```bash
+docker-compose ps
+```
+
+应该看到 3 个服务都是 Up 状态:
+- quanyoumi-app
+- quanyoumi-db
+- quanyoumi-minio
+
+### 2. 检查应用日志
+
+```bash
+docker-compose logs app
+```
+
+应该看到:
+```
+服务器运行在 http://localhost:3000
+运行模式: 生产环境(前后端一体)
+```
+
+### 3. 测试访问
+
+浏览器访问 http://localhost:3000,应该能看到首页。
+
+## 🛠️ 常见问题
+
+### 问题 1: 端口被占用
+
+错误信息:`port is already allocated`
+
+解决方法:
+```bash
+# 修改 docker-compose.yml 中的端口映射
+ports:
+ - "3001:3000" # 改为其他端口
+```
+
+### 问题 2: 数据库连接失败
+
+错误信息:`ECONNREFUSED` 或 `Access denied`
+
+解决方法:
+1. 检查数据库是否启动:`docker-compose ps db`
+2. 检查密码是否一致(app 和 db 的密码要相同)
+3. 等待数据库完全启动(约 30 秒)
+
+### 问题 3: 前端页面空白
+
+解决方法:
+1. 检查浏览器控制台是否有错误
+2. 确认后端 API 是否正常:访问 http://localhost:3000/api/activities
+3. 重新构建镜像:`docker-compose build --no-cache`
+
+### 问题 4: 图片上传失败
+
+解决方法:
+1. 检查 MinIO 是否运行:`docker-compose ps minio`
+2. 访问 MinIO 控制台创建 bucket:http://localhost:9001
+3. 检查环境变量配置是否正确
+
+## 🔄 更新应用
+
+```bash
+# 1. 停止服务
+docker-compose down
+
+# 2. 拉取最新代码
+git pull
+
+# 3. 重新构建
+docker-compose build --no-cache
+
+# 4. 启动服务
+docker-compose up -d
+```
+
+## 🗑️ 清理
+
+### 停止服务(保留数据)
+```bash
+docker-compose down
+```
+
+### 完全清理(删除数据)
+```bash
+docker-compose down -v
+```
+
+### 删除镜像
+```bash
+docker rmi quanyoumi-app:0.0.1
+```
+
+## 📊 生产环境建议
+
+1. **使用反向代理**
+ - 推荐使用 Nginx 或 Caddy
+ - 配置 HTTPS 证书
+ - 设置域名
+
+2. **修改默认密码**
+ - MySQL root 密码
+ - MinIO 访问密钥
+ - JWT 密钥(长随机字符串)
+
+3. **数据备份**
+ - 定期备份 MySQL 数据
+ - 备份 MinIO 存储
+ - 备份上传文件
+
+4. **监控告警**
+ - 配置日志收集
+ - 设置资源监控
+ - 配置告警通知
+
+5. **安全加固**
+ - 限制数据库外部访问
+ - 使用防火墙规则
+ - 定期更新镜像
+
+## 📞 技术支持
+
+如有问题,请查看:
+1. 应用日志:`docker-compose logs app`
+2. 数据库日志:`docker-compose logs db`
+3. MinIO 日志:`docker-compose logs minio`
+
+或联系技术支持团队。
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..8049fbe
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,57 @@
+# 多阶段构建 - 前端构建阶段
+FROM node:18-alpine AS frontend-builder
+
+WORKDIR /app/frontend
+
+# 复制前端依赖文件
+COPY frontend/package*.json ./
+
+# 安装前端依赖(包括 devDependencies,因为需要 vite 构建)
+RUN npm ci
+
+# 复制前端源码
+COPY frontend/ ./
+
+# 构建前端(使用默认的 .env 文件中的配置)
+RUN npm run build
+
+# 后端运行阶段
+FROM node:18-alpine
+
+WORKDIR /app
+
+# 安装 dumb-init 和 envsubst
+RUN apk add --no-cache dumb-init gettext
+
+# 复制后端依赖文件
+COPY backend/package*.json ./
+
+# 安装后端依赖(仅生产依赖)
+RUN npm ci --only=production
+
+# 复制后端源码
+COPY backend/ ./
+
+# 从前端构建阶段复制构建产物
+COPY --from=frontend-builder /app/frontend/dist ./public
+
+# 创建上传目录
+RUN mkdir -p uploads
+
+# 复制启动脚本
+COPY docker-entrypoint.sh /usr/local/bin/
+RUN chmod +x /usr/local/bin/docker-entrypoint.sh
+
+# 暴露端口
+EXPOSE 3000
+
+# 设置环境变量
+ENV NODE_ENV=production
+
+# 健康检查
+HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
+ CMD node -e "require('http').get('http://localhost:3000/api/activities', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
+
+# 使用启动脚本
+ENTRYPOINT ["docker-entrypoint.sh"]
+CMD ["node", "server.js"]
diff --git a/backend/.env.example b/backend/.env.example
new file mode 100644
index 0000000..8ff80e7
--- /dev/null
+++ b/backend/.env.example
@@ -0,0 +1,17 @@
+PORT=3000
+DB_HOST=localhost
+DB_USER=root
+DB_PASSWORD=your-db-password
+DB_NAME=quanyoumi
+JWT_SECRET=your-secret-key-change-in-production
+
+# MinIO 配置
+MINIO_ENDPOINT=localhost # 后端连接 MinIO 的地址
+MINIO_PORT=9000
+MINIO_USE_SSL=false
+MINIO_ACCESS_KEY=jFywUsaCb4zNr2LV7hTP
+MINIO_SECRET_KEY=minioadmin
+MINIO_BUCKET=quanyoumi
+# MINIO_PUBLIC_URL(可选):前端访问文件的公开地址,不填则自动用 MINIO_ENDPOINT 拼接
+# 生产环境如果用了反向代理(如 Nginx),填写外网地址,例如:https://cdn.yourdomain.com
+# MINIO_PUBLIC_URL=http://localhost:9000
diff --git a/backend/init-admin.js b/backend/init-admin.js
new file mode 100644
index 0000000..f474dfa
--- /dev/null
+++ b/backend/init-admin.js
@@ -0,0 +1,27 @@
+// 初始化管理员账号
+require('dotenv').config();
+const bcrypt = require('bcryptjs');
+const { Admin, sequelize } = require('./models');
+
+async function initAdmin() {
+ try {
+ await sequelize.sync({ force: false });
+
+ const hashedPassword = bcrypt.hashSync('admin123', 10);
+ await Admin.create({
+ username: 'admin',
+ password: hashedPassword,
+ name: '管理员'
+ });
+
+ console.log('管理员账号创建成功');
+ console.log('用户名: admin');
+ console.log('密码: admin123');
+ process.exit(0);
+ } catch (error) {
+ console.error('创建失败:', error.message);
+ process.exit(1);
+ }
+}
+
+initAdmin();
diff --git a/backend/middleware/auth.js b/backend/middleware/auth.js
new file mode 100644
index 0000000..71c4f76
--- /dev/null
+++ b/backend/middleware/auth.js
@@ -0,0 +1,19 @@
+const jwt = require('jsonwebtoken');
+
+const auth = (req, res, next) => {
+ const token = req.header('Authorization')?.replace('Bearer ', '');
+
+ if (!token) {
+ return res.status(401).json({ error: '未授权访问' });
+ }
+
+ try {
+ const decoded = jwt.verify(token, process.env.JWT_SECRET);
+ req.adminId = decoded.id;
+ next();
+ } catch (error) {
+ res.status(401).json({ error: '无效的token' });
+ }
+};
+
+module.exports = auth;
diff --git a/backend/middleware/upload.js b/backend/middleware/upload.js
new file mode 100644
index 0000000..b852c14
--- /dev/null
+++ b/backend/middleware/upload.js
@@ -0,0 +1,30 @@
+const multer = require('multer');
+const path = require('path');
+const { v4: uuidv4 } = require('uuid');
+const { uploadBuffer } = require('../utils/minio');
+
+// 使用内存存储,文件不落盘,不限制大小
+const upload = multer({
+ storage: multer.memoryStorage(),
+ fileFilter: (req, file, cb) => {
+ const extname = /jpeg|jpg|png|gif|mp4|mov|avi/.test(
+ path.extname(file.originalname).toLowerCase()
+ );
+ const mimetype = /image|video/.test(file.mimetype);
+ if (mimetype && extname) return cb(null, true);
+ cb(new Error('只允许上传图片或视频文件'));
+ }
+});
+
+// 将 req.files 或 req.file 上传到 MinIO,返回 url 数组或单个 url
+const uploadFilesToMinio = async (files) => {
+ const list = Array.isArray(files) ? files : [files];
+ return Promise.all(list.map(async (file) => {
+ const ext = path.extname(file.originalname).toLowerCase();
+ const filename = `${Date.now()}-${uuidv4()}${ext}`;
+ const url = await uploadBuffer(file.buffer, filename, file.mimetype);
+ return { ...file, filename, url };
+ }));
+};
+
+module.exports = { upload, uploadFilesToMinio };
diff --git a/backend/models/Activity.js b/backend/models/Activity.js
new file mode 100644
index 0000000..c388c3d
--- /dev/null
+++ b/backend/models/Activity.js
@@ -0,0 +1,44 @@
+const { DataTypes } = require('sequelize');
+const sequelize = require('./db');
+
+const Activity = sequelize.define('Activity', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ title: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ description: DataTypes.TEXT,
+ location: DataTypes.STRING,
+ locationLat: DataTypes.DECIMAL(10, 7),
+ locationLng: DataTypes.DECIMAL(10, 7),
+ startTime: DataTypes.DATE,
+ endTime: DataTypes.DATE,
+ registrationDeadline: DataTypes.DATE,
+ maxParticipants: DataTypes.INTEGER,
+ status: {
+ type: DataTypes.ENUM('upcoming', 'ongoing', 'completed'),
+ defaultValue: 'upcoming'
+ },
+ registrationEnabled: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true,
+ comment: '报名开关'
+ },
+ coverImage: DataTypes.STRING,
+ price: {
+ type: DataTypes.DECIMAL(10, 2),
+ defaultValue: 0,
+ comment: '人均费用'
+ },
+ budget: {
+ type: DataTypes.DECIMAL(10, 2),
+ defaultValue: 0,
+ comment: '活动预算'
+ }
+});
+
+module.exports = Activity;
diff --git a/backend/models/Admin.js b/backend/models/Admin.js
new file mode 100644
index 0000000..dc7eabe
--- /dev/null
+++ b/backend/models/Admin.js
@@ -0,0 +1,22 @@
+const { DataTypes } = require('sequelize');
+const sequelize = require('./db');
+
+const Admin = sequelize.define('Admin', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ username: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ unique: true
+ },
+ password: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ name: DataTypes.STRING
+});
+
+module.exports = Admin;
diff --git a/backend/models/Expense.js b/backend/models/Expense.js
new file mode 100644
index 0000000..672dcf6
--- /dev/null
+++ b/backend/models/Expense.js
@@ -0,0 +1,32 @@
+const { DataTypes } = require('sequelize');
+const sequelize = require('./db');
+
+const Expense = sequelize.define('Expense', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ activityId: {
+ type: DataTypes.INTEGER,
+ allowNull: false
+ },
+ item: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ amount: {
+ type: DataTypes.DECIMAL(10, 2),
+ allowNull: false
+ },
+ category: DataTypes.STRING,
+ receipt: DataTypes.STRING,
+ note: DataTypes.TEXT,
+ media: {
+ type: DataTypes.JSON,
+ defaultValue: [],
+ comment: '经费相关照片/视频,最多5个'
+ }
+});
+
+module.exports = Expense;
diff --git a/backend/models/Photo.js b/backend/models/Photo.js
new file mode 100644
index 0000000..722e5b8
--- /dev/null
+++ b/backend/models/Photo.js
@@ -0,0 +1,30 @@
+const { DataTypes } = require('sequelize');
+const sequelize = require('./db');
+
+const Photo = sequelize.define('Photo', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ activityId: {
+ type: DataTypes.INTEGER,
+ allowNull: false
+ },
+ url: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ type: {
+ type: DataTypes.ENUM('image', 'video'),
+ defaultValue: 'image'
+ },
+ description: DataTypes.STRING,
+ uploadedBy: DataTypes.STRING,
+ status: {
+ type: DataTypes.ENUM('pending', 'approved', 'rejected'),
+ defaultValue: 'approved'
+ }
+});
+
+module.exports = Photo;
diff --git a/backend/models/Registration.js b/backend/models/Registration.js
new file mode 100644
index 0000000..c36d62e
--- /dev/null
+++ b/backend/models/Registration.js
@@ -0,0 +1,40 @@
+const { DataTypes } = require('sequelize');
+const sequelize = require('./db');
+
+const Registration = sequelize.define('Registration', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ activityId: {
+ type: DataTypes.INTEGER,
+ allowNull: false
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ phone: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ carModel: DataTypes.STRING,
+ carNumber: DataTypes.STRING,
+ peopleCount: {
+ type: DataTypes.INTEGER,
+ defaultValue: 1
+ },
+ status: {
+ type: DataTypes.ENUM('pending', 'approved', 'rejected'),
+ defaultValue: 'pending'
+ },
+ note: DataTypes.TEXT,
+ checkInStatus: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ checkInTime: DataTypes.DATE
+});
+
+module.exports = Registration;
diff --git a/backend/models/Sponsor.js b/backend/models/Sponsor.js
new file mode 100644
index 0000000..ab4bbf0
--- /dev/null
+++ b/backend/models/Sponsor.js
@@ -0,0 +1,26 @@
+const { DataTypes } = require('sequelize');
+const sequelize = require('./db');
+
+const Sponsor = sequelize.define('Sponsor', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ activityId: {
+ type: DataTypes.INTEGER,
+ allowNull: false
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ logo: DataTypes.STRING,
+ type: {
+ type: DataTypes.ENUM('title', 'sponsor'),
+ defaultValue: 'sponsor'
+ },
+ link: DataTypes.STRING
+});
+
+module.exports = Sponsor;
diff --git a/backend/models/db.js b/backend/models/db.js
new file mode 100644
index 0000000..0fc3cc8
--- /dev/null
+++ b/backend/models/db.js
@@ -0,0 +1,14 @@
+const { Sequelize } = require('sequelize');
+
+const sequelize = new Sequelize(
+ process.env.DB_NAME || 'quanyoumi',
+ process.env.DB_USER || 'root',
+ process.env.DB_PASSWORD || '',
+ {
+ host: process.env.DB_HOST || 'localhost',
+ dialect: 'mysql',
+ logging: false
+ }
+);
+
+module.exports = sequelize;
diff --git a/backend/models/index.js b/backend/models/index.js
new file mode 100644
index 0000000..cffc31b
--- /dev/null
+++ b/backend/models/index.js
@@ -0,0 +1,22 @@
+const sequelize = require('./db');
+const Activity = require('./Activity');
+const Registration = require('./Registration');
+const Expense = require('./Expense');
+const Photo = require('./Photo');
+const Sponsor = require('./Sponsor');
+const Admin = require('./Admin');
+
+// 同步数据库
+sequelize.sync({ alter: true }).then(() => {
+ console.log('数据库同步完成');
+});
+
+module.exports = {
+ sequelize,
+ Activity,
+ Registration,
+ Expense,
+ Photo,
+ Sponsor,
+ Admin
+};
diff --git a/backend/package-lock.json b/backend/package-lock.json
new file mode 100644
index 0000000..f9035e2
--- /dev/null
+++ b/backend/package-lock.json
@@ -0,0 +1,2140 @@
+{
+ "name": "quanyoumi-backend",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "quanyoumi-backend",
+ "version": "1.0.0",
+ "dependencies": {
+ "bcryptjs": "^2.4.3",
+ "cors": "^2.8.5",
+ "dotenv": "^16.3.1",
+ "express": "^4.18.2",
+ "jsonwebtoken": "^9.0.2",
+ "minio": "^8.0.7",
+ "multer": "^1.4.5-lts.1",
+ "mysql2": "^3.6.0",
+ "sequelize": "^6.33.0",
+ "uuid": "^9.0.1"
+ },
+ "devDependencies": {
+ "nodemon": "^3.0.1"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.13",
+ "resolved": "https://registry.npmmirror.com/@types/debug/-/debug-4.1.13.tgz",
+ "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "25.5.2",
+ "resolved": "https://registry.npmmirror.com/@types/node/-/node-25.5.2.tgz",
+ "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.18.0"
+ }
+ },
+ "node_modules/@types/validator": {
+ "version": "13.15.10",
+ "resolved": "https://registry.npmmirror.com/@types/validator/-/validator-13.15.10.tgz",
+ "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/append-field": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/append-field/-/append-field-1.0.0.tgz",
+ "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmmirror.com/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "license": "MIT"
+ },
+ "node_modules/aws-ssl-profiles": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
+ "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmmirror.com/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/block-stream2": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/block-stream2/-/block-stream2-2.1.0.tgz",
+ "integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==",
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/block-stream2/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.4",
+ "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.4.tgz",
+ "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
+ "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.1",
+ "iconv-lite": "~0.4.24",
+ "on-finished": "~2.4.1",
+ "qs": "~6.14.0",
+ "raw-body": "~2.5.3",
+ "type-is": "~1.6.18",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-5.0.5.tgz",
+ "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-or-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/browser-or-node/-/browser-or-node-2.1.1.tgz",
+ "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==",
+ "license": "MIT"
+ },
+ "node_modules/buffer-crc32": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
+ "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/busboy": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/busboy/-/busboy-1.6.0.tgz",
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
+ "dependencies": {
+ "streamsearch": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.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==",
+ "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==",
+ "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/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "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/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmmirror.com/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.7.tgz",
+ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
+ "license": "MIT"
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz",
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dottie": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmmirror.com/dottie/-/dottie-2.0.7.tgz",
+ "integrity": "sha512-7lAK2A0b3zZr3UC5aE69CPdCFR4RHW1o2Dr74TqFykxkUCBXSRJum/yPc7g8zRHJqWKomPLHwFLLoUnn8PXXRg==",
+ "license": "MIT"
+ },
+ "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==",
+ "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/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz",
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
+ "license": "MIT"
+ },
+ "node_modules/express": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmmirror.com/express/-/express-4.22.1.tgz",
+ "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
+ "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.7.1",
+ "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.3.1",
+ "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.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "~6.14.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "~0.19.0",
+ "serve-static": "~1.16.2",
+ "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"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/fast-xml-builder": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
+ "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "path-expression-matcher": "^1.1.3"
+ }
+ },
+ "node_modules/fast-xml-parser": {
+ "version": "5.5.10",
+ "resolved": "https://registry.npmmirror.com/fast-xml-parser/-/fast-xml-parser-5.5.10.tgz",
+ "integrity": "sha512-go2J2xODMc32hT+4Xr/bBGXMaIoiCwrwp2mMtAvKyvEFW6S/v5Gn2pBmE4nvbwNjGhpcAiOwEv7R6/GZ6XRa9w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "fast-xml-builder": "^1.1.4",
+ "path-expression-matcher": "^1.2.1",
+ "strnum": "^2.2.2"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/filter-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz",
+ "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.3.2.tgz",
+ "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "~2.0.2",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "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/generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "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==",
+ "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==",
+ "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==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/inflection": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmmirror.com/inflection/-/inflection-1.13.4.tgz",
+ "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==",
+ "engines": [
+ "node >= 0.4.0"
+ ],
+ "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==",
+ "license": "ISC"
+ },
+ "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==",
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
+ "license": "MIT"
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
+ "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==",
+ "license": "MIT",
+ "dependencies": {
+ "jws": "^4.0.1",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/jsonwebtoken/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/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/jws/-/jws-4.0.1.tgz",
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
+ "license": "MIT",
+ "dependencies": {
+ "jwa": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "license": "MIT"
+ },
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/lru.min": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/lru.min/-/lru.min-1.1.4.tgz",
+ "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==",
+ "license": "MIT",
+ "engines": {
+ "bun": ">=1.0.0",
+ "deno": ">=1.30.0",
+ "node": ">=8.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wellwelwel"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "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/minio": {
+ "version": "8.0.7",
+ "resolved": "https://registry.npmmirror.com/minio/-/minio-8.0.7.tgz",
+ "integrity": "sha512-E737MgufW8CeQAsTAtnEMrxZ9scMSf29kkhZoXzDTKj/Jszzo2SfeZUH9wbDQH2Rsq6TCtl/yQL0+XdVKZansQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.4",
+ "block-stream2": "^2.1.0",
+ "browser-or-node": "^2.1.1",
+ "buffer-crc32": "^1.0.0",
+ "eventemitter3": "^5.0.1",
+ "fast-xml-parser": "^5.3.4",
+ "ipaddr.js": "^2.0.1",
+ "lodash": "^4.17.21",
+ "mime-types": "^2.1.35",
+ "query-string": "^7.1.3",
+ "stream-json": "^1.8.0",
+ "through2": "^4.0.2",
+ "xml2js": "^0.5.0 || ^0.6.2"
+ },
+ "engines": {
+ "node": "^16 || ^18 || >=20"
+ }
+ },
+ "node_modules/minio/node_modules/ipaddr.js": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.3.0.tgz",
+ "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "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/moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.48",
+ "resolved": "https://registry.npmmirror.com/moment-timezone/-/moment-timezone-0.5.48.tgz",
+ "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
+ "license": "MIT",
+ "dependencies": {
+ "moment": "^2.29.4"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/multer": {
+ "version": "1.4.5-lts.2",
+ "resolved": "https://registry.npmmirror.com/multer/-/multer-1.4.5-lts.2.tgz",
+ "integrity": "sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==",
+ "deprecated": "Multer 1.x is impacted by a number of vulnerabilities, which have been patched in 2.x. You should upgrade to the latest 2.x version.",
+ "license": "MIT",
+ "dependencies": {
+ "append-field": "^1.0.0",
+ "busboy": "^1.0.0",
+ "concat-stream": "^1.5.2",
+ "mkdirp": "^0.5.4",
+ "object-assign": "^4.1.1",
+ "type-is": "^1.6.4",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/mysql2": {
+ "version": "3.20.0",
+ "resolved": "https://registry.npmmirror.com/mysql2/-/mysql2-3.20.0.tgz",
+ "integrity": "sha512-eCLUs7BNbgA6nf/MZXsaBO1SfGs0LtLVrJD3WeWq+jPLDWkSufTD+aGMwykfUVPdZnblaUK1a8G/P63cl9FkKg==",
+ "license": "MIT",
+ "dependencies": {
+ "aws-ssl-profiles": "^1.1.2",
+ "denque": "^2.1.0",
+ "generate-function": "^2.3.1",
+ "iconv-lite": "^0.7.2",
+ "long": "^5.3.2",
+ "lru.min": "^1.1.4",
+ "named-placeholders": "^1.1.6",
+ "sql-escaper": "^1.3.3"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 8"
+ }
+ },
+ "node_modules/mysql2/node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/named-placeholders": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmmirror.com/named-placeholders/-/named-placeholders-1.1.6.tgz",
+ "integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==",
+ "license": "MIT",
+ "dependencies": {
+ "lru.min": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/nodemon": {
+ "version": "3.1.14",
+ "resolved": "https://registry.npmmirror.com/nodemon/-/nodemon-3.1.14.tgz",
+ "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^4",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^10.2.1",
+ "pstree.remy": "^1.1.8",
+ "semver": "^7.5.3",
+ "simple-update-notifier": "^2.0.0",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nodemon"
+ }
+ },
+ "node_modules/nodemon/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/nodemon/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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-expression-matcher": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/path-expression-matcher/-/path-expression-matcher-1.3.0.tgz",
+ "integrity": "sha512-tkolHg8cWjEFA8+TqYGk0w6aNEZVcb7pVxW8KXZpU+ebaBr3s1ogbLssjK1cL74TtEuKl/qy6cb90RnwTFt3kw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
+ "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
+ "license": "MIT"
+ },
+ "node_modules/pg-connection-string": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmmirror.com/pg-connection-string/-/pg-connection-string-2.12.0.tgz",
+ "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmmirror.com/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/qs": {
+ "version": "6.14.2",
+ "resolved": "https://registry.npmmirror.com/qs/-/qs-6.14.2.tgz",
+ "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/query-string": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz",
+ "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
+ "license": "MIT",
+ "dependencies": {
+ "decode-uri-component": "^0.2.2",
+ "filter-obj": "^1.1.0",
+ "split-on-first": "^1.0.0",
+ "strict-uri-encode": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.3.tgz",
+ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/retry-as-promised": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmmirror.com/retry-as-promised/-/retry-as-promised-7.1.1.tgz",
+ "integrity": "sha512-hMD7odLOt3LkTjcif8aRZqi/hybjpLNgSk5oF5FCowfCjok6LukpN2bDX7R5wDmbgBQFn7YoBxSagmtXHaJYJw==",
+ "license": "MIT"
+ },
+ "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==",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/sax": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/sax/-/sax-1.6.0.tgz",
+ "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmmirror.com/send/-/send-0.19.2.tgz",
+ "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.1",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "~2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "~2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/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/sequelize": {
+ "version": "6.37.8",
+ "resolved": "https://registry.npmmirror.com/sequelize/-/sequelize-6.37.8.tgz",
+ "integrity": "sha512-HJ0IQFqcTsTiqbEgiuioYFMSD00TP6Cz7zoTti+zVVBwVe9fEhev9cH6WnM3XU31+ABS356durAb99ZuOthnKw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sequelize"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.1.8",
+ "@types/validator": "^13.7.17",
+ "debug": "^4.3.4",
+ "dottie": "^2.0.6",
+ "inflection": "^1.13.4",
+ "lodash": "^4.17.21",
+ "moment": "^2.29.4",
+ "moment-timezone": "^0.5.43",
+ "pg-connection-string": "^2.6.1",
+ "retry-as-promised": "^7.0.4",
+ "semver": "^7.5.4",
+ "sequelize-pool": "^7.1.0",
+ "toposort-class": "^1.0.1",
+ "uuid": "^8.3.2",
+ "validator": "^13.9.0",
+ "wkx": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ibm_db": {
+ "optional": true
+ },
+ "mariadb": {
+ "optional": true
+ },
+ "mysql2": {
+ "optional": true
+ },
+ "oracledb": {
+ "optional": true
+ },
+ "pg": {
+ "optional": true
+ },
+ "pg-hstore": {
+ "optional": true
+ },
+ "snowflake-sdk": {
+ "optional": true
+ },
+ "sqlite3": {
+ "optional": true
+ },
+ "tedious": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/sequelize-pool": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmmirror.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz",
+ "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/sequelize/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/sequelize/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/sequelize/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.16.3.tgz",
+ "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "~0.19.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==",
+ "license": "ISC"
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "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.0",
+ "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "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==",
+ "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==",
+ "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/simple-update-notifier": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+ "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/split-on-first": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz",
+ "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/sql-escaper": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/sql-escaper/-/sql-escaper-1.3.3.tgz",
+ "integrity": "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==",
+ "license": "MIT",
+ "engines": {
+ "bun": ">=1.0.0",
+ "deno": ">=2.0.0",
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/mysqljs/sql-escaper?sponsor=1"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/stream-chain": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmmirror.com/stream-chain/-/stream-chain-2.2.5.tgz",
+ "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/stream-json": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmmirror.com/stream-json/-/stream-json-1.9.1.tgz",
+ "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "stream-chain": "^2.2.5"
+ }
+ },
+ "node_modules/streamsearch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/streamsearch/-/streamsearch-1.1.0.tgz",
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/strict-uri-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/strnum": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmmirror.com/strnum/-/strnum-2.2.3.tgz",
+ "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/through2": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz",
+ "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "3"
+ }
+ },
+ "node_modules/through2/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/toposort-class": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/toposort-class/-/toposort-class-1.0.1.tgz",
+ "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==",
+ "license": "MIT"
+ },
+ "node_modules/touch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/touch/-/touch-3.1.1.tgz",
+ "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "license": "MIT"
+ },
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
+ "license": "MIT"
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/validator": {
+ "version": "13.15.35",
+ "resolved": "https://registry.npmmirror.com/validator/-/validator-13.15.35.tgz",
+ "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/wkx": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmmirror.com/wkx/-/wkx-0.5.0.tgz",
+ "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.6.2.tgz",
+ "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+ "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/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"
+ }
+ }
+ }
+}
diff --git a/backend/package.json b/backend/package.json
new file mode 100644
index 0000000..c4dc3e0
--- /dev/null
+++ b/backend/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "quanyoumi-backend",
+ "version": "1.0.0",
+ "description": "泉友米车友会管理系统后端",
+ "main": "server.js",
+ "scripts": {
+ "start": "node server.js",
+ "dev": "nodemon server.js"
+ },
+ "dependencies": {
+ "bcryptjs": "^2.4.3",
+ "cors": "^2.8.5",
+ "dotenv": "^16.3.1",
+ "express": "^4.18.2",
+ "jsonwebtoken": "^9.0.2",
+ "minio": "^8.0.7",
+ "multer": "^1.4.5-lts.1",
+ "mysql2": "^3.6.0",
+ "sequelize": "^6.33.0",
+ "uuid": "^9.0.1"
+ },
+ "devDependencies": {
+ "nodemon": "^3.0.1"
+ }
+}
diff --git a/backend/routes/activity.js b/backend/routes/activity.js
new file mode 100644
index 0000000..3881fc3
--- /dev/null
+++ b/backend/routes/activity.js
@@ -0,0 +1,113 @@
+const express = require('express');
+const router = express.Router();
+const { Activity, Photo, Sponsor, Expense, Registration } = require('../models');
+const { upload, uploadFilesToMinio } = require('../middleware/upload');
+
+// 获取活动列表
+router.get('/activities', async (req, res) => {
+ try {
+ const { status } = req.query;
+ const where = status ? { status } : {};
+ const activities = await Activity.findAll({ where, order: [['startTime', 'DESC']] });
+ res.json(activities);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取活动详情
+router.get('/activities/:id', async (req, res) => {
+ try {
+ const activity = await Activity.findByPk(req.params.id);
+ // 只返回已审核通过的照片
+ const photos = await Photo.findAll({
+ where: { activityId: req.params.id, status: 'approved' }
+ });
+ const sponsors = await Sponsor.findAll({ where: { activityId: req.params.id } });
+ const expenses = await Expense.findAll({ where: { activityId: req.params.id } });
+
+ res.json({ activity, photos, sponsors, expenses });
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取活动经费(公开接口)
+router.get('/activities/:id/expenses', async (req, res) => {
+ try {
+ const expenses = await Expense.findAll({ where: { activityId: req.params.id } });
+ res.json(expenses);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 用户上传照片(需要审核)
+router.post('/activities/:id/photos', upload.array('photos', 10), async (req, res) => {
+ try {
+ const { uploadedBy } = req.body;
+ const uploaded = await uploadFilesToMinio(req.files);
+ const photos = uploaded.map(file => ({
+ activityId: req.params.id,
+ url: file.url,
+ type: /\.(mp4|mov|avi)$/i.test(file.filename) ? 'video' : 'image',
+ uploadedBy,
+ status: 'pending'
+ }));
+ const created = await Photo.bulkCreate(photos);
+ res.json(created);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 用户验证登录
+router.post('/auth/verify/:activityId', async (req, res) => {
+ try {
+ const { phone, carNumber } = req.body;
+ const { activityId } = req.params;
+
+ console.log('验证请求:', { phone, carNumber, activityId });
+
+ if (!phone || !carNumber) {
+ return res.status(400).json({ error: '请输入手机号和车牌号' });
+ }
+
+ const registration = await Registration.findOne({
+ where: {
+ activityId,
+ phone,
+ carNumber
+ }
+ });
+
+ console.log('查询结果:', registration ? '找到' : '未找到');
+
+ if (!registration) {
+ // 调试:查询该活动下该手机号的所有报名
+ const allRegs = await Registration.findAll({
+ where: { activityId, phone }
+ });
+ console.log('该手机号的所有报名:', allRegs.map(r => ({ id: r.id, carNumber: r.carNumber })));
+
+ return res.status(404).json({ error: '未找到报名信息,请检查车牌号是否正确' });
+ }
+
+ res.json({
+ registration: {
+ id: registration.id,
+ name: registration.name,
+ phone: registration.phone,
+ carNumber: registration.carNumber,
+ carModel: registration.carModel,
+ status: registration.status,
+ activityId: registration.activityId
+ }
+ });
+ } catch (error) {
+ console.error('验证错误:', error);
+ res.status(500).json({ error: error.message });
+ }
+});
+
+module.exports = router;
diff --git a/backend/routes/admin.js b/backend/routes/admin.js
new file mode 100644
index 0000000..fbdce2d
--- /dev/null
+++ b/backend/routes/admin.js
@@ -0,0 +1,294 @@
+const express = require('express');
+const router = express.Router();
+const bcrypt = require('bcryptjs');
+const jwt = require('jsonwebtoken');
+const auth = require('../middleware/auth');
+const { upload, uploadFilesToMinio } = require('../middleware/upload');
+const { deleteFile } = require('../utils/minio');
+const { Admin, Activity, Registration, Expense, Photo, Sponsor } = require('../models');
+
+// 管理员登录
+router.post('/login', async (req, res) => {
+ try {
+ const { username, password } = req.body;
+ const admin = await Admin.findOne({ where: { username } });
+ if (!admin || !bcrypt.compareSync(password, admin.password)) {
+ return res.status(401).json({ error: '用户名或密码错误' });
+ }
+ const token = jwt.sign({ id: admin.id }, process.env.JWT_SECRET, { expiresIn: '7d' });
+ res.json({ token, admin: { id: admin.id, username: admin.username, name: admin.name } });
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 创建活动
+router.post('/activities', auth, async (req, res) => {
+ try {
+ const activity = await Activity.create(req.body);
+ res.json(activity);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 编辑活动
+router.put('/activities/:id', auth, async (req, res) => {
+ try {
+ await Activity.update(req.body, { where: { id: req.params.id } });
+ const activity = await Activity.findByPk(req.params.id);
+ res.json(activity);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 审核报名
+router.put('/registrations/:id', auth, async (req, res) => {
+ try {
+ const { status, peopleCount } = req.body;
+ const updateData = {};
+ if (status) updateData.status = status;
+ if (peopleCount !== undefined) updateData.peopleCount = peopleCount;
+
+ await Registration.update(updateData, { where: { id: req.params.id } });
+ const registration = await Registration.findByPk(req.params.id);
+ res.json(registration);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 签到/取消签到
+router.put('/registrations/:id/checkin', auth, async (req, res) => {
+ try {
+ const registration = await Registration.findByPk(req.params.id);
+ if (!registration) {
+ return res.status(404).json({ error: '报名信息不存在' });
+ }
+
+ const newStatus = !registration.checkInStatus;
+ await Registration.update({
+ checkInStatus: newStatus,
+ checkInTime: newStatus ? new Date() : null
+ }, { where: { id: req.params.id } });
+
+ const updated = await Registration.findByPk(req.params.id);
+ res.json(updated);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取所有报名(含待审核)
+router.get('/registrations', auth, async (req, res) => {
+ try {
+ const { activityId } = req.query;
+ const where = activityId ? { activityId } : {};
+ const registrations = await Registration.findAll({ where, order: [['createdAt', 'DESC']] });
+ res.json(registrations);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 上传经费明细
+router.post('/expenses', auth, upload.array('media', 5), async (req, res) => {
+ try {
+ const { activityId, item, amount, category, note } = req.body;
+ let receipt = null;
+ let media = [];
+
+ if (req.files && req.files.length > 0) {
+ const uploaded = await uploadFilesToMinio(req.files);
+ media = uploaded.map(file => ({
+ url: file.url,
+ type: file.mimetype.startsWith('video/') ? 'video' : 'image'
+ }));
+ }
+
+ const expense = await Expense.create({
+ activityId,
+ item,
+ amount,
+ category,
+ receipt,
+ note,
+ media
+ });
+ res.json(expense);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取经费列表
+router.get('/expenses', auth, async (req, res) => {
+ try {
+ const { activityId } = req.query;
+ const where = activityId ? { activityId } : {};
+ const expenses = await Expense.findAll({ where });
+ res.json(expenses);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 更新经费
+router.put('/expenses/:id', auth, upload.array('media', 5), async (req, res) => {
+ try {
+ const { item, amount, category, note, existingMedia } = req.body;
+ const updateData = { item, amount, category, note };
+
+ // 处理现有媒体
+ let media = [];
+ if (existingMedia) {
+ try {
+ media = JSON.parse(existingMedia);
+ } catch (e) {
+ media = [];
+ }
+ }
+
+ // 处理新上传的媒体
+ if (req.files && req.files.length > 0) {
+ const uploaded = await uploadFilesToMinio(req.files);
+ const newMedia = uploaded.map(file => ({
+ url: file.url,
+ type: file.mimetype.startsWith('video/') ? 'video' : 'image'
+ }));
+ media = [...media, ...newMedia].slice(0, 5); // 限制最多5个
+ }
+
+ updateData.media = media;
+
+ await Expense.update(updateData, { where: { id: req.params.id } });
+ const expense = await Expense.findByPk(req.params.id);
+ res.json(expense);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 删除经费
+router.delete('/expenses/:id', auth, async (req, res) => {
+ try {
+ await Expense.destroy({ where: { id: req.params.id } });
+ res.json({ message: '删除成功' });
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 上传活动照片
+router.post('/photos', auth, upload.array('photos', 10), async (req, res) => {
+ try {
+ const { activityId } = req.body;
+ const uploaded = await uploadFilesToMinio(req.files);
+ const photos = uploaded.map(file => ({
+ activityId,
+ url: file.url,
+ type: /\.(mp4|mov|avi)$/i.test(file.filename) ? 'video' : 'image',
+ status: 'approved'
+ }));
+ const created = await Photo.bulkCreate(photos);
+ res.json(created);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取待审核照片
+router.get('/photos/pending', auth, async (req, res) => {
+ try {
+ const photos = await Photo.findAll({
+ where: { status: 'pending' },
+ order: [['createdAt', 'DESC']]
+ });
+ res.json(photos);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 审核照片
+router.put('/photos/:id', auth, async (req, res) => {
+ try {
+ const { status } = req.body;
+ await Photo.update({ status }, { where: { id: req.params.id } });
+ const photo = await Photo.findByPk(req.params.id);
+ res.json(photo);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 删除照片
+router.delete('/photos/:id', auth, async (req, res) => {
+ try {
+ const photo = await Photo.findByPk(req.params.id);
+ if (!photo) {
+ return res.status(404).json({ error: '照片不存在' });
+ }
+
+ // 从URL提取文件名
+ const filename = photo.url.split('/').pop();
+
+ // 从MinIO删除文件
+ await deleteFile(filename);
+
+ // 从数据库删除记录
+ await photo.destroy();
+
+ res.json({ message: '删除成功' });
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 添加赞助商
+router.post('/sponsors', auth, upload.single('logo'), async (req, res) => {
+ try {
+ const { activityId, name, type, link } = req.body;
+ let logo = null;
+ if (req.file) {
+ const [uploaded] = await uploadFilesToMinio(req.file);
+ logo = uploaded.url;
+ }
+ const sponsor = await Sponsor.create({ activityId, name, logo, type, link });
+ res.json(sponsor);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 更新赞助商
+router.put('/sponsors/:id', auth, upload.single('logo'), async (req, res) => {
+ try {
+ const { name, type, link } = req.body;
+ const updateData = { name, type, link };
+
+ if (req.file) {
+ const [uploaded] = await uploadFilesToMinio(req.file);
+ updateData.logo = uploaded.url;
+ }
+
+ await Sponsor.update(updateData, { where: { id: req.params.id } });
+ const sponsor = await Sponsor.findByPk(req.params.id);
+ res.json(sponsor);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 删除赞助商
+router.delete('/sponsors/:id', auth, async (req, res) => {
+ try {
+ await Sponsor.destroy({ where: { id: req.params.id } });
+ res.json({ message: '删除成功' });
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+module.exports = router;
diff --git a/backend/routes/registration.js b/backend/routes/registration.js
new file mode 100644
index 0000000..6cd8cd5
--- /dev/null
+++ b/backend/routes/registration.js
@@ -0,0 +1,47 @@
+const express = require('express');
+const router = express.Router();
+const { Registration, Activity } = require('../models');
+
+// 提交报名
+router.post('/registrations', async (req, res) => {
+ try {
+ const { activityId, name, phone, carModel, carNumber, note } = req.body;
+
+ const activity = await Activity.findByPk(activityId);
+ if (!activity) {
+ return res.status(404).json({ error: '活动不存在' });
+ }
+
+ const registration = await Registration.create({
+ activityId, name, phone, carModel, carNumber, note
+ });
+
+ res.json(registration);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 查询报名状态
+router.get('/registrations/:id', async (req, res) => {
+ try {
+ const registration = await Registration.findByPk(req.params.id);
+ res.json(registration);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取活动报名列表(已通过)
+router.get('/activities/:id/registrations', async (req, res) => {
+ try {
+ const registrations = await Registration.findAll({
+ where: { activityId: req.params.id, status: 'approved' }
+ });
+ res.json(registrations);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+module.exports = router;
diff --git a/backend/server.js b/backend/server.js
new file mode 100644
index 0000000..8812c16
--- /dev/null
+++ b/backend/server.js
@@ -0,0 +1,36 @@
+require('dotenv').config();
+const express = require('express');
+const cors = require('cors');
+const path = require('path');
+
+const app = express();
+
+// 中间件
+app.use(cors());
+app.use(express.json());
+
+// API 路由
+app.use('/api', require('./routes/activity'));
+app.use('/api', require('./routes/registration'));
+app.use('/api/admin', require('./routes/admin'));
+
+// 生产环境下提供前端静态文件
+if (process.env.NODE_ENV === 'production') {
+ // 静态文件目录
+ app.use(express.static(path.join(__dirname, 'public')));
+
+ // 所有其他请求返回 index.html(支持前端路由)
+ app.get('*', (req, res) => {
+ res.sendFile(path.join(__dirname, 'public', 'index.html'));
+ });
+}
+
+const PORT = process.env.PORT || 3000;
+app.listen(PORT, () => {
+ console.log(`服务器运行在 http://localhost:${PORT}`);
+ if (process.env.NODE_ENV === 'production') {
+ console.log('运行模式: 生产环境(前后端一体)');
+ } else {
+ console.log('运行模式: 开发环境(仅后端API)');
+ }
+});
diff --git a/backend/uploads/.gitkeep b/backend/uploads/.gitkeep
new file mode 100644
index 0000000..49cc8ef
Binary files /dev/null and b/backend/uploads/.gitkeep differ
diff --git a/backend/utils/minio.js b/backend/utils/minio.js
new file mode 100644
index 0000000..318ee3b
--- /dev/null
+++ b/backend/utils/minio.js
@@ -0,0 +1,88 @@
+const Minio = require('minio');
+
+const config = {
+ endPoint: process.env.MINIO_ENDPOINT || 'localhost',
+ port: parseInt(process.env.MINIO_PORT) || 9000,
+ useSSL: process.env.MINIO_USE_SSL === 'true',
+ accessKey: process.env.MINIO_ACCESS_KEY || 'minioadmin',
+ secretKey: process.env.MINIO_SECRET_KEY || 'minioadmin'
+};
+
+console.log('MinIO 配置:', {
+ ...config,
+ secretKey: '***' // 隐藏密钥
+});
+
+const client = new Minio.Client(config);
+
+const BUCKET = process.env.MINIO_BUCKET || 'quanyoumi';
+
+// 确保 bucket 存在
+const ensureBucket = async () => {
+ try {
+ console.log(`检查 bucket: ${BUCKET}`);
+ const exists = await client.bucketExists(BUCKET);
+ console.log(`Bucket ${BUCKET} 存在:`, exists);
+
+ if (!exists) {
+ console.log(`创建 bucket: ${BUCKET}`);
+ await client.makeBucket(BUCKET);
+
+ // 设置公开读取策略
+ const policy = JSON.stringify({
+ Version: '2012-10-17',
+ Statement: [{
+ Effect: 'Allow',
+ Principal: { AWS: ['*'] },
+ Action: ['s3:GetObject'],
+ Resource: [`arn:aws:s3:::${BUCKET}/*`]
+ }]
+ });
+ await client.setBucketPolicy(BUCKET, policy);
+ console.log(`Bucket ${BUCKET} 创建成功并设置为公开读取`);
+ }
+ } catch (error) {
+ console.error('ensureBucket 错误:', error);
+ throw error;
+ }
+};
+
+// 上传 buffer 到 MinIO,返回公开访问 URL
+const uploadBuffer = async (buffer, filename, mimetype) => {
+ try {
+ console.log(`开始上传文件: ${filename}, 大小: ${buffer.length} bytes`);
+ await ensureBucket();
+
+ await client.putObject(BUCKET, filename, buffer, buffer.length, { 'Content-Type': mimetype });
+ console.log(`文件上传成功: ${filename}`);
+
+ // 如果配置了公开 URL 就用,否则用 endpoint 拼接
+ const publicUrl = process.env.MINIO_PUBLIC_URL;
+ if (publicUrl) {
+ return `${publicUrl}/${BUCKET}/${filename}`;
+ }
+
+ const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http';
+ const endpoint = process.env.MINIO_ENDPOINT || 'localhost';
+ const port = process.env.MINIO_PORT || 9000;
+ return `${protocol}://${endpoint}:${port}/${BUCKET}/${filename}`;
+ } catch (error) {
+ console.error('uploadBuffer 错误:', error);
+ throw error;
+ }
+};
+
+// 从 MinIO 删除文件
+const deleteFile = async (filename) => {
+ try {
+ console.log(`开始删除文件: ${filename}`);
+ await client.removeObject(BUCKET, filename);
+ console.log(`文件删除成功: ${filename}`);
+ return true;
+ } catch (error) {
+ console.error('deleteFile 错误:', error);
+ throw error;
+ }
+};
+
+module.exports = { client, BUCKET, uploadBuffer, deleteFile };
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..baf8326
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,69 @@
+@echo off
+REM 泉友米车友会 - Docker 构建脚本 (Windows)
+REM 版本: 0.0.1
+
+echo ==========================================
+echo 泉友米车友会 Docker 镜像构建
+echo 版本: 0.0.1
+echo ==========================================
+
+REM 检查 Docker 是否安装
+docker --version >nul 2>&1
+if errorlevel 1 (
+ echo 错误: Docker 未安装,请先安装 Docker Desktop
+ pause
+ exit /b 1
+)
+
+echo.
+echo 开始构建 Docker 镜像...
+docker build -t quanyoumi-app:0.0.1 -t quanyoumi-app:latest .
+
+if errorlevel 1 (
+ echo.
+ echo 构建失败!
+ pause
+ exit /b 1
+)
+
+echo.
+echo ==========================================
+echo 构建完成!
+echo ==========================================
+echo.
+echo 镜像信息:
+docker images | findstr quanyoumi-app
+echo.
+
+REM 标记镜像到阿里云仓库
+echo 正在标记镜像到阿里云仓库...
+docker tag quanyoumi-app:0.0.1 registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+docker tag quanyoumi-app:latest registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:latest
+
+echo.
+echo 正在推送镜像到阿里云仓库...
+docker push registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+docker push registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:latest
+
+if errorlevel 1 (
+ echo.
+ echo 推送失败!请检查是否已登录阿里云镜像仓库
+ echo 登录命令: docker login --username=你的用户名 registry.cn-hangzhou.aliyuncs.com
+ pause
+ exit /b 1
+)
+
+echo.
+echo ==========================================
+echo 推送完成!
+echo ==========================================
+echo.
+echo 镜像地址:
+echo registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+echo registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:latest
+echo.
+echo 在 NAS 上使用:
+echo docker pull registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+echo docker-compose up -d
+echo.
+pause
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..4f4ef91
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# 泉友米车友会 - Docker 构建脚本
+# 版本: 0.0.1
+
+set -e
+
+echo "=========================================="
+echo "泉友米车友会 Docker 镜像构建"
+echo "版本: 0.0.1"
+echo "=========================================="
+
+# 检查 Docker 是否安装
+if ! command -v docker &> /dev/null; then
+ echo "错误: Docker 未安装,请先安装 Docker"
+ exit 1
+fi
+
+# 构建镜像
+echo ""
+echo "开始构建 Docker 镜像..."
+docker build -t quanyoumi-app:0.0.1 -t quanyoumi-app:latest .
+
+echo ""
+echo "=========================================="
+echo "构建完成!"
+echo "=========================================="
+echo ""
+echo "镜像信息:"
+docker images | grep quanyoumi-app
+echo ""
+
+# 标记镜像到阿里云仓库
+echo "正在标记镜像到阿里云仓库..."
+docker tag quanyoumi-app:0.0.1 registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+docker tag quanyoumi-app:latest registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:latest
+
+echo ""
+echo "正在推送镜像到阿里云仓库..."
+docker push registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+docker push registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:latest
+
+echo ""
+echo "=========================================="
+echo "推送完成!"
+echo "=========================================="
+echo ""
+echo "镜像地址:"
+echo " registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1"
+echo " registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:latest"
+echo ""
+echo "在 NAS 上使用:"
+echo " docker pull registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1"
+echo " docker-compose up -d"
+echo ""
diff --git a/database-migration-checkin.sql b/database-migration-checkin.sql
new file mode 100644
index 0000000..176d76c
--- /dev/null
+++ b/database-migration-checkin.sql
@@ -0,0 +1,4 @@
+-- 添加签到功能字段
+ALTER TABLE Registrations
+ADD COLUMN checkInStatus BOOLEAN DEFAULT false COMMENT '是否已签到',
+ADD COLUMN checkInTime DATETIME NULL COMMENT '签到时间';
diff --git a/database.sql b/database.sql
new file mode 100644
index 0000000..07cb768
--- /dev/null
+++ b/database.sql
@@ -0,0 +1,90 @@
+-- 创建数据库
+CREATE DATABASE IF NOT EXISTS quanyoumi CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+USE quanyoumi;
+
+-- 活动表
+CREATE TABLE IF NOT EXISTS Activities (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ title VARCHAR(255) NOT NULL,
+ description TEXT,
+ location VARCHAR(255),
+ locationLat DECIMAL(10, 7),
+ locationLng DECIMAL(10, 7),
+ startTime DATETIME,
+ endTime DATETIME,
+ registrationDeadline DATETIME,
+ maxParticipants INT,
+ budget DECIMAL(10, 2) DEFAULT 0 COMMENT '活动预算',
+ status ENUM('upcoming', 'ongoing', 'completed') DEFAULT 'upcoming',
+ coverImage VARCHAR(255),
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
+
+-- 报名表
+CREATE TABLE IF NOT EXISTS Registrations (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ activityId INT NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ phone VARCHAR(20) NOT NULL,
+ carModel VARCHAR(100),
+ carNumber VARCHAR(20),
+ peopleCount INT DEFAULT 1,
+ status ENUM('pending', 'approved', 'rejected') DEFAULT 'pending',
+ note TEXT,
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ FOREIGN KEY (activityId) REFERENCES Activities(id) ON DELETE CASCADE
+);
+
+-- 经费表
+CREATE TABLE IF NOT EXISTS Expenses (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ activityId INT NOT NULL,
+ item VARCHAR(255) NOT NULL,
+ amount DECIMAL(10, 2) NOT NULL,
+ category VARCHAR(100),
+ receipt VARCHAR(255),
+ note TEXT,
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ FOREIGN KEY (activityId) REFERENCES Activities(id) ON DELETE CASCADE
+);
+
+-- 照片表
+CREATE TABLE IF NOT EXISTS Photos (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ activityId INT NOT NULL,
+ url VARCHAR(255) NOT NULL,
+ type ENUM('image', 'video') DEFAULT 'image',
+ description VARCHAR(255),
+ uploadedBy VARCHAR(100),
+ status ENUM('pending', 'approved', 'rejected') DEFAULT 'approved',
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ FOREIGN KEY (activityId) REFERENCES Activities(id) ON DELETE CASCADE
+);
+
+-- 赞助商表
+CREATE TABLE IF NOT EXISTS Sponsors (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ activityId INT NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ logo VARCHAR(255),
+ type ENUM('title', 'sponsor') DEFAULT 'sponsor',
+ link VARCHAR(255),
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ FOREIGN KEY (activityId) REFERENCES Activities(id) ON DELETE CASCADE
+);
+
+-- 管理员表
+CREATE TABLE IF NOT EXISTS Admins (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ username VARCHAR(50) NOT NULL UNIQUE,
+ password VARCHAR(255) NOT NULL,
+ name VARCHAR(100),
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..6797397
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,99 @@
+version: '3.8'
+
+services:
+ # 应用服务(前端+后端)
+ app:
+ image: registry.cn-hangzhou.aliyuncs.com/yvan329/quanyoumi-app:0.0.1
+ container_name: quanyoumi-app
+ restart: unless-stopped
+ ports:
+ - "3000:3000"
+ environment:
+ - NODE_ENV=production
+ - PORT=3000
+ # 数据库配置
+ - DB_HOST=db
+ - DB_PORT=3306
+ - DB_USER=root
+ - DB_PASSWORD=quanyoumi2024
+ - DB_NAME=quanyoumi
+ # JWT 密钥(请修改为随机字符串)
+ - JWT_SECRET=quanyoumi_jwt_secret_change_this_in_production_2024
+ # 高德地图配置(必填)
+ - AMAP_KEY=fd5b77136ba34fe6b4f0f86dca7782d9
+ - AMAP_SECURITY_CODE=7f61638e5635d944a534ff747dc615ac
+ # MinIO 配置
+ - MINIO_ENDPOINT=minio
+ - MINIO_PORT=9000
+ - MINIO_ACCESS_KEY=minioadmin
+ - MINIO_SECRET_KEY=minioadmin123
+ - MINIO_BUCKET=quanyoumi
+ volumes:
+ - app-uploads:/app/uploads
+ depends_on:
+ - db
+ - minio
+ networks:
+ - quanyoumi-network
+ healthcheck:
+ test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/activities', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"]
+ interval: 30s
+ timeout: 3s
+ retries: 3
+ start_period: 10s
+
+ # MySQL 数据库
+ db:
+ image: mysql:8.0
+ container_name: quanyoumi-db
+ restart: unless-stopped
+ environment:
+ - MYSQL_ROOT_PASSWORD=quanyoumi2024
+ - MYSQL_DATABASE=quanyoumi
+ - MYSQL_CHARACTER_SET_SERVER=utf8mb4
+ - MYSQL_COLLATION_SERVER=utf8mb4_unicode_ci
+ volumes:
+ - mysql-data:/var/lib/mysql
+ - ./database.sql:/docker-entrypoint-initdb.d/init.sql
+ networks:
+ - quanyoumi-network
+ healthcheck:
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pquanyoumi2024"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 30s
+
+ # MinIO 对象存储
+ minio:
+ image: minio/minio:latest
+ container_name: quanyoumi-minio
+ restart: unless-stopped
+ command: server /data --console-address ":9001"
+ environment:
+ - MINIO_ROOT_USER=minioadmin
+ - MINIO_ROOT_PASSWORD=minioadmin123
+ volumes:
+ - minio-data:/data
+ ports:
+ - "9001:9001"
+ networks:
+ - quanyoumi-network
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
+ interval: 30s
+ timeout: 20s
+ retries: 3
+ start_period: 10s
+
+volumes:
+ mysql-data:
+ driver: local
+ minio-data:
+ driver: local
+ app-uploads:
+ driver: local
+
+networks:
+ quanyoumi-network:
+ driver: bridge
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
new file mode 100644
index 0000000..4511471
--- /dev/null
+++ b/docker-entrypoint.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+set -e
+
+echo "=========================================="
+echo "泉友米车友会 - 启动中..."
+echo "=========================================="
+
+# 替换前端 index.html 中的环境变量占位符
+if [ -f "/app/public/index.html" ]; then
+ echo "配置高德地图 Key..."
+
+ # 使用环境变量替换占位符(直接修改文件)
+ AMAP_KEY="${AMAP_KEY:-YOUR_AMAP_KEY_PLACEHOLDER}"
+ AMAP_SECURITY_CODE="${AMAP_SECURITY_CODE:-YOUR_AMAP_SECURITY_CODE_PLACEHOLDER}"
+
+ # 使用 sed -i 直接修改文件
+ sed -i "s|YOUR_AMAP_KEY_PLACEHOLDER|${AMAP_KEY}|g" /app/public/index.html
+ sed -i "s|YOUR_AMAP_SECURITY_CODE_PLACEHOLDER|${AMAP_SECURITY_CODE}|g" /app/public/index.html
+
+ echo "环境变量注入完成:"
+ echo " AMAP_KEY: ${AMAP_KEY}"
+ echo " AMAP_SECURITY_CODE: ${AMAP_SECURITY_CODE}"
+
+ if [ "$AMAP_KEY" != "YOUR_AMAP_KEY_PLACEHOLDER" ] && [ -n "$AMAP_KEY" ]; then
+ echo "✓ 高德地图 Key 已配置"
+ else
+ echo "⚠ 警告: 高德地图 Key 未配置,地图功能将不可用"
+ echo " 请在 docker-compose.yml 中设置 AMAP_KEY 环境变量"
+ fi
+fi
+
+echo "=========================================="
+echo "启动应用服务..."
+echo "=========================================="
+
+# 使用 dumb-init 启动应用
+exec dumb-init "$@"
diff --git a/frontend/.env.example b/frontend/.env.example
new file mode 100644
index 0000000..d625a93
--- /dev/null
+++ b/frontend/.env.example
@@ -0,0 +1,9 @@
+# 高德地图API Key
+VITE_AMAP_KEY=your_amap_key_here
+
+# 高德地图安全密钥(securityJsCode)
+# 获取方式:登录 https://console.amap.com/ -> 应用管理 -> 查看应用详情 -> 安全密钥
+VITE_AMAP_SECURITY_CODE=your_security_code_here
+
+# API基础地址
+VITE_API_BASE_URL=/api
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000..0c161e0
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ 泉友米车友会
+
+
+
+
+
+
+
diff --git a/frontend/map-test.html b/frontend/map-test.html
new file mode 100644
index 0000000..b6e73ed
--- /dev/null
+++ b/frontend/map-test.html
@@ -0,0 +1,201 @@
+
+
+
+
+
+ 高德地图搜索测试
+
+
+
+ 高德地图搜索功能测试
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
new file mode 100644
index 0000000..f7ed9ac
--- /dev/null
+++ b/frontend/package-lock.json
@@ -0,0 +1,1135 @@
+{
+ "name": "quanyoumi-frontend",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "quanyoumi-frontend",
+ "version": "1.0.0",
+ "dependencies": {
+ "axios": "^1.5.0",
+ "vant": "^4.7.1",
+ "vue": "^3.3.4",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^4.4.0",
+ "vite": "^4.5.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.2.tgz",
+ "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@vant/popperjs": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
+ "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==",
+ "license": "MIT"
+ },
+ "node_modules/@vant/use": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
+ "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
+ "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.0.0 || ^5.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.32.tgz",
+ "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.2",
+ "@vue/shared": "3.5.32",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz",
+ "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.32",
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz",
+ "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.2",
+ "@vue/compiler-core": "3.5.32",
+ "@vue/compiler-dom": "3.5.32",
+ "@vue/compiler-ssr": "3.5.32",
+ "@vue/shared": "3.5.32",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.8",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz",
+ "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.32",
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "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/reactivity": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.32.tgz",
+ "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.32.tgz",
+ "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.32",
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz",
+ "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.32",
+ "@vue/runtime-core": "3.5.32",
+ "@vue/shared": "3.5.32",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.32.tgz",
+ "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.32",
+ "@vue/shared": "3.5.32"
+ },
+ "peerDependencies": {
+ "vue": "3.5.32"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.32.tgz",
+ "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==",
+ "license": "MIT"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.14.0",
+ "resolved": "https://registry.npmmirror.com/axios/-/axios-1.14.0.tgz",
+ "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.11",
+ "form-data": "^4.0.5",
+ "proxy-from-env": "^2.1.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "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==",
+ "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/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==",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
+ "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/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "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/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "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/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": {
+ "version": "8.5.8",
+ "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.8.tgz",
+ "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
+ "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/proxy-from-env": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+ "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.30.0",
+ "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.30.0.tgz",
+ "integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "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/vant": {
+ "version": "4.9.24",
+ "resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.24.tgz",
+ "integrity": "sha512-tP1A7Vjzv1/B1ljb95Jhv9Q9w6acaaZDJvy6wcKrwGgY0gQZlg+FXLZH/AIKZBE3xvYGDUsv/M7AuGcr/Pqd6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@vant/popperjs": "^1.3.0",
+ "@vant/use": "^1.6.0",
+ "@vue/shared": "^3.5.31"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "4.5.14",
+ "resolved": "https://registry.npmmirror.com/vite/-/vite-4.5.14.tgz",
+ "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.18.10",
+ "postcss": "^8.4.27",
+ "rollup": "^3.27.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "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.5.32",
+ "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.32.tgz",
+ "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.32",
+ "@vue/compiler-sfc": "3.5.32",
+ "@vue/runtime-dom": "3.5.32",
+ "@vue/server-renderer": "3.5.32",
+ "@vue/shared": "3.5.32"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-router": {
+ "version": "4.6.4",
+ "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.6.4.tgz",
+ "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^6.6.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ }
+ }
+}
diff --git a/frontend/package.json b/frontend/package.json
new file mode 100644
index 0000000..5f624ee
--- /dev/null
+++ b/frontend/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "quanyoumi-frontend",
+ "version": "1.0.0",
+ "description": "泉友米车友会前端",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "vue": "^3.3.4",
+ "vue-router": "^4.2.5",
+ "vant": "^4.7.1",
+ "axios": "^1.5.0"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^4.4.0",
+ "vite": "^4.5.0"
+ }
+}
diff --git a/frontend/public/are-you-ok.mp3 b/frontend/public/are-you-ok.mp3
new file mode 100644
index 0000000..5fe3565
Binary files /dev/null and b/frontend/public/are-you-ok.mp3 differ
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
new file mode 100644
index 0000000..429f05d
--- /dev/null
+++ b/frontend/src/App.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js
new file mode 100644
index 0000000..93cb2b8
--- /dev/null
+++ b/frontend/src/api/index.js
@@ -0,0 +1,69 @@
+import axios from 'axios';
+
+const api = axios.create({
+ baseURL: '/api',
+ timeout: 10000
+});
+
+api.interceptors.request.use(config => {
+ const token = localStorage.getItem('token');
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+});
+
+export default {
+ // 活动相关
+ getActivities: (params) => api.get('/activities', { params }),
+ getActivity: (id) => api.get(`/activities/${id}`),
+
+ // 报名相关
+ submitRegistration: (data) => api.post('/registrations', data),
+ getRegistration: (id) => api.get(`/registrations/${id}`),
+ getActivityRegistrations: (id) => api.get(`/activities/${id}/registrations`),
+
+ // 用户上传照片
+ uploadUserPhotos: (id, data) => api.post(`/activities/${id}/photos`, data, {
+ headers: { 'Content-Type': 'multipart/form-data' },
+ timeout: 300000 // 5分钟超时
+ }),
+
+ // 用户验证登录
+ verifyUser: (activityId, data) => api.post(`/auth/verify/${activityId}`, data),
+
+ // 管理员相关
+ adminLogin: (data) => api.post('/admin/login', data),
+ createActivity: (data) => api.post('/admin/activities', data),
+ updateActivity: (id, data) => api.put(`/admin/activities/${id}`, data),
+ approveRegistration: (id, status) => api.put(`/admin/registrations/${id}`, { status }),
+ updateRegistration: (id, data) => api.put(`/admin/registrations/${id}`, data),
+ checkInRegistration: (id) => api.put(`/admin/registrations/${id}/checkin`),
+ getAllRegistrations: (params) => api.get('/admin/registrations', { params }),
+ addExpense: (data) => api.post('/admin/expenses', data, {
+ headers: { 'Content-Type': 'multipart/form-data' },
+ timeout: 60000
+ }),
+ getExpenses: (params) => api.get('/admin/expenses', { params }),
+ updateExpense: (id, data) => api.put(`/admin/expenses/${id}`, data, {
+ headers: { 'Content-Type': 'multipart/form-data' },
+ timeout: 60000
+ }),
+ deleteExpense: (id) => api.delete(`/admin/expenses/${id}`),
+ uploadPhotos: (data) => api.post('/admin/photos', data, {
+ headers: { 'Content-Type': 'multipart/form-data' },
+ timeout: 300000 // 5分钟超时,适配大文件上传
+ }),
+ getPendingPhotos: () => api.get('/admin/photos/pending'),
+ approvePhoto: (id, status) => api.put(`/admin/photos/${id}`, { status }),
+ deletePhoto: (id) => api.delete(`/admin/photos/${id}`),
+ addSponsor: (data) => api.post('/admin/sponsors', data, {
+ headers: { 'Content-Type': 'multipart/form-data' },
+ timeout: 60000 // 1分钟超时
+ }),
+ updateSponsor: (id, data) => api.put(`/admin/sponsors/${id}`, data, {
+ headers: { 'Content-Type': 'multipart/form-data' },
+ timeout: 60000
+ }),
+ deleteSponsor: (id) => api.delete(`/admin/sponsors/${id}`)
+};
diff --git a/frontend/src/main.js b/frontend/src/main.js
new file mode 100644
index 0000000..e1a78ac
--- /dev/null
+++ b/frontend/src/main.js
@@ -0,0 +1,118 @@
+import { createApp } from 'vue';
+import App from './App.vue';
+import router from './router';
+import Vant from 'vant';
+import 'vant/lib/index.css';
+
+// 全局样式 - 防止移动端输入框自动缩放
+const globalStyle = document.createElement('style');
+globalStyle.textContent = `
+ /* 防止iOS输入框自动缩放 */
+ input, textarea, select {
+ font-size: 16px !important;
+ }
+
+ /* 防止页面缩放 */
+ * {
+ touch-action: manipulation;
+ }
+
+ /* 优化输入框体验 */
+ input:focus, textarea:focus, select:focus {
+ font-size: 16px !important;
+ }
+`;
+document.head.appendChild(globalStyle);
+
+// 获取高德地图配置(优先使用运行时配置,其次使用构建时环境变量)
+const getAmapKey = () => {
+ if (window.AMAP_CONFIG && window.AMAP_CONFIG.key && window.AMAP_CONFIG.key !== 'YOUR_AMAP_KEY_PLACEHOLDER') {
+ return window.AMAP_CONFIG.key;
+ }
+ return import.meta.env.VITE_AMAP_KEY;
+};
+
+const getAmapSecurityCode = () => {
+ if (window.AMAP_CONFIG && window.AMAP_CONFIG.securityCode && window.AMAP_CONFIG.securityCode !== 'YOUR_AMAP_SECURITY_CODE_PLACEHOLDER') {
+ return window.AMAP_CONFIG.securityCode;
+ }
+ return import.meta.env.VITE_AMAP_SECURITY_CODE || 'b2e67bb4d5eed8848f0b8aae6ca667fc';
+};
+
+// 配置高德地图安全密钥(必须在加载地图前配置)
+window._AMapSecurityConfig = {
+ securityJsCode: getAmapSecurityCode()
+};
+
+console.log('高德地图配置:', {
+ hasKey: !!getAmapKey(),
+ keySource: window.AMAP_CONFIG && window.AMAP_CONFIG.key !== 'YOUR_AMAP_KEY_PLACEHOLDER' ? 'runtime' : 'build-time',
+ hasSecurityCode: !!getAmapSecurityCode()
+});
+
+const app = createApp(App);
+app.use(router);
+app.use(Vant);
+app.mount('#app');
+
+// 动态加载高德地图(含插件)
+const loadAMap = () => {
+ return new Promise((resolve, reject) => {
+ const amapKey = getAmapKey();
+
+ if (!amapKey || amapKey === 'YOUR_AMAP_KEY_PLACEHOLDER' || amapKey === 'YOUR_AMAP_KEY') {
+ console.error('高德地图Key未配置!');
+ console.error('请在 docker-compose.yml 中配置 AMAP_KEY 环境变量');
+ console.error('当前 Key 值:', amapKey);
+ reject(new Error('高德地图Key未配置'));
+ return;
+ }
+
+ if (window.AMap) {
+ // 如果已加载,检查插件是否可用
+ if (window.AMap.Geocoder && window.AMap.PlaceSearch) {
+ console.log('高德地图已加载,插件可用');
+ resolve(window.AMap);
+ } else {
+ // 插件未加载,异步加载
+ console.log('加载高德地图插件...');
+ window.AMap.plugin(['AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.AutoComplete'], () => {
+ console.log('高德地图插件加载完成');
+ resolve(window.AMap);
+ });
+ }
+ return;
+ }
+
+ console.log('开始加载高德地图脚本...');
+ const script = document.createElement('script');
+ script.src = `https://webapi.amap.com/maps?v=2.0&key=${amapKey}&plugin=AMap.Geocoder,AMap.PlaceSearch,AMap.AutoComplete`;
+ script.async = true;
+ script.onload = () => {
+ if (window.AMap) {
+ console.log('高德地图脚本加载成功');
+ // 脚本加载后再确保插件加载
+ window.AMap.plugin(['AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.AutoComplete'], () => {
+ console.log('高德地图插件初始化完成');
+ resolve(window.AMap);
+ });
+ } else {
+ console.error('高德地图加载失败:window.AMap未定义');
+ reject(new Error('高德地图加载失败'));
+ }
+ };
+ script.onerror = (error) => {
+ console.error('高德地图脚本加载失败:', error);
+ reject(new Error('高德地图脚本加载失败'));
+ };
+ document.head.appendChild(script);
+ });
+};
+
+// 导出加载函数供其他组件使用
+window.loadAMap = loadAMap;
+
+// 预加载地图
+loadAMap().catch(err => {
+ console.error('地图预加载失败:', err);
+});
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
new file mode 100644
index 0000000..4925153
--- /dev/null
+++ b/frontend/src/router/index.js
@@ -0,0 +1,61 @@
+import { createRouter, createWebHistory } from 'vue-router';
+
+const routes = [
+ {
+ path: '/',
+ name: 'Home',
+ component: () => import('../views/Home.vue')
+ },
+ {
+ path: '/landing',
+ name: 'LandingPage',
+ component: () => import('../views/LandingPage.vue')
+ },
+ {
+ path: '/activity/:id',
+ name: 'ActivityDetail',
+ component: () => import('../views/ActivityDetail.vue')
+ },
+ {
+ path: '/register/:id',
+ name: 'Register',
+ component: () => import('../views/Register.vue')
+ },
+ {
+ path: '/share/:id',
+ name: 'SharePage',
+ component: () => import('../views/SharePage.vue')
+ },
+ {
+ path: '/admin/login',
+ name: 'AdminLogin',
+ component: () => import('../views/admin/Login.vue')
+ },
+ {
+ path: '/admin',
+ name: 'Admin',
+ component: () => import('../views/admin/Dashboard.vue'),
+ meta: { requiresAuth: true }
+ },
+ {
+ path: '/admin/activity/:id',
+ name: 'ActivityManage',
+ component: () => import('../views/admin/ActivityManage.vue'),
+ meta: { requiresAuth: true }
+ }
+];
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes
+});
+
+router.beforeEach((to, from, next) => {
+ if (to.meta.requiresAuth && !localStorage.getItem('token')) {
+ next('/admin/login');
+ } else {
+ next();
+ }
+});
+
+export default router;
diff --git a/frontend/src/views/ActivityDetail.vue b/frontend/src/views/ActivityDetail.vue
new file mode 100644
index 0000000..0a4e7d9
--- /dev/null
+++ b/frontend/src/views/ActivityDetail.vue
@@ -0,0 +1,1442 @@
+
+
+
+
+
+
+
+
+
+
活动时间
+
{{ formatDate(activity.startTime) }}
+
+
+
+
+
+
活动地点
+
{{ activity.location }}
+
+
+
+
+
+
+
报名截止
+
{{ formatDate(activity.registrationDeadline) }}
+
+
+
+
+
+
人均费用
+
{{ activity.price > 0 ? `¥${activity.price}` : '免费' }}
+
+
+
+
+
+
活动介绍
+
{{ activity.description }}
+
+
+
+
活动流程
+
+
+
+
+
14:00 - 14:30
+
签到与集结
+
+ 车辆到场 → 指引至临时停车点 → 签到处签名 → 扫码入群 → 领取积分卡
+
+
📋 积分卡说明
+
+ • 每人领取一张积分卡(红绿双色章)
+ • 初始积分:0分
+ • 游戏得分范围:+1至+5分
+ • 游戏扣分范围:-1至-5分
+ • 最终积分可兑换礼品
+
+
+
+
+
+
+
+
+
14:30 - 16:30
+
观赏素材拍摄
+
全员车前合影、签到墙合照、地标合影、动态全员上车、点火、拍“泉州”俩个字
+
+
+
+
+
+
16:30 - 18:00
+
互动游戏时间
+
+
+
🎮 游戏项目清单
+
+
+
🎯 套圈圈
+
得分规则:套中1个+1分,套中3个+3分,套中5个+5分
+
+
+
+
🏺 投壶
+
得分规则:投中3个+2分,投中5个+4分,全中+5分
+
+
+
+
🎲 摇筛子
+
得分规则:豹子+5分,顺子+3分,对子+1分
+
+
+
+
🃏 牛牛/划拳
+
得分规则:赢一局+1分,连赢3局+3分,连赢5局+5分
+
+
+
+
⚽ 足球射门
+
得分规则:进1球+1分,进3球+3分,进5球+5分
+
+
+
+
🎮 王者荣耀
+
得分规则:获胜+3分,MVP+5分,失败-1分
+
+
+
+
💧 抛水瓶
+
得分规则:立住1个+2分,立住3个+4分,立住5个+5分
+
+
+
+
🎴 扑克游戏
+
得分规则:根据游戏类型,赢家+2分,输家-1分
+
+
+
+
🐊 鳄鱼/插剑玩具
+
得分规则:挑战成功+3分,失败-2分
+
+
+
+
🪑 最终复活挑战 - 抢椅子
+
+ 规则:音乐停止时抢座位,未抢到者淘汰
+ 得分:冠军+5分,亚军+3分,季军+2分,淘汰-1分
+
+
+
+
+
+
+
+
+
+
18:00 - 19:30
+
落日BBQ
+
+ 落日余晖下午餐串成一排、齐开大灯、拍摄氛围感大片、边烤肉边欣赏晚霞
+
+
+ 💡 提示:分享美食照片到朋友圈并@活动官方账号可获得 +1分
+
+
+
+
+
+
+
+
+
19:00 - 20:00
+
篝火歌舞会
+
+
+
🎤 互动游戏环节
+
+
+
🥁 击鼓传花(10轮)
+
+ 规则:音乐停止时持花者上台,吃柠檬或苦瓜
+ 得分:勇敢完成+2分,拒绝挑战-3分
+
+
+
+
+
🤝 喊数抱团(10轮)
+
+ 规则:主持人喊数字,参与者按数字抱团,落单者淘汰
+ 惩罚:上台自我介绍(1分钟)
+ 得分:成功抱团+1分,落单但完成自我介绍+2分,拒绝-2分
+
+
+
+
+
🎵 大合唱
+
+ 全员参与,气氛热烈,每人+1分
+
+
+
+
+
🎭 个人才艺表演
+
+ 规则:自愿上台唱歌、跳舞、表演才艺
+ 提示:需提前到后台准备BGM
+ 得分:参与表演+3分,精彩表演+5分
+
+
+
+
+
👶 小朋友互动
+
+ 主持人邀请小朋友上台互动,参与即有礼品
+ 家长陪同参与+2分
+
+
+
+
+
+
+
+
+
+
20:00 - 20:30
+
璀璨烟火秀
+
+
+
🎆 烟花表演
+
+ 1. 米兰之夜 - 大型专业烟火表演
+ 2. 仙女棒 - 每车配发手持烟花,拍照打卡
+ 3. 加特林压轴 - 震撼收尾,全场欢呼
+
+ 💡 提示:拍摄烟花视频并分享可获得 +2分
+
+
+
+
+
+
+
+
+
20:30 以后
+
积分兑奖 & 自由交流
+
+
+
🏆 积分兑换礼品
+
+ 积分排行榜:
+ • 第1名(20分以上):神秘大奖
+ • 第2-3名(15-19分):精美礼品
+ • 第4-10名(10-14分):纪念品
+ • 参与奖(5-9分):小礼物
+
+ 随后自由合影、整理垃圾、提醒安全驾驶返程
+
+
+
+
+
+
+
+
+
+
活动经费 ¥{{ totalExpense }}
+
+
+
+
{{ expense.item }}
+
{{ expense.category }}
+
+
+
金额:¥{{ expense.amount }}
+
+
+
+
+
+
+
+ 您的报名正在审核中,审核通过后可查看活动经费
+ 您的报名未通过审核
+
+
+
+
+
赞助商
+
+
+
+
+
活动照片与视频
+
+
+
+
+
+
+
+ 上传照片/视频
+
+
您可以上传活动照片或视频,审核后将展示给所有人
+
+
+
+
+
+ 审核通过后可上传照片/视频
+ 您的报名未通过审核
+
+
+
+
+
+
报名名单 ({{ registrations.length }}人)
+
+
+
{{ reg.name.charAt(0) }}
+
+
{{ reg.name }}
+
{{ reg.carModel }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 分享
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/ActivityDetail_fixed.vue b/frontend/src/views/ActivityDetail_fixed.vue
new file mode 100644
index 0000000..33ea90c
--- /dev/null
+++ b/frontend/src/views/ActivityDetail_fixed.vue
@@ -0,0 +1,1577 @@
+
+
+
+
+
+
+
+
+
+
活动时间
+
{{ formatDate(activity.startTime) }}
+
+
+
+
+
+
活动地点
+
{{ activity.location }}
+
+
+
+
+
+
+
报名截止
+
{{ formatDate(activity.registrationDeadline) }}
+
+
+
+
+
+
人均费用
+
{{ activity.price > 0 ? `¥${activity.price}` : '免费' }}
+
+
+
+
+
+
活动介绍
+
{{ activity.description }}
+
+
+
+
活动流程
+
+
+
+
+
+ 14:00 - 14:30
+
+
+
签到与集�?/div>
+
车辆到场 �?签到处签�?�?扫码入群 �?领取积分�?/div>
+
+
+
+
+
+
+
+ 14:30 - 16:30
+
+
+
观赏素材拍摄
+
全员车前合影、签到墙合照、地标合�?/div>
+
+
+
+
+
+
+
+ 16:30 - 18:00
+
+
+
互动游戏时间
+
套圈圈、投壶、摇筛子、足球射门等10+游戏项目
+
+
+
+
+
+
+
+ 18:00 - 19:30
+
+
+
落日BBQ
+
落日余晖下烤肉、拍摄氛围感大片
+
+
+
+
+
+
+
+ 19:00 - 20:00
+
+
+
篝火歌舞�?/div>
+
击鼓传花、喊数抱团、才艺表演等互动游戏
+
+
+
+
+
+
+
+ 20:00 - 20:30
+
+
+
璀璨烟火秀
+
米兰之夜、仙女棒、加特林压轴
+
+
+
+
+
+
+
+ 20:30 以后
+
+
+
积分兑奖 & 自由交流
+
积分兑换礼品、自由合影、安全返�?/div>
+
+
+
+
+
活动经费 ¥{{ totalExpense }}
+
+
+
+
{{ expense.item }}
+
{{ expense.category }}
+
+
+
金额:¥{{ expense.amount }}
+
+
+
+
+
+
+
+ 您的报名正在审核中,审核通过后可查看活动经费
+ 您的报名未通过审核
+
+
+
+
+
赞助商
+
+
+
+
+
活动照片与视频
+
+
+
+
+
+
+
+ 上传照片/视频
+
+
您可以上传活动照片或视频,审核后将展示给所有人
+
+
+
+
+
+ 审核通过后可上传照片/视频
+ 您的报名未通过审核
+
+
+
+
+
+
报名名单 ({{ registrations.length }}�?
+
+
+
{{ reg.name.charAt(0) }}
+
+
{{ reg.name }}
+
{{ reg.carModel }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 分享
+
+
+
+
+
+
+
+
+
+
+
+
+ �?/span>
+
+ ·
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
new file mode 100644
index 0000000..b5b3b0d
--- /dev/null
+++ b/frontend/src/views/Home.vue
@@ -0,0 +1,314 @@
+
+
+
+
+
+
+
+
+
+
泉友米车友会
+
驾驭激情 · 共享旅程
+
+ 查看宣传页
+
+
+
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
{{ activity.status === 'upcoming' ? '报名中' : '已结束' }}
+
+
+
{{ activity.title }}
+
{{ activity.description }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/LandingPage.vue b/frontend/src/views/LandingPage.vue
new file mode 100644
index 0000000..e6f8baa
--- /dev/null
+++ b/frontend/src/views/LandingPage.vue
@@ -0,0 +1,957 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
小米汽车车友会
+
驾驭未来 · 智享生活
+
Are You OK? 一起探索小米汽车的无限可能
+
+
+
+
+
+
+
+ ✨
+ 车友会特色
+
+
+
+
+
+
+
{{ feature.icon }}
+
{{ feature.title }}
+
{{ feature.desc }}
+
+
+
+
+
+
+
+
+ 🎯
+ 精彩活动
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
{{ activity.title }}
+
+
+ {{ formatDate(activity.startTime) }}
+
+
+
+ {{ activity.location }}
+
+
+
+
+
+
+ 查看全部活动
+
+
+
+
+
+
+
+
+
+
+
加入我们
+
与千位小米汽车车主一起,探索智能出行新体验
+
+ 立即加入车友会
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/Register.vue b/frontend/src/views/Register.vue
new file mode 100644
index 0000000..f9603b0
--- /dev/null
+++ b/frontend/src/views/Register.vue
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+
diff --git a/frontend/src/views/SharePage.vue b/frontend/src/views/SharePage.vue
new file mode 100644
index 0000000..4d859c2
--- /dev/null
+++ b/frontend/src/views/SharePage.vue
@@ -0,0 +1,450 @@
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
活动时间
+
{{ formatDate(activity.startTime) }}
+
+
+
+
+
+
+
活动地点
+
{{ activity.location }}
+
+
+
+
+
+
+
报名截止
+
{{ formatDate(activity.registrationDeadline) }}
+
+
+
+
+
+
+
+ 活动介绍
+
+
{{ activity.description }}
+
+
+
+
+
+ 已报名 {{ registrations.length }}人
+
+
+
+ {{ reg.name.charAt(0) }}
+
+
+ +{{ registrations.length - 10 }}
+
+
+
+
+
+
+
+ 查看详情并报名
+
+
+
+
+ 点击按钮查看完整活动信息
+
+
+
+
+
+
+
+
+
+ 返回首页
+
+
+
+
+
+
+
diff --git a/frontend/src/views/admin/ActivityManage.vue b/frontend/src/views/admin/ActivityManage.vue
new file mode 100644
index 0000000..1639d12
--- /dev/null
+++ b/frontend/src/views/admin/ActivityManage.vue
@@ -0,0 +1,2747 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
¥{{ totalExpense }}
+
总支出
+
+
+
+
+
+
{{ registrations.length }}
+
报名人数
+
+
+
+
+
+
{{ approvedPhotos.length + pendingPhotos.length }}
+
媒体数量
+
+
+
+
+
+
{{ registrations.filter(r => r.status === 'pending').length + pendingPhotos.length }}
+
待审核
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
¥{{ totalExpense }}
+
总支出
+
+
+
+
+
+
¥{{ activity.budget || '0' }}
+
预算
+
+
+
+
+
+
+ {{ activity.budget ? ((totalExpense / activity.budget) * 100).toFixed(1) : '0' }}%
+
+
使用率
+
+
+
+
+
+
{{ expenses.length }}
+
经费项
+
+
+
+
+
+
+
+
+
+
+
{{ expense.item }}
+
+ {{ expense.category }}
+ {{ expense.note }}
+
+
+
+
¥{{ expense.amount }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ registrations.filter(r => r.status === 'pending').length }}
+
待审核
+
+
+
+
+
+
{{ registrations.filter(r => r.status === 'approved').length }}
+
已通过
+
+
+
+
+
+
{{ registrations.filter(r => r.status === 'rejected').length }}
+
已拒绝
+
+
+
+
+
+
{{ registrations.length }}
+
总报名
+
+
+
+
+
+
{{ registrations.filter(r => r.checkInStatus).length }}
+
已签到
+
+
+
+
+
+
{{ registrations.filter(r => !r.checkInStatus).length }}
+
未签到
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ reg.name ? reg.name.charAt(0) : '?' }}
+
+
+
{{ reg.name || '未知' }}
+
+
+ 已签到
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ approvedPhotos.filter(p => p.type === 'image').length + pendingPhotos.filter(p => p.type === 'image').length }}
+
图片
+
+
+
+
+
+
{{ approvedPhotos.filter(p => p.type === 'video').length + pendingPhotos.filter(p => p.type === 'video').length }}
+
视频
+
+
+
+
+
+
{{ pendingPhotos.length }}
+
待审核
+
+
+
+
+
+
{{ approvedPhotos.length }}
+
已通过
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ result.name }}
+
{{ result.address }}
+
+
+
+
+
+ {{ selectedLocation.name || '请在地图上选择位置' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentEditReg.name }}
+ 当前人数:{{ currentEditReg.peopleCount || 1 }}人
+
+
+
+
+ 确定
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/admin/Dashboard.vue b/frontend/src/views/admin/Dashboard.vue
new file mode 100644
index 0000000..7fbc36a
--- /dev/null
+++ b/frontend/src/views/admin/Dashboard.vue
@@ -0,0 +1,920 @@
+
+
+
+
+
+
+
+
+
+
+
{{ activity.description }}
+
+
+
+ {{ activity.location }}
+
+
+
+ {{ formatDate(activity.startTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ result.name }}
+
{{ result.address }}
+
+
+
+
+
+ {{ selectedLocation.name || '请在地图上选择位置' }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/admin/Login.vue b/frontend/src/views/admin/Login.vue
new file mode 100644
index 0000000..6c210f4
--- /dev/null
+++ b/frontend/src/views/admin/Login.vue
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/vite.config.js b/frontend/vite.config.js
new file mode 100644
index 0000000..0cd1fb8
--- /dev/null
+++ b/frontend/vite.config.js
@@ -0,0 +1,15 @@
+import { defineConfig } from 'vite';
+import vue from '@vitejs/plugin-vue';
+
+export default defineConfig({
+ plugins: [vue()],
+ server: {
+ port: 5173,
+ proxy: {
+ '/api': {
+ target: 'http://localhost:3000',
+ changeOrigin: true
+ }
+ }
+ }
+});
diff --git a/start.bat b/start.bat
new file mode 100644
index 0000000..3c310be
--- /dev/null
+++ b/start.bat
@@ -0,0 +1,31 @@
+@echo off
+echo ========================================
+echo 泉友米车友会管理系统
+echo ========================================
+echo.
+echo 请确保已完成以下步骤:
+echo 1. 安装MySQL并创建数据库 quanyoumi
+echo 2. 配置 backend/.env 文件
+echo 3. 运行 node backend/init-admin.js 初始化管理员
+echo.
+echo 按任意键启动后端服务...
+pause > nul
+
+cd backend
+start cmd /k "npm run dev"
+
+echo.
+echo 后端服务已启动在 http://localhost:3000
+echo.
+echo 按任意键启动前端服务...
+pause > nul
+
+cd ../frontend
+start cmd /k "npm run dev"
+
+echo.
+echo 前端服务已启动在 http://localhost:5173
+echo 管理后台: http://localhost:5173/admin/login
+echo 默认账号: admin / admin123
+echo.
+pause
diff --git a/签到功能说明.md b/签到功能说明.md
new file mode 100644
index 0000000..fee5d5e
--- /dev/null
+++ b/签到功能说明.md
@@ -0,0 +1,53 @@
+# 签到功能实施说明
+
+## 已完成的修改
+
+### 1. 数据库修改
+- 创建了迁移脚本 `database-migration-checkin.sql`
+- 添加了两个字段:
+ - `checkInStatus` (BOOLEAN) - 签到状态
+ - `checkInTime` (DATETIME) - 签到时间
+
+### 2. 后端修改
+- **模型更新** (`backend/models/Registration.js`)
+ - 添加签到字段定义
+
+- **API接口** (`backend/routes/admin.js`)
+ - 新增 `PUT /admin/registrations/:id/checkin` - 签到/取消签到接口
+
+- **前端API** (`frontend/src/api/index.js`)
+ - 添加 `checkInRegistration` 方法
+
+### 3. 前端修改
+- **后台管理页面** (`frontend/src/views/admin/ActivityManage.vue`)
+ - 统计栏新增:已签到/未签到统计(一行三个布局)
+ - 报名列表显示签到状态标签
+ - 报名列表显示签到时间
+ - 添加签到/取消签到按钮(仅已通过审核的用户可签到)
+ - 手机号改为可点击拨打的链接
+ - 车牌号可点击复制
+
+## 使用步骤
+
+### 1. 执行数据库迁移
+```bash
+mysql -u root -p quanyoumi < database-migration-checkin.sql
+```
+
+### 2. 重启后端服务
+```bash
+cd backend
+npm start
+```
+
+### 3. 功能使用
+- 进入后台管理 -> 活动管理 -> 报名情况
+- 查看签到统计(已签到/未签到人数)
+- 点击"签到"按钮为用户签到
+- 点击手机号直接拨打电话
+- 点击车牌号复制到剪贴板
+
+## 注意事项
+- 只有审核通过的用户才能签到
+- 签到后可以取消签到
+- 签到时间会自动记录