diff --git a/.gitignore b/.gitignore
index 425ab26..72b9a92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,47 +1,47 @@
-# General
-.DS_Store
-.AppleDouble
-.LSOverride
-Icon
-._*
-Thumbs.db
-ehthumbs.db
-Desktop.ini
-*.log
-*.tmp
-*.bak
-*.swp
-*.swo
-*~
-.idea/
-.vscode/
-*.sublime-project
-*.sublime-workspace
-
-# Backend (Go)
-/mengyamonitor-backend/mengyamonitor-backend
-/mengyamonitor-backend/mengyamonitor-backend.exe
-/mengyamonitor-backend/*.exe
-/mengyamonitor-backend/*.out
-/mengyamonitor-backend/bin/
-/mengyamonitor-backend/dist/
-/mengyamonitor-backend/vendor/
-/mengyamonitor-backend/.env
-/mengyamonitor-backend/debug
-/mengyamonitor-backend/__debug_bin
-
-# Frontend (Node/React/Vite)
-/mengyamonitor-frontend/node_modules/
-/mengyamonitor-frontend/dist/
-/mengyamonitor-frontend/build/
-/mengyamonitor-frontend/coverage/
-/mengyamonitor-frontend/.env
-/mengyamonitor-frontend/.env.local
-/mengyamonitor-frontend/.env.development.local
-/mengyamonitor-frontend/.env.test.local
-/mengyamonitor-frontend/.env.production.local
-/mengyamonitor-frontend/npm-debug.log*
-/mengyamonitor-frontend/yarn-debug.log*
-/mengyamonitor-frontend/yarn-error.log*
-/mengyamonitor-frontend/pnpm-debug.log*
-/mengyamonitor-frontend/.eslintcache
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+Icon
+._*
+Thumbs.db
+ehthumbs.db
+Desktop.ini
+*.log
+*.tmp
+*.bak
+*.swp
+*.swo
+*~
+.idea/
+.vscode/
+*.sublime-project
+*.sublime-workspace
+
+# Backend (Go)
+/mengyamonitor-backend/mengyamonitor-backend
+/mengyamonitor-backend/mengyamonitor-backend.exe
+/mengyamonitor-backend/*.exe
+/mengyamonitor-backend/*.out
+/mengyamonitor-backend/bin/
+/mengyamonitor-backend/dist/
+/mengyamonitor-backend/vendor/
+/mengyamonitor-backend/.env
+/mengyamonitor-backend/debug
+/mengyamonitor-backend/__debug_bin
+
+# Frontend (Node/React/Vite)
+/mengyamonitor-frontend/node_modules/
+/mengyamonitor-frontend/dist/
+/mengyamonitor-frontend/build/
+/mengyamonitor-frontend/coverage/
+/mengyamonitor-frontend/.env
+/mengyamonitor-frontend/.env.local
+/mengyamonitor-frontend/.env.development.local
+/mengyamonitor-frontend/.env.test.local
+/mengyamonitor-frontend/.env.production.local
+/mengyamonitor-frontend/npm-debug.log*
+/mengyamonitor-frontend/yarn-debug.log*
+/mengyamonitor-frontend/yarn-error.log*
+/mengyamonitor-frontend/pnpm-debug.log*
+/mengyamonitor-frontend/.eslintcache
diff --git a/README.md b/README.md
index 991379d..54712b4 100644
--- a/README.md
+++ b/README.md
@@ -1,156 +1,156 @@
-# 萌芽监控面板
-
-一个简洁高效的 Linux 服务器监控面板,采用前后端分离架构。
-
-## 项目概述
-
-### 功能
-- 实时监控 Linux 服务器的 CPU、内存、存储、GPU 使用情况
-- 支持同时监控多个服务器
-- 卡片式展示,直观清晰
-- 详情弹窗查看完整信息
-
-### 技术栈
-- **前端**: React 19 + TypeScript + Vite
-- **后端**: Go (原生 net/http 库)
-- **风格**: 白色柔和风格界面
-
-## 快速开始
-
-### 后端部署
-
-1. 进入后端目录
-```bash
-cd mengyamonitor-backend
-```
-
-2. 编译(在 Linux 服务器上)
-```bash
-go build -o mengyamonitor-backend
-```
-
-3. 运行
-```bash
-./mengyamonitor-backend
-```
-默认监听端口: 9292
-
-4. 可选:配置环境变量
-```bash
-PORT=8080 ./mengyamonitor-backend
-```
-
-### 前端开发
-
-1. 进入前端目录
-```bash
-cd mengyamonitor-frontend
-```
-
-2. 安装依赖
-```bash
-npm install
-```
-
-3. 启动开发服务器
-```bash
-npm run dev
-```
-默认访问端口: 2929
-
-4. 构建生产版本
-```bash
-npm run build
-```
-
-## 使用说明
-
-### 1. 部署后端到服务器
-将编译好的 `mengyamonitor-backend` 二进制文件上传到需要监控的 Linux 服务器并运行。
-
-### 2. 配置前端
-在前端界面点击"添加服务器",输入:
-- 服务器名称:例如"生产服务器1"
-- 服务器地址:例如"http://192.168.1.100:9292"
-
-### 3. 查看监控数据
-- 主界面显示所有服务器的基本信息(CPU、内存使用率)
-- 点击"查看详情"可查看完整的系统信息
-- 数据每2秒自动刷新
-
-## 项目结构
-
-```
-萌芽监控面板/
-├── mengyamonitor-backend/ # 后端服务
-│ ├── main.go # 主程序和HTTP服务器
-│ ├── systeminfo.go # 系统信息采集
-│ ├── go.mod # Go模块配置
-│ └── README.md # 后端文档
-│
-├── mengyamonitor-frontend/ # 前端应用
-│ ├── src/
-│ │ ├── api/ # API调用层
-│ │ ├── components/ # React组件
-│ │ ├── hooks/ # 自定义Hooks
-│ │ ├── types/ # TypeScript类型
-│ │ ├── utils/ # 工具函数
-│ │ ├── App.tsx # 主应用
-│ │ └── main.tsx # 入口文件
-│ ├── package.json
-│ ├── vite.config.ts
-│ └── README.md # 前端文档
-│
-└── 需求.txt # 需求文档
-```
-
-## API 接口
-
-### GET /api/health
-健康检查
-
-### GET /api/metrics
-获取系统监控指标
-```json
-{
- "data": {
- "hostname": "server1",
- "timestamp": "2025-12-10T10:00:00Z",
- "cpu": { "usagePercent": 23.45, ... },
- "memory": { "usedPercent": 50.0, ... },
- "storage": [...],
- "gpu": [...],
- "os": { ... },
- "uptimeSeconds": 864000.5
- }
-}
-```
-
-## 注意事项
-
-1. **系统支持**: 后端仅支持 Linux 系统
-2. **权限要求**: 需要读取 `/proc` 文件系统的权限
-3. **GPU 监控**: 需要安装 `nvidia-smi` 工具(可选)
-4. **网络访问**: 确保前端可以访问后端的 9292 端口
-5. **CORS**: 后端已配置允许跨域访问
-
-## 常见问题
-
-**Q: 前端无法连接后端?**
-A: 检查服务器防火墙是否开放 9292 端口,确保后端服务正在运行。
-
-**Q: GPU 信息显示不可用?**
-A: 如果服务器没有 NVIDIA GPU 或未安装 nvidia-smi,GPU 信息会显示为"不可用",这是正常的。
-
-**Q: 如何将前端打包成桌面应用?**
-A: 可以使用 Electron 或 Tauri 框架将前端打包成桌面应用,详见前端 README。
-
-## 开发者
-
-- 前后端分离架构,代码结构清晰
-- 符合企业级开发规范
-- 易于扩展和维护
-
-## License
-
-MIT
+# 萌芽监控面板
+
+一个简洁高效的 Linux 服务器监控面板,采用前后端分离架构。
+
+## 项目概述
+
+### 功能
+- 实时监控 Linux 服务器的 CPU、内存、存储、GPU 使用情况
+- 支持同时监控多个服务器
+- 卡片式展示,直观清晰
+- 详情弹窗查看完整信息
+
+### 技术栈
+- **前端**: React 19 + TypeScript + Vite
+- **后端**: Go (原生 net/http 库)
+- **风格**: 白色柔和风格界面
+
+## 快速开始
+
+### 后端部署
+
+1. 进入后端目录
+```bash
+cd mengyamonitor-backend
+```
+
+2. 编译(在 Linux 服务器上)
+```bash
+go build -o mengyamonitor-backend
+```
+
+3. 运行
+```bash
+./mengyamonitor-backend
+```
+默认监听端口: 9292
+
+4. 可选:配置环境变量
+```bash
+PORT=8080 ./mengyamonitor-backend
+```
+
+### 前端开发
+
+1. 进入前端目录
+```bash
+cd mengyamonitor-frontend
+```
+
+2. 安装依赖
+```bash
+npm install
+```
+
+3. 启动开发服务器
+```bash
+npm run dev
+```
+默认访问端口: 2929
+
+4. 构建生产版本
+```bash
+npm run build
+```
+
+## 使用说明
+
+### 1. 部署后端到服务器
+将编译好的 `mengyamonitor-backend` 二进制文件上传到需要监控的 Linux 服务器并运行。
+
+### 2. 配置前端
+在前端界面点击"添加服务器",输入:
+- 服务器名称:例如"生产服务器1"
+- 服务器地址:例如"http://192.168.1.100:9292"
+
+### 3. 查看监控数据
+- 主界面显示所有服务器的基本信息(CPU、内存使用率)
+- 点击"查看详情"可查看完整的系统信息
+- 数据每2秒自动刷新
+
+## 项目结构
+
+```
+萌芽监控面板/
+├── mengyamonitor-backend/ # 后端服务
+│ ├── main.go # 主程序和HTTP服务器
+│ ├── systeminfo.go # 系统信息采集
+│ ├── go.mod # Go模块配置
+│ └── README.md # 后端文档
+│
+├── mengyamonitor-frontend/ # 前端应用
+│ ├── src/
+│ │ ├── api/ # API调用层
+│ │ ├── components/ # React组件
+│ │ ├── hooks/ # 自定义Hooks
+│ │ ├── types/ # TypeScript类型
+│ │ ├── utils/ # 工具函数
+│ │ ├── App.tsx # 主应用
+│ │ └── main.tsx # 入口文件
+│ ├── package.json
+│ ├── vite.config.ts
+│ └── README.md # 前端文档
+│
+└── 需求.txt # 需求文档
+```
+
+## API 接口
+
+### GET /api/health
+健康检查
+
+### GET /api/metrics
+获取系统监控指标
+```json
+{
+ "data": {
+ "hostname": "server1",
+ "timestamp": "2025-12-10T10:00:00Z",
+ "cpu": { "usagePercent": 23.45, ... },
+ "memory": { "usedPercent": 50.0, ... },
+ "storage": [...],
+ "gpu": [...],
+ "os": { ... },
+ "uptimeSeconds": 864000.5
+ }
+}
+```
+
+## 注意事项
+
+1. **系统支持**: 后端仅支持 Linux 系统
+2. **权限要求**: 需要读取 `/proc` 文件系统的权限
+3. **GPU 监控**: 需要安装 `nvidia-smi` 工具(可选)
+4. **网络访问**: 确保前端可以访问后端的 9292 端口
+5. **CORS**: 后端已配置允许跨域访问
+
+## 常见问题
+
+**Q: 前端无法连接后端?**
+A: 检查服务器防火墙是否开放 9292 端口,确保后端服务正在运行。
+
+**Q: GPU 信息显示不可用?**
+A: 如果服务器没有 NVIDIA GPU 或未安装 nvidia-smi,GPU 信息会显示为"不可用",这是正常的。
+
+**Q: 如何将前端打包成桌面应用?**
+A: 可以使用 Electron 或 Tauri 框架将前端打包成桌面应用,详见前端 README。
+
+## 开发者
+
+- 前后端分离架构,代码结构清晰
+- 符合企业级开发规范
+- 易于扩展和维护
+
+## License
+
+MIT
diff --git a/build-frontend.bat b/build-frontend.bat
new file mode 100644
index 0000000..f9feee2
--- /dev/null
+++ b/build-frontend.bat
@@ -0,0 +1,7 @@
+@echo off
+chcp 65001 >nul
+echo 构建前端项目...
+cd mengyamonitor-frontend
+echo 正在安装依赖...
+call npm install
+npm run build
diff --git a/mengyamonitor-backend/BUILD.md b/mengyamonitor-backend/BUILD.md
deleted file mode 100644
index 7550137..0000000
--- a/mengyamonitor-backend/BUILD.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# 编译说明 - 兼容旧版本系统
-
-## 问题说明
-
-如果在 Debian 11 或其他旧版本系统上运行时出现 GLIBC 版本错误:
-```
-./mengyamonitor-backend: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
-```
-
-这是因为编译时使用了较新版本的 GLIBC,而目标系统的 GLIBC 版本较旧。
-
-## 解决方案
-
-### 方案 1:在目标系统上编译(推荐)
-
-在 Debian 11 服务器上直接编译:
-
-```bash
-cd mengyamonitor-backend
-
-# 禁用 CGO,静态链接
-export CGO_ENABLED=0
-go build -ldflags="-s -w" -o mengyamonitor-backend .
-
-# 或者使用提供的脚本
-chmod +x build.sh
-./build.sh
-```
-
-### 方案 2:使用静态链接编译
-
-在任何系统上编译,但使用静态链接:
-
-```bash
-cd mengyamonitor-backend
-
-# 禁用 CGO
-export CGO_ENABLED=0
-export GOOS=linux
-export GOARCH=amd64
-
-# 编译(静态链接,不依赖系统库)
-go build -ldflags="-s -w" -o mengyamonitor-backend .
-```
-
-### 方案 3:使用 Docker 编译
-
-使用 Docker 在 Debian 11 环境中编译:
-
-```bash
-# 使用 Debian 11 镜像编译
-docker run --rm -v $(pwd):/app -w /app golang:1.21-bullseye sh -c "
- export CGO_ENABLED=0
- go build -ldflags='-s -w' -o mengyamonitor-backend .
-"
-
-# 或者使用多阶段构建
-docker build -t mengyamonitor-backend -f Dockerfile.build .
-```
-
-## 验证编译结果
-
-编译完成后,检查二进制文件:
-
-```bash
-# 检查文件类型
-file mengyamonitor-backend
-
-# 检查依赖(如果是静态链接,应该显示 "not a dynamic executable")
-ldd mengyamonitor-backend
-
-# 检查 GLIBC 依赖(应该没有或很少)
-objdump -T mengyamonitor-backend | grep GLIBC
-```
-
-## 编译参数说明
-
-- `CGO_ENABLED=0`: 禁用 CGO,使用纯 Go 实现,不依赖系统 C 库
-- `-ldflags="-s -w"`: 减小二进制文件大小
- - `-s`: 省略符号表和调试信息
- - `-w`: 省略 DWARF 符号表
-
-## 注意事项
-
-1. 禁用 CGO 后,某些需要 C 库的功能可能不可用,但本项目不依赖 CGO
-2. 静态链接的二进制文件会稍大一些,但兼容性更好
-3. 如果必须使用 CGO,需要在目标系统上编译,或使用相同 GLIBC 版本的系统编译
-
diff --git a/mengyamonitor-backend/README.md b/mengyamonitor-backend/README.md
index 160f6fe..da6aad8 100644
--- a/mengyamonitor-backend/README.md
+++ b/mengyamonitor-backend/README.md
@@ -1,121 +1,121 @@
-# 萌芽监控面板 - 后端服务
-
-## 概述
-Linux 服务器监控后端服务,使用 Go 原生 net/http 库实现。
-
-## 功能
-- CPU 使用率和负载监控
-- 内存使用情况
-- 磁盘存储监控
-- GPU 监控(支持 NVIDIA)
-- 操作系统信息
-- 系统运行时间
-
-## API 端点
-
-### `GET /api/health`
-健康检查端点
-```json
-{
- "status": "ok",
- "timestamp": "2025-12-10T10:00:00Z"
-}
-```
-
-### `GET /api/metrics`
-获取系统监控指标
-```json
-{
- "data": {
- "hostname": "server1",
- "timestamp": "2025-12-10T10:00:00Z",
- "cpu": {
- "model": "Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz",
- "cores": 8,
- "usagePercent": 23.45,
- "loadAverages": [1.2, 1.5, 1.8]
- },
- "memory": {
- "totalBytes": 16777216000,
- "usedBytes": 8388608000,
- "freeBytes": 8388608000,
- "usedPercent": 50.0
- },
- "storage": [{
- "mount": "/",
- "totalBytes": 107374182400,
- "usedBytes": 53687091200,
- "freeBytes": 53687091200,
- "usedPercent": 50.0
- }],
- "gpu": [{
- "name": "Tesla T4",
- "memoryTotalMB": 15360,
- "memoryUsedMB": 512,
- "utilizationPercent": 15.0,
- "status": "ok"
- }],
- "os": {
- "kernel": "Linux version 5.15.0",
- "distro": "Ubuntu 22.04 LTS",
- "architecture": "amd64"
- },
- "uptimeSeconds": 864000.5
- }
-}
-```
-
-## 运行方式
-
-### 开发环境
-```bash
-go run .
-```
-
-### 生产环境
-
-#### 标准编译
-```bash
-# 编译
-go build -o mengyamonitor-backend
-
-# 运行
-./mengyamonitor-backend
-```
-
-#### 兼容旧版本系统编译(推荐)
-
-如果需要在 Debian 11 或其他旧版本系统上运行,使用静态链接编译:
-
-```bash
-# 禁用 CGO,静态链接(不依赖系统 GLIBC 版本)
-export CGO_ENABLED=0
-go build -ldflags="-s -w" -o mengyamonitor-backend .
-
-# 或使用提供的脚本
-chmod +x build.sh
-./build.sh
-```
-
-这样可以避免 GLIBC 版本兼容性问题。详细说明请参考 [BUILD.md](./BUILD.md)。
-
-### 环境变量
-- `HOST`: 监听地址,默认 `0.0.0.0`
-- `PORT`: 监听端口,默认 `9292`
-
-示例:
-```bash
-PORT=8080 ./mengyamonitor-backend
-```
-
-## 部署到服务器
-
-1. 将编译好的二进制文件上传到目标服务器
-2. 赋予执行权限:`chmod +x mengyamonitor-backend`
-3. 运行服务:`./mengyamonitor-backend`
-4. 可选:使用 systemd 或 supervisor 管理服务进程
-
-## 注意事项
-- 仅支持 Linux 系统
-- GPU 监控需要安装 nvidia-smi 工具
-- 需要读取 /proc 文件系统的权限
+# 萌芽监控面板 - 后端服务
+
+## 概述
+Linux 服务器监控后端服务,使用 Go 原生 net/http 库实现。
+
+## 功能
+- CPU 使用率和负载监控
+- 内存使用情况
+- 磁盘存储监控
+- GPU 监控(支持 NVIDIA)
+- 操作系统信息
+- 系统运行时间
+
+## API 端点
+
+### `GET /api/health`
+健康检查端点
+```json
+{
+ "status": "ok",
+ "timestamp": "2025-12-10T10:00:00Z"
+}
+```
+
+### `GET /api/metrics`
+获取系统监控指标
+```json
+{
+ "data": {
+ "hostname": "server1",
+ "timestamp": "2025-12-10T10:00:00Z",
+ "cpu": {
+ "model": "Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz",
+ "cores": 8,
+ "usagePercent": 23.45,
+ "loadAverages": [1.2, 1.5, 1.8]
+ },
+ "memory": {
+ "totalBytes": 16777216000,
+ "usedBytes": 8388608000,
+ "freeBytes": 8388608000,
+ "usedPercent": 50.0
+ },
+ "storage": [{
+ "mount": "/",
+ "totalBytes": 107374182400,
+ "usedBytes": 53687091200,
+ "freeBytes": 53687091200,
+ "usedPercent": 50.0
+ }],
+ "gpu": [{
+ "name": "Tesla T4",
+ "memoryTotalMB": 15360,
+ "memoryUsedMB": 512,
+ "utilizationPercent": 15.0,
+ "status": "ok"
+ }],
+ "os": {
+ "kernel": "Linux version 5.15.0",
+ "distro": "Ubuntu 22.04 LTS",
+ "architecture": "amd64"
+ },
+ "uptimeSeconds": 864000.5
+ }
+}
+```
+
+## 运行方式
+
+### 开发环境
+```bash
+go run .
+```
+
+### 生产环境
+
+#### 标准编译
+```bash
+# 编译
+go build -o mengyamonitor-backend
+
+# 运行
+./mengyamonitor-backend
+```
+
+#### 兼容旧版本系统编译(推荐)
+
+如果需要在 Debian 11 或其他旧版本系统上运行,使用静态链接编译:
+
+```bash
+# 禁用 CGO,静态链接(不依赖系统 GLIBC 版本)
+export CGO_ENABLED=0
+go build -ldflags="-s -w" -o mengyamonitor-backend .
+
+# 或使用提供的脚本
+chmod +x build.sh
+./build.sh
+```
+
+这样可以避免 GLIBC 版本兼容性问题。详细说明请参考 [BUILD.md](./BUILD.md)。
+
+### 环境变量
+- `HOST`: 监听地址,默认 `0.0.0.0`
+- `PORT`: 监听端口,默认 `9292`
+
+示例:
+```bash
+PORT=8080 ./mengyamonitor-backend
+```
+
+## 部署到服务器
+
+1. 将编译好的二进制文件上传到目标服务器
+2. 赋予执行权限:`chmod +x mengyamonitor-backend`
+3. 运行服务:`./mengyamonitor-backend`
+4. 可选:使用 systemd 或 supervisor 管理服务进程
+
+## 注意事项
+- 仅支持 Linux 系统
+- GPU 监控需要安装 nvidia-smi 工具
+- 需要读取 /proc 文件系统的权限
diff --git a/mengyamonitor-backend/build.sh b/mengyamonitor-backend/build_amd64.sh
similarity index 100%
rename from mengyamonitor-backend/build.sh
rename to mengyamonitor-backend/build_amd64.sh
diff --git a/mengyamonitor-backend/build_arm64.sh b/mengyamonitor-backend/build_arm64.sh
new file mode 100644
index 0000000..a51970a
--- /dev/null
+++ b/mengyamonitor-backend/build_arm64.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Linux ARM64 交叉编译脚本
+
+echo "开始交叉编译 mengyamonitor-backend (Linux ARM64)..."
+
+# 禁用 CGO,使用纯 Go 编译(不依赖系统 C 库)
+export CGO_ENABLED=0
+
+# 设置目标平台为 Linux ARM64
+export GOOS=linux
+export GOARCH=arm64
+
+# 编译(静态链接)
+go build -ldflags="-s -w" -o mengyamonitor-backend-arm64 .
+
+if [ $? -eq 0 ]; then
+ echo "编译成功!"
+ echo "二进制文件: mengyamonitor-backend-arm64"
+ echo ""
+ echo "目标平台: Linux ARM64"
+ echo "编译模式: 静态链接,无外部依赖"
+ echo ""
+ echo "检查文件信息:"
+ file mengyamonitor-backend-arm64 2>/dev/null || echo "文件已生成: mengyamonitor-backend-arm64"
+ echo ""
+ ls -lh mengyamonitor-backend-arm64
+else
+ echo "编译失败!"
+ exit 1
+fi
diff --git a/mengyamonitor-backend/collector.go b/mengyamonitor-backend/collector.go
index 0e7078f..ace0ecf 100644
--- a/mengyamonitor-backend/collector.go
+++ b/mengyamonitor-backend/collector.go
@@ -1,103 +1,103 @@
-package main
-
-import (
- "bufio"
- "os"
- "runtime"
- "strconv"
- "strings"
- "time"
-)
-
-// CollectMetrics 收集所有系统监控指标
-func CollectMetrics() (*Metrics, error) {
- hostname, _ := os.Hostname()
-
- cpuModel := firstMatchInFile("/proc/cpuinfo", "model name")
- cpuUsage, err := readCPUUsage()
- if err != nil {
- return nil, err
- }
- cpuTemp := readCPUTemperature()
- perCoreUsage := readPerCoreUsage()
-
- mem, err := readMemory()
- if err != nil {
- return nil, err
- }
-
- storage, err := readAllStorage()
- if err != nil {
- return nil, err
- }
-
- gpu := readGPU()
- network := readNetworkInterfaces()
- systemStats := readSystemStats()
- systemStats.DockerStats = readDockerStats()
-
- osInfo := readOSInfo()
- uptime := readUptime()
-
- loads := readLoadAverages()
-
- return &Metrics{
- Hostname: hostname,
- Timestamp: time.Now().UTC(),
- CPU: CPUMetrics{
- Model: cpuModel,
- Cores: runtime.NumCPU(),
- UsagePercent: round(cpuUsage, 2),
- LoadAverages: loads,
- Temperature: cpuTemp,
- PerCoreUsage: perCoreUsage,
- },
- Memory: mem,
- Storage: storage,
- GPU: gpu,
- Network: network,
- System: systemStats,
- OS: osInfo,
- UptimeSeconds: uptime,
- }, nil
-}
-
-func readOSInfo() OSInfo {
- distro := readOSRelease()
- kernel := strings.TrimSpace(readFirstLine("/proc/version"))
- arch := runtime.GOARCH
- return OSInfo{
- Kernel: kernel,
- Distro: distro,
- Architecture: arch,
- }
-}
-
-func readOSRelease() string {
- f, err := os.Open("/etc/os-release")
- if err != nil {
- return runtime.GOOS
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- if strings.HasPrefix(line, "PRETTY_NAME=") {
- return strings.Trim(line[len("PRETTY_NAME="):], "\"")
- }
- }
- return runtime.GOOS
-}
-
-func readUptime() float64 {
- line := readFirstLine("/proc/uptime")
- fields := strings.Fields(line)
- if len(fields) == 0 {
- return 0
- }
- v, err := strconv.ParseFloat(fields[0], 64)
- if err != nil {
- return 0
- }
- return v
-}
+package main
+
+import (
+ "bufio"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// CollectMetrics 收集所有系统监控指标
+func CollectMetrics() (*Metrics, error) {
+ hostname, _ := os.Hostname()
+
+ cpuModel := firstMatchInFile("/proc/cpuinfo", "model name")
+ cpuUsage, err := readCPUUsage()
+ if err != nil {
+ return nil, err
+ }
+ cpuTemp := readCPUTemperature()
+ perCoreUsage := readPerCoreUsage()
+
+ mem, err := readMemory()
+ if err != nil {
+ return nil, err
+ }
+
+ storage, err := readAllStorage()
+ if err != nil {
+ return nil, err
+ }
+
+ gpu := readGPU()
+ network := readNetworkInterfaces()
+ systemStats := readSystemStats()
+ systemStats.DockerStats = readDockerStats()
+
+ osInfo := readOSInfo()
+ uptime := readUptime()
+
+ loads := readLoadAverages()
+
+ return &Metrics{
+ Hostname: hostname,
+ Timestamp: time.Now().UTC(),
+ CPU: CPUMetrics{
+ Model: cpuModel,
+ Cores: runtime.NumCPU(),
+ UsagePercent: round(cpuUsage, 2),
+ LoadAverages: loads,
+ Temperature: cpuTemp,
+ PerCoreUsage: perCoreUsage,
+ },
+ Memory: mem,
+ Storage: storage,
+ GPU: gpu,
+ Network: network,
+ System: systemStats,
+ OS: osInfo,
+ UptimeSeconds: uptime,
+ }, nil
+}
+
+func readOSInfo() OSInfo {
+ distro := readOSRelease()
+ kernel := strings.TrimSpace(readFirstLine("/proc/version"))
+ arch := runtime.GOARCH
+ return OSInfo{
+ Kernel: kernel,
+ Distro: distro,
+ Architecture: arch,
+ }
+}
+
+func readOSRelease() string {
+ f, err := os.Open("/etc/os-release")
+ if err != nil {
+ return runtime.GOOS
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.HasPrefix(line, "PRETTY_NAME=") {
+ return strings.Trim(line[len("PRETTY_NAME="):], "\"")
+ }
+ }
+ return runtime.GOOS
+}
+
+func readUptime() float64 {
+ line := readFirstLine("/proc/uptime")
+ fields := strings.Fields(line)
+ if len(fields) == 0 {
+ return 0
+ }
+ v, err := strconv.ParseFloat(fields[0], 64)
+ if err != nil {
+ return 0
+ }
+ return v
+}
diff --git a/mengyamonitor-backend/cpu.go b/mengyamonitor-backend/cpu.go
index d6994b1..4850a51 100644
--- a/mengyamonitor-backend/cpu.go
+++ b/mengyamonitor-backend/cpu.go
@@ -1,182 +1,182 @@
-package main
-
-import (
- "bufio"
- "errors"
- "os"
- "strconv"
- "strings"
- "time"
-)
-
-// readCPUUsage 读取CPU整体使用率
-func readCPUUsage() (float64, error) {
- idle1, total1, err := readCPUTicks()
- if err != nil {
- return 0, err
- }
- time.Sleep(250 * time.Millisecond)
- idle2, total2, err := readCPUTicks()
- if err != nil {
- return 0, err
- }
- if total2 == total1 {
- return 0, errors.New("cpu totals unchanged")
- }
- idleDelta := float64(idle2 - idle1)
- totalDelta := float64(total2 - total1)
- usage := (1.0 - idleDelta/totalDelta) * 100
- if usage < 0 {
- usage = 0
- }
- return usage, nil
-}
-
-// readCPUTicks 读取CPU的idle和total ticks
-func readCPUTicks() (idle, total uint64, err error) {
- f, err := os.Open("/proc/stat")
- if err != nil {
- return 0, 0, err
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- if !scanner.Scan() {
- return 0, 0, errors.New("failed to scan /proc/stat")
- }
- fields := strings.Fields(scanner.Text())
- if len(fields) < 5 {
- return 0, 0, errors.New("unexpected /proc/stat format")
- }
- // fields[0] is "cpu"
- var vals []uint64
- for _, f := range fields[1:] {
- v, err := strconv.ParseUint(f, 10, 64)
- if err != nil {
- return 0, 0, err
- }
- vals = append(vals, v)
- }
- for _, v := range vals {
- total += v
- }
- if len(vals) > 3 {
- idle = vals[3] // idle time
- // 注意:不包含 iowait,因为 iowait 不算真正的空闲时间
- // 如果系统有 iowait,它会在 total 中,但不应该算作 idle
- }
- return idle, total, nil
-}
-
-// readPerCoreUsage 读取每个CPU核心的使用率
-func readPerCoreUsage() []CoreUsage {
- coreUsages := []CoreUsage{}
-
- // 第一次读取
- cores1 := readPerCoreTicks()
- time.Sleep(100 * time.Millisecond) // 减少到100ms
- // 第二次读取
- cores2 := readPerCoreTicks()
-
- for i := 0; i < len(cores1) && i < len(cores2); i++ {
- idle1, total1 := cores1[i][0], cores1[i][1]
- idle2, total2 := cores2[i][0], cores2[i][1]
-
- if total2 == total1 {
- continue
- }
-
- idleDelta := float64(idle2 - idle1)
- totalDelta := float64(total2 - total1)
- usage := (1.0 - idleDelta/totalDelta) * 100
- if usage < 0 {
- usage = 0
- }
-
- coreUsages = append(coreUsages, CoreUsage{
- Core: i,
- Percent: round(usage, 1),
- })
- }
-
- return coreUsages
-}
-
-// readPerCoreTicks 读取每个CPU核心的ticks
-func readPerCoreTicks() [][2]uint64 {
- var result [][2]uint64
-
- f, err := os.Open("/proc/stat")
- if err != nil {
- return result
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- if !strings.HasPrefix(line, "cpu") {
- continue
- }
- if strings.HasPrefix(line, "cpu ") {
- continue // 跳过总的cpu行
- }
-
- fields := strings.Fields(line)
- if len(fields) < 5 {
- continue
- }
-
- var vals []uint64
- for _, f := range fields[1:] {
- v, err := strconv.ParseUint(f, 10, 64)
- if err != nil {
- break
- }
- vals = append(vals, v)
- }
-
- if len(vals) < 5 {
- continue
- }
-
- var total, idle uint64
- for _, v := range vals {
- total += v
- }
- idle = vals[3] // idle time only, not including iowait
-
- result = append(result, [2]uint64{idle, total})
- }
-
- return result
-}
-
-// readCPUTemperature 读取CPU温度
-func readCPUTemperature() float64 {
- // 尝试从常见位置读取温度
- paths := []string{
- "/sys/class/thermal/thermal_zone0/temp",
- "/sys/class/hwmon/hwmon0/temp1_input",
- "/sys/class/hwmon/hwmon1/temp1_input",
- }
- for _, path := range paths {
- if temp := readTempFromFile(path); temp > 0 {
- return temp
- }
- }
- return 0
-}
-
-// readLoadAverages 读取系统负载平均值
-func readLoadAverages() []float64 {
- line := readFirstLine("/proc/loadavg")
- fields := strings.Fields(line)
- res := make([]float64, 0, 3)
- for i := 0; i < len(fields) && i < 3; i++ {
- v, err := strconv.ParseFloat(fields[i], 64)
- if err == nil {
- res = append(res, v)
- }
- }
- return res
-}
+package main
+
+import (
+ "bufio"
+ "errors"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// readCPUUsage 读取CPU整体使用率
+func readCPUUsage() (float64, error) {
+ idle1, total1, err := readCPUTicks()
+ if err != nil {
+ return 0, err
+ }
+ time.Sleep(250 * time.Millisecond)
+ idle2, total2, err := readCPUTicks()
+ if err != nil {
+ return 0, err
+ }
+ if total2 == total1 {
+ return 0, errors.New("cpu totals unchanged")
+ }
+ idleDelta := float64(idle2 - idle1)
+ totalDelta := float64(total2 - total1)
+ usage := (1.0 - idleDelta/totalDelta) * 100
+ if usage < 0 {
+ usage = 0
+ }
+ return usage, nil
+}
+
+// readCPUTicks 读取CPU的idle和total ticks
+func readCPUTicks() (idle, total uint64, err error) {
+ f, err := os.Open("/proc/stat")
+ if err != nil {
+ return 0, 0, err
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ if !scanner.Scan() {
+ return 0, 0, errors.New("failed to scan /proc/stat")
+ }
+ fields := strings.Fields(scanner.Text())
+ if len(fields) < 5 {
+ return 0, 0, errors.New("unexpected /proc/stat format")
+ }
+ // fields[0] is "cpu"
+ var vals []uint64
+ for _, f := range fields[1:] {
+ v, err := strconv.ParseUint(f, 10, 64)
+ if err != nil {
+ return 0, 0, err
+ }
+ vals = append(vals, v)
+ }
+ for _, v := range vals {
+ total += v
+ }
+ if len(vals) > 3 {
+ idle = vals[3] // idle time
+ // 注意:不包含 iowait,因为 iowait 不算真正的空闲时间
+ // 如果系统有 iowait,它会在 total 中,但不应该算作 idle
+ }
+ return idle, total, nil
+}
+
+// readPerCoreUsage 读取每个CPU核心的使用率
+func readPerCoreUsage() []CoreUsage {
+ coreUsages := []CoreUsage{}
+
+ // 第一次读取
+ cores1 := readPerCoreTicks()
+ time.Sleep(100 * time.Millisecond) // 减少到100ms
+ // 第二次读取
+ cores2 := readPerCoreTicks()
+
+ for i := 0; i < len(cores1) && i < len(cores2); i++ {
+ idle1, total1 := cores1[i][0], cores1[i][1]
+ idle2, total2 := cores2[i][0], cores2[i][1]
+
+ if total2 == total1 {
+ continue
+ }
+
+ idleDelta := float64(idle2 - idle1)
+ totalDelta := float64(total2 - total1)
+ usage := (1.0 - idleDelta/totalDelta) * 100
+ if usage < 0 {
+ usage = 0
+ }
+
+ coreUsages = append(coreUsages, CoreUsage{
+ Core: i,
+ Percent: round(usage, 1),
+ })
+ }
+
+ return coreUsages
+}
+
+// readPerCoreTicks 读取每个CPU核心的ticks
+func readPerCoreTicks() [][2]uint64 {
+ var result [][2]uint64
+
+ f, err := os.Open("/proc/stat")
+ if err != nil {
+ return result
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if !strings.HasPrefix(line, "cpu") {
+ continue
+ }
+ if strings.HasPrefix(line, "cpu ") {
+ continue // 跳过总的cpu行
+ }
+
+ fields := strings.Fields(line)
+ if len(fields) < 5 {
+ continue
+ }
+
+ var vals []uint64
+ for _, f := range fields[1:] {
+ v, err := strconv.ParseUint(f, 10, 64)
+ if err != nil {
+ break
+ }
+ vals = append(vals, v)
+ }
+
+ if len(vals) < 5 {
+ continue
+ }
+
+ var total, idle uint64
+ for _, v := range vals {
+ total += v
+ }
+ idle = vals[3] // idle time only, not including iowait
+
+ result = append(result, [2]uint64{idle, total})
+ }
+
+ return result
+}
+
+// readCPUTemperature 读取CPU温度
+func readCPUTemperature() float64 {
+ // 尝试从常见位置读取温度
+ paths := []string{
+ "/sys/class/thermal/thermal_zone0/temp",
+ "/sys/class/hwmon/hwmon0/temp1_input",
+ "/sys/class/hwmon/hwmon1/temp1_input",
+ }
+ for _, path := range paths {
+ if temp := readTempFromFile(path); temp > 0 {
+ return temp
+ }
+ }
+ return 0
+}
+
+// readLoadAverages 读取系统负载平均值
+func readLoadAverages() []float64 {
+ line := readFirstLine("/proc/loadavg")
+ fields := strings.Fields(line)
+ res := make([]float64, 0, 3)
+ for i := 0; i < len(fields) && i < 3; i++ {
+ v, err := strconv.ParseFloat(fields[i], 64)
+ if err == nil {
+ res = append(res, v)
+ }
+ }
+ return res
+}
diff --git a/mengyamonitor-backend/go.mod b/mengyamonitor-backend/go.mod
index 9920de7..ddf7f21 100644
--- a/mengyamonitor-backend/go.mod
+++ b/mengyamonitor-backend/go.mod
@@ -1,3 +1,3 @@
-module mengyamonitor-backend
-
-go 1.22
+module mengyamonitor-backend
+
+go 1.22
diff --git a/mengyamonitor-backend/gpu.go b/mengyamonitor-backend/gpu.go
index 3bc6900..e0d4a7e 100644
--- a/mengyamonitor-backend/gpu.go
+++ b/mengyamonitor-backend/gpu.go
@@ -1,48 +1,48 @@
-package main
-
-import (
- "os/exec"
- "strconv"
- "strings"
-)
-
-// readGPU 读取GPU信息
-func readGPU() []GPUMetrics {
- _, err := exec.LookPath("nvidia-smi")
- if err != nil {
- return []GPUMetrics{{Status: "not_available"}}
- }
- // Query GPU info including temperature
- cmd := exec.Command("nvidia-smi", "--query-gpu=name,memory.total,memory.used,utilization.gpu,temperature.gpu", "--format=csv,noheader,nounits")
- out, err := cmd.Output()
- if err != nil {
- return []GPUMetrics{{Status: "error", Name: "nvidia-smi", UtilizationPercent: 0}}
- }
- lines := strings.Split(strings.TrimSpace(string(out)), "\n")
- gpus := make([]GPUMetrics, 0, len(lines))
- for _, line := range lines {
- parts := strings.Split(line, ",")
- for i := range parts {
- parts[i] = strings.TrimSpace(parts[i])
- }
- if len(parts) < 5 {
- continue
- }
- total, _ := strconv.ParseInt(parts[1], 10, 64)
- used, _ := strconv.ParseInt(parts[2], 10, 64)
- util, _ := strconv.ParseFloat(parts[3], 64)
- temp, _ := strconv.ParseFloat(parts[4], 64)
- gpus = append(gpus, GPUMetrics{
- Name: parts[0],
- MemoryTotalMB: total,
- MemoryUsedMB: used,
- UtilizationPercent: round(util, 2),
- Temperature: temp,
- Status: "ok",
- })
- }
- if len(gpus) == 0 {
- return []GPUMetrics{{Status: "not_available"}}
- }
- return gpus
-}
+package main
+
+import (
+ "os/exec"
+ "strconv"
+ "strings"
+)
+
+// readGPU 读取GPU信息
+func readGPU() []GPUMetrics {
+ _, err := exec.LookPath("nvidia-smi")
+ if err != nil {
+ return []GPUMetrics{{Status: "not_available"}}
+ }
+ // Query GPU info including temperature
+ cmd := exec.Command("nvidia-smi", "--query-gpu=name,memory.total,memory.used,utilization.gpu,temperature.gpu", "--format=csv,noheader,nounits")
+ out, err := cmd.Output()
+ if err != nil {
+ return []GPUMetrics{{Status: "error", Name: "nvidia-smi", UtilizationPercent: 0}}
+ }
+ lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+ gpus := make([]GPUMetrics, 0, len(lines))
+ for _, line := range lines {
+ parts := strings.Split(line, ",")
+ for i := range parts {
+ parts[i] = strings.TrimSpace(parts[i])
+ }
+ if len(parts) < 5 {
+ continue
+ }
+ total, _ := strconv.ParseInt(parts[1], 10, 64)
+ used, _ := strconv.ParseInt(parts[2], 10, 64)
+ util, _ := strconv.ParseFloat(parts[3], 64)
+ temp, _ := strconv.ParseFloat(parts[4], 64)
+ gpus = append(gpus, GPUMetrics{
+ Name: parts[0],
+ MemoryTotalMB: total,
+ MemoryUsedMB: used,
+ UtilizationPercent: round(util, 2),
+ Temperature: temp,
+ Status: "ok",
+ })
+ }
+ if len(gpus) == 0 {
+ return []GPUMetrics{{Status: "not_available"}}
+ }
+ return gpus
+}
diff --git a/mengyamonitor-backend/latency.go b/mengyamonitor-backend/latency.go
index 015835c..564fc1c 100644
--- a/mengyamonitor-backend/latency.go
+++ b/mengyamonitor-backend/latency.go
@@ -1,56 +1,56 @@
-package main
-
-import (
- "fmt"
- "net"
- "time"
-)
-
-// LatencyInfo 延迟信息
-type LatencyInfo struct {
- ClientToServer float64 `json:"clientToServer"` // 客户端到服务器延迟(ms),由前端计算
- External map[string]string `json:"external"` // 外部网站延迟
-}
-
-// checkExternalLatency 检测外部网站延迟
-func checkExternalLatency(host string, timeout time.Duration) string {
- start := time.Now()
-
- // 尝试 TCP 连接 80 端口
- conn, err := net.DialTimeout("tcp", host+":80", timeout)
- if err != nil {
- // 如果 80 端口失败,尝试 443 (HTTPS)
- conn, err = net.DialTimeout("tcp", host+":443", timeout)
- if err != nil {
- return "超时"
- }
- }
- defer conn.Close()
-
- latency := time.Since(start).Milliseconds()
-
- // 检查是否超时(超过超时时间的一半就认为可能有问题)
- if latency > timeout.Milliseconds()/2 {
- return "超时"
- }
-
- return fmt.Sprintf("%d ms", latency)
-}
-
-// readExternalLatencies 读取外部网站延迟
-func readExternalLatencies() map[string]string {
- latencies := make(map[string]string)
- timeout := 3 * time.Second
-
- // 检测百度
- latencies["baidu.com"] = checkExternalLatency("baidu.com", timeout)
-
- // 检测谷歌
- latencies["google.com"] = checkExternalLatency("google.com", timeout)
-
- // 检测 GitHub
- latencies["github.com"] = checkExternalLatency("github.com", timeout)
-
- return latencies
-}
-
+package main
+
+import (
+ "fmt"
+ "net"
+ "time"
+)
+
+// LatencyInfo 延迟信息
+type LatencyInfo struct {
+ ClientToServer float64 `json:"clientToServer"` // 客户端到服务器延迟(ms),由前端计算
+ External map[string]string `json:"external"` // 外部网站延迟
+}
+
+// checkExternalLatency 检测外部网站延迟
+func checkExternalLatency(host string, timeout time.Duration) string {
+ start := time.Now()
+
+ // 尝试 TCP 连接 80 端口
+ conn, err := net.DialTimeout("tcp", host+":80", timeout)
+ if err != nil {
+ // 如果 80 端口失败,尝试 443 (HTTPS)
+ conn, err = net.DialTimeout("tcp", host+":443", timeout)
+ if err != nil {
+ return "超时"
+ }
+ }
+ defer conn.Close()
+
+ latency := time.Since(start).Milliseconds()
+
+ // 检查是否超时(超过超时时间的一半就认为可能有问题)
+ if latency > timeout.Milliseconds()/2 {
+ return "超时"
+ }
+
+ return fmt.Sprintf("%d ms", latency)
+}
+
+// readExternalLatencies 读取外部网站延迟
+func readExternalLatencies() map[string]string {
+ latencies := make(map[string]string)
+ timeout := 3 * time.Second
+
+ // 检测百度
+ latencies["baidu.com"] = checkExternalLatency("baidu.com", timeout)
+
+ // 检测谷歌
+ latencies["google.com"] = checkExternalLatency("google.com", timeout)
+
+ // 检测 GitHub
+ latencies["github.com"] = checkExternalLatency("github.com", timeout)
+
+ return latencies
+}
+
diff --git a/mengyamonitor-backend/main.go b/mengyamonitor-backend/main.go
index 12475a8..39c2d6d 100644
--- a/mengyamonitor-backend/main.go
+++ b/mengyamonitor-backend/main.go
@@ -1,265 +1,265 @@
-package main
-
-import (
- "encoding/json"
- "fmt"
- "log"
- "net/http"
- "os"
- "runtime"
- "time"
-)
-
-// envelope keeps JSON responses consistent.
-type envelope map[string]any
-
-func main() {
- host := getenv("HOST", "0.0.0.0")
- port := getenv("PORT", "9292")
-
- mux := http.NewServeMux()
- mux.HandleFunc("/", rootHandler)
- mux.HandleFunc("/api/health", healthHandler)
- // 拆分的细粒度API端点
- mux.HandleFunc("/api/metrics/cpu", cpuMetricsHandler)
- mux.HandleFunc("/api/metrics/memory", memoryMetricsHandler)
- mux.HandleFunc("/api/metrics/storage", storageMetricsHandler)
- mux.HandleFunc("/api/metrics/gpu", gpuMetricsHandler)
- mux.HandleFunc("/api/metrics/network", networkMetricsHandler)
- mux.HandleFunc("/api/metrics/system", systemMetricsHandler)
- mux.HandleFunc("/api/metrics/docker", dockerMetricsHandler)
- mux.HandleFunc("/api/metrics/latency", latencyMetricsHandler)
-
- srv := &http.Server{
- Addr: fmt.Sprintf("%s:%s", host, port),
- Handler: loggingMiddleware(corsMiddleware(mux)),
- ReadHeaderTimeout: 5 * time.Second,
- }
-
- log.Printf("server starting on http://%s:%s", host, port)
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("server error: %v", err)
- }
-}
-
-func rootHandler(w http.ResponseWriter, r *http.Request) {
- respondJSON(w, http.StatusOK, envelope{
- "service": "萌芽监控面板 API",
- "version": "1.0.0",
- "endpoints": []map[string]string{
- {
- "path": "/",
- "description": "API 信息和可用端点列表",
- },
- {
- "path": "/api/health",
- "description": "健康检查",
- },
- {
- "path": "/api/metrics/cpu",
- "description": "获取 CPU 监控数据",
- },
- {
- "path": "/api/metrics/memory",
- "description": "获取内存监控数据",
- },
- {
- "path": "/api/metrics/storage",
- "description": "获取存储监控数据",
- },
- {
- "path": "/api/metrics/gpu",
- "description": "获取 GPU 监控数据",
- },
- {
- "path": "/api/metrics/network",
- "description": "获取网络接口监控数据",
- },
- {
- "path": "/api/metrics/system",
- "description": "获取系统统计信息(进程、包、磁盘速度等)",
- },
- {
- "path": "/api/metrics/docker",
- "description": "获取 Docker 容器监控数据",
- },
- },
- })
-}
-
-func healthHandler(w http.ResponseWriter, r *http.Request) {
- respondJSON(w, http.StatusOK, envelope{
- "status": "ok",
- "timestamp": time.Now().UTC(),
- })
-}
-
-// CPU监控数据
-func cpuMetricsHandler(w http.ResponseWriter, r *http.Request) {
- cpuModel := firstMatchInFile("/proc/cpuinfo", "model name")
- cpuUsage, err := readCPUUsage()
- if err != nil {
- cpuUsage = 0
- }
- cpuTemp := readCPUTemperature()
- perCoreUsage := readPerCoreUsage()
- loads := readLoadAverages()
-
- cores := runtime.NumCPU()
- respondJSON(w, http.StatusOK, envelope{
- "data": CPUMetrics{
- Model: cpuModel,
- Cores: cores,
- UsagePercent: round(cpuUsage, 2),
- LoadAverages: loads,
- Temperature: cpuTemp,
- PerCoreUsage: perCoreUsage,
- },
- })
-}
-
-// 内存监控数据
-func memoryMetricsHandler(w http.ResponseWriter, r *http.Request) {
- mem, err := readMemory()
- if err != nil {
- respondJSON(w, http.StatusInternalServerError, envelope{
- "error": "failed to read memory",
- })
- return
- }
- respondJSON(w, http.StatusOK, envelope{
- "data": mem,
- })
-}
-
-// 存储监控数据
-func storageMetricsHandler(w http.ResponseWriter, r *http.Request) {
- storage, err := readAllStorage()
- if err != nil {
- respondJSON(w, http.StatusInternalServerError, envelope{
- "error": "failed to read storage",
- })
- return
- }
- respondJSON(w, http.StatusOK, envelope{
- "data": storage,
- })
-}
-
-// GPU监控数据
-func gpuMetricsHandler(w http.ResponseWriter, r *http.Request) {
- gpu := readGPU()
- respondJSON(w, http.StatusOK, envelope{
- "data": gpu,
- })
-}
-
-// 网络监控数据
-func networkMetricsHandler(w http.ResponseWriter, r *http.Request) {
- network := readNetworkInterfaces()
- respondJSON(w, http.StatusOK, envelope{
- "data": network,
- })
-}
-
-// 系统统计信息
-func systemMetricsHandler(w http.ResponseWriter, r *http.Request) {
- stats := readSystemStats()
-
- // 读取系统基本信息
- hostname, _ := os.Hostname()
- osInfo := readOSInfo()
- uptime := readUptime()
-
- // 计算总网络速度(汇总所有接口)
- networkInterfaces := readNetworkInterfaces()
- var totalRxSpeed, totalTxSpeed float64
- for _, iface := range networkInterfaces {
- totalRxSpeed += iface.RxSpeed // bytes/s
- totalTxSpeed += iface.TxSpeed // bytes/s
- }
- // 转换为 MB/s
- stats.NetworkRxSpeed = round(totalRxSpeed/1024/1024, 2)
- stats.NetworkTxSpeed = round(totalTxSpeed/1024/1024, 2)
-
- respondJSON(w, http.StatusOK, envelope{
- "data": map[string]interface{}{
- "hostname": hostname,
- "os": osInfo,
- "uptimeSeconds": uptime,
- "processCount": stats.ProcessCount,
- "packageCount": stats.PackageCount,
- "packageManager": stats.PackageManager,
- "temperature": stats.Temperature,
- "diskReadSpeed": stats.DiskReadSpeed,
- "diskWriteSpeed": stats.DiskWriteSpeed,
- "networkRxSpeed": stats.NetworkRxSpeed,
- "networkTxSpeed": stats.NetworkTxSpeed,
- "topProcesses": stats.TopProcesses,
- "systemLogs": stats.SystemLogs,
- },
- })
-}
-
-// Docker监控数据
-func dockerMetricsHandler(w http.ResponseWriter, r *http.Request) {
- docker := readDockerStats()
- respondJSON(w, http.StatusOK, envelope{
- "data": docker,
- })
-}
-
-// 延迟监控数据
-func latencyMetricsHandler(w http.ResponseWriter, r *http.Request) {
- // 记录请求开始时间,用于计算客户端到服务器的延迟
- startTime := time.Now()
-
- // 读取外部网站延迟
- externalLatencies := readExternalLatencies()
-
- // 计算服务器处理时间(这个可以作为参考,实际客户端延迟由前端计算)
- serverProcessTime := time.Since(startTime).Milliseconds()
-
- respondJSON(w, http.StatusOK, envelope{
- "data": map[string]interface{}{
- "serverProcessTime": serverProcessTime, // 服务器处理时间(参考)
- "external": externalLatencies,
- },
- })
-}
-
-func respondJSON(w http.ResponseWriter, status int, body envelope) {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(status)
- if err := json.NewEncoder(w).Encode(body); err != nil {
- log.Printf("write json error: %v", err)
- }
-}
-
-func getenv(key, fallback string) string {
- if v, ok := os.LookupEnv(key); ok && v != "" {
- return v
- }
- return fallback
-}
-
-func loggingMiddleware(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- start := time.Now()
- next.ServeHTTP(w, r)
- log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
- })
-}
-
-func corsMiddleware(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
- w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
- if r.Method == http.MethodOptions {
- w.WriteHeader(http.StatusNoContent)
- return
- }
- next.ServeHTTP(w, r)
- })
-}
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "net/http"
+ "os"
+ "runtime"
+ "time"
+)
+
+// envelope keeps JSON responses consistent.
+type envelope map[string]any
+
+func main() {
+ host := getenv("HOST", "0.0.0.0")
+ port := getenv("PORT", "9292")
+
+ mux := http.NewServeMux()
+ mux.HandleFunc("/", rootHandler)
+ mux.HandleFunc("/api/health", healthHandler)
+ // 拆分的细粒度API端点
+ mux.HandleFunc("/api/metrics/cpu", cpuMetricsHandler)
+ mux.HandleFunc("/api/metrics/memory", memoryMetricsHandler)
+ mux.HandleFunc("/api/metrics/storage", storageMetricsHandler)
+ mux.HandleFunc("/api/metrics/gpu", gpuMetricsHandler)
+ mux.HandleFunc("/api/metrics/network", networkMetricsHandler)
+ mux.HandleFunc("/api/metrics/system", systemMetricsHandler)
+ mux.HandleFunc("/api/metrics/docker", dockerMetricsHandler)
+ mux.HandleFunc("/api/metrics/latency", latencyMetricsHandler)
+
+ srv := &http.Server{
+ Addr: fmt.Sprintf("%s:%s", host, port),
+ Handler: loggingMiddleware(corsMiddleware(mux)),
+ ReadHeaderTimeout: 5 * time.Second,
+ }
+
+ log.Printf("server starting on http://%s:%s", host, port)
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("server error: %v", err)
+ }
+}
+
+func rootHandler(w http.ResponseWriter, r *http.Request) {
+ respondJSON(w, http.StatusOK, envelope{
+ "service": "萌芽监控面板 API",
+ "version": "1.0.0",
+ "endpoints": []map[string]string{
+ {
+ "path": "/",
+ "description": "API 信息和可用端点列表",
+ },
+ {
+ "path": "/api/health",
+ "description": "健康检查",
+ },
+ {
+ "path": "/api/metrics/cpu",
+ "description": "获取 CPU 监控数据",
+ },
+ {
+ "path": "/api/metrics/memory",
+ "description": "获取内存监控数据",
+ },
+ {
+ "path": "/api/metrics/storage",
+ "description": "获取存储监控数据",
+ },
+ {
+ "path": "/api/metrics/gpu",
+ "description": "获取 GPU 监控数据",
+ },
+ {
+ "path": "/api/metrics/network",
+ "description": "获取网络接口监控数据",
+ },
+ {
+ "path": "/api/metrics/system",
+ "description": "获取系统统计信息(进程、包、磁盘速度等)",
+ },
+ {
+ "path": "/api/metrics/docker",
+ "description": "获取 Docker 容器监控数据",
+ },
+ },
+ })
+}
+
+func healthHandler(w http.ResponseWriter, r *http.Request) {
+ respondJSON(w, http.StatusOK, envelope{
+ "status": "ok",
+ "timestamp": time.Now().UTC(),
+ })
+}
+
+// CPU监控数据
+func cpuMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ cpuModel := firstMatchInFile("/proc/cpuinfo", "model name")
+ cpuUsage, err := readCPUUsage()
+ if err != nil {
+ cpuUsage = 0
+ }
+ cpuTemp := readCPUTemperature()
+ perCoreUsage := readPerCoreUsage()
+ loads := readLoadAverages()
+
+ cores := runtime.NumCPU()
+ respondJSON(w, http.StatusOK, envelope{
+ "data": CPUMetrics{
+ Model: cpuModel,
+ Cores: cores,
+ UsagePercent: round(cpuUsage, 2),
+ LoadAverages: loads,
+ Temperature: cpuTemp,
+ PerCoreUsage: perCoreUsage,
+ },
+ })
+}
+
+// 内存监控数据
+func memoryMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ mem, err := readMemory()
+ if err != nil {
+ respondJSON(w, http.StatusInternalServerError, envelope{
+ "error": "failed to read memory",
+ })
+ return
+ }
+ respondJSON(w, http.StatusOK, envelope{
+ "data": mem,
+ })
+}
+
+// 存储监控数据
+func storageMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ storage, err := readAllStorage()
+ if err != nil {
+ respondJSON(w, http.StatusInternalServerError, envelope{
+ "error": "failed to read storage",
+ })
+ return
+ }
+ respondJSON(w, http.StatusOK, envelope{
+ "data": storage,
+ })
+}
+
+// GPU监控数据
+func gpuMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ gpu := readGPU()
+ respondJSON(w, http.StatusOK, envelope{
+ "data": gpu,
+ })
+}
+
+// 网络监控数据
+func networkMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ network := readNetworkInterfaces()
+ respondJSON(w, http.StatusOK, envelope{
+ "data": network,
+ })
+}
+
+// 系统统计信息
+func systemMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ stats := readSystemStats()
+
+ // 读取系统基本信息
+ hostname, _ := os.Hostname()
+ osInfo := readOSInfo()
+ uptime := readUptime()
+
+ // 计算总网络速度(汇总所有接口)
+ networkInterfaces := readNetworkInterfaces()
+ var totalRxSpeed, totalTxSpeed float64
+ for _, iface := range networkInterfaces {
+ totalRxSpeed += iface.RxSpeed // bytes/s
+ totalTxSpeed += iface.TxSpeed // bytes/s
+ }
+ // 转换为 MB/s
+ stats.NetworkRxSpeed = round(totalRxSpeed/1024/1024, 2)
+ stats.NetworkTxSpeed = round(totalTxSpeed/1024/1024, 2)
+
+ respondJSON(w, http.StatusOK, envelope{
+ "data": map[string]interface{}{
+ "hostname": hostname,
+ "os": osInfo,
+ "uptimeSeconds": uptime,
+ "processCount": stats.ProcessCount,
+ "packageCount": stats.PackageCount,
+ "packageManager": stats.PackageManager,
+ "temperature": stats.Temperature,
+ "diskReadSpeed": stats.DiskReadSpeed,
+ "diskWriteSpeed": stats.DiskWriteSpeed,
+ "networkRxSpeed": stats.NetworkRxSpeed,
+ "networkTxSpeed": stats.NetworkTxSpeed,
+ "topProcesses": stats.TopProcesses,
+ "systemLogs": stats.SystemLogs,
+ },
+ })
+}
+
+// Docker监控数据
+func dockerMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ docker := readDockerStats()
+ respondJSON(w, http.StatusOK, envelope{
+ "data": docker,
+ })
+}
+
+// 延迟监控数据
+func latencyMetricsHandler(w http.ResponseWriter, r *http.Request) {
+ // 记录请求开始时间,用于计算客户端到服务器的延迟
+ startTime := time.Now()
+
+ // 读取外部网站延迟
+ externalLatencies := readExternalLatencies()
+
+ // 计算服务器处理时间(这个可以作为参考,实际客户端延迟由前端计算)
+ serverProcessTime := time.Since(startTime).Milliseconds()
+
+ respondJSON(w, http.StatusOK, envelope{
+ "data": map[string]interface{}{
+ "serverProcessTime": serverProcessTime, // 服务器处理时间(参考)
+ "external": externalLatencies,
+ },
+ })
+}
+
+func respondJSON(w http.ResponseWriter, status int, body envelope) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(status)
+ if err := json.NewEncoder(w).Encode(body); err != nil {
+ log.Printf("write json error: %v", err)
+ }
+}
+
+func getenv(key, fallback string) string {
+ if v, ok := os.LookupEnv(key); ok && v != "" {
+ return v
+ }
+ return fallback
+}
+
+func loggingMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ start := time.Now()
+ next.ServeHTTP(w, r)
+ log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
+ })
+}
+
+func corsMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
+ w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
+ if r.Method == http.MethodOptions {
+ w.WriteHeader(http.StatusNoContent)
+ return
+ }
+ next.ServeHTTP(w, r)
+ })
+}
diff --git a/mengyamonitor-backend/memory.go b/mengyamonitor-backend/memory.go
index 5fd2731..4299a08 100644
--- a/mengyamonitor-backend/memory.go
+++ b/mengyamonitor-backend/memory.go
@@ -1,64 +1,64 @@
-package main
-
-import (
- "bufio"
- "os"
- "strconv"
- "strings"
-)
-
-// readMemory 读取内存信息
-func readMemory() (MemoryMetrics, error) {
- totals := map[string]uint64{}
- f, err := os.Open("/proc/meminfo")
- if err != nil {
- return MemoryMetrics{}, err
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- parts := strings.Split(line, ":")
- if len(parts) < 2 {
- continue
- }
- key := strings.TrimSpace(parts[0])
- fields := strings.Fields(strings.TrimSpace(parts[1]))
- if len(fields) == 0 {
- continue
- }
- value, err := strconv.ParseUint(fields[0], 10, 64)
- if err != nil {
- continue
- }
- totals[key] = value * 1024 // kB to bytes
- }
- total := totals["MemTotal"]
-
- // 优先使用 MemAvailable(Linux 3.14+),如果没有则计算
- var free uint64
- if available, ok := totals["MemAvailable"]; ok && available > 0 {
- free = available
- } else {
- // 回退到 MemFree + Buffers + Cached(适用于较老的系统)
- free = totals["MemFree"]
- if buffers, ok := totals["Buffers"]; ok {
- free += buffers
- }
- if cached, ok := totals["Cached"]; ok {
- free += cached
- }
- }
-
- used := total - free
- usedPercent := 0.0
- if total > 0 {
- usedPercent = (float64(used) / float64(total)) * 100
- }
- return MemoryMetrics{
- TotalBytes: total,
- UsedBytes: used,
- FreeBytes: free,
- UsedPercent: round(usedPercent, 2),
- }, nil
-}
+package main
+
+import (
+ "bufio"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// readMemory 读取内存信息
+func readMemory() (MemoryMetrics, error) {
+ totals := map[string]uint64{}
+ f, err := os.Open("/proc/meminfo")
+ if err != nil {
+ return MemoryMetrics{}, err
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ parts := strings.Split(line, ":")
+ if len(parts) < 2 {
+ continue
+ }
+ key := strings.TrimSpace(parts[0])
+ fields := strings.Fields(strings.TrimSpace(parts[1]))
+ if len(fields) == 0 {
+ continue
+ }
+ value, err := strconv.ParseUint(fields[0], 10, 64)
+ if err != nil {
+ continue
+ }
+ totals[key] = value * 1024 // kB to bytes
+ }
+ total := totals["MemTotal"]
+
+ // 优先使用 MemAvailable(Linux 3.14+),如果没有则计算
+ var free uint64
+ if available, ok := totals["MemAvailable"]; ok && available > 0 {
+ free = available
+ } else {
+ // 回退到 MemFree + Buffers + Cached(适用于较老的系统)
+ free = totals["MemFree"]
+ if buffers, ok := totals["Buffers"]; ok {
+ free += buffers
+ }
+ if cached, ok := totals["Cached"]; ok {
+ free += cached
+ }
+ }
+
+ used := total - free
+ usedPercent := 0.0
+ if total > 0 {
+ usedPercent = (float64(used) / float64(total)) * 100
+ }
+ return MemoryMetrics{
+ TotalBytes: total,
+ UsedBytes: used,
+ FreeBytes: free,
+ UsedPercent: round(usedPercent, 2),
+ }, nil
+}
diff --git a/mengyamonitor-backend/network.go b/mengyamonitor-backend/network.go
index 5a61e02..824b952 100644
--- a/mengyamonitor-backend/network.go
+++ b/mengyamonitor-backend/network.go
@@ -1,110 +1,112 @@
-package main
-
-import (
- "os"
- "os/exec"
- "strconv"
- "strings"
- "time"
-)
-
-// readNetworkInterfaces 读取网络接口信息(包含瞬时流量速度) - 优化版:所有接口并行采样
-func readNetworkInterfaces() []NetworkInterface {
- interfaces := []NetworkInterface{}
-
- // 读取网络接口列表
- entries, err := os.ReadDir("/sys/class/net")
- if err != nil {
- return interfaces
- }
-
- // 收集要监控的接口名称
- var validIfaces []string
- for _, entry := range entries {
- ifName := entry.Name()
- if ifName == "lo" { // 跳过回环接口
- continue
- }
-
- // 跳过 Docker 相关网络接口
- if strings.HasPrefix(ifName, "docker") ||
- strings.HasPrefix(ifName, "br-") ||
- strings.HasPrefix(ifName, "veth") {
- continue
- }
-
- validIfaces = append(validIfaces, ifName)
- }
-
- // 第一次批量读取所有接口的流量
- firstReadings := make(map[string][2]uint64) // [rx, tx]
- for _, ifName := range validIfaces {
- rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes"
- txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes"
-
- var rxBytes, txBytes uint64
- if rxStr := readFirstLine(rxPath); rxStr != "" {
- rxBytes, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64)
- }
- if txStr := readFirstLine(txPath); txStr != "" {
- txBytes, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64)
- }
- firstReadings[ifName] = [2]uint64{rxBytes, txBytes}
- }
-
- // 等待500ms(所有接口一起等待,而不是每个接口单独等待)
- time.Sleep(500 * time.Millisecond)
-
- // 第二次批量读取并构建结果
- for _, ifName := range validIfaces {
- iface := NetworkInterface{
- Name: ifName,
- }
-
- // 读取 MAC 地址
- macPath := "/sys/class/net/" + ifName + "/address"
- iface.MACAddress = strings.TrimSpace(readFirstLine(macPath))
-
- // 读取 IP 地址 (使用 ip addr show)
- cmd := exec.Command("ip", "addr", "show", ifName)
- if out, err := cmd.Output(); err == nil {
- lines := strings.Split(string(out), "\n")
- for _, line := range lines {
- line = strings.TrimSpace(line)
- if strings.HasPrefix(line, "inet ") {
- fields := strings.Fields(line)
- if len(fields) >= 2 {
- iface.IPAddress = strings.Split(fields[1], "/")[0]
- break
- }
- }
- }
- }
-
- // 读取第二次流量统计
- rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes"
- txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes"
-
- var rxBytes2, txBytes2 uint64
- if rxStr := readFirstLine(rxPath); rxStr != "" {
- rxBytes2, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64)
- }
- if txStr := readFirstLine(txPath); txStr != "" {
- txBytes2, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64)
- }
-
- // 设置累计流量
- iface.RxBytes = rxBytes2
- iface.TxBytes = txBytes2
-
- // 计算瞬时速度 (bytes/s,乘以2因为采样间隔是0.5秒)
- if first, ok := firstReadings[ifName]; ok {
- iface.RxSpeed = float64(rxBytes2-first[0]) * 2
- iface.TxSpeed = float64(txBytes2-first[1]) * 2
- }
-
- interfaces = append(interfaces, iface)
- }
-
- return interfaces
-}
+package main
+
+import (
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// readNetworkInterfaces 读取网络接口信息(包含瞬时流量速度) - 优化版:所有接口并行采样
+func readNetworkInterfaces() []NetworkInterface {
+ interfaces := []NetworkInterface{}
+
+ // 读取网络接口列表
+ entries, err := os.ReadDir("/sys/class/net")
+ if err != nil {
+ return interfaces
+ }
+
+ // 收集要监控的接口名称
+ var validIfaces []string
+ for _, entry := range entries {
+ ifName := entry.Name()
+ if ifName == "lo" { // 跳过回环接口
+ continue
+ }
+
+ // 跳过 Docker 相关网络接口
+ if strings.HasPrefix(ifName, "docker") ||
+ strings.HasPrefix(ifName, "br-") ||
+ strings.HasPrefix(ifName, "wwan") ||
+ strings.HasPrefix(ifName, "nm-bridge") ||
+ strings.HasPrefix(ifName, "veth") {
+ continue
+ }
+
+ validIfaces = append(validIfaces, ifName)
+ }
+
+ // 第一次批量读取所有接口的流量
+ firstReadings := make(map[string][2]uint64) // [rx, tx]
+ for _, ifName := range validIfaces {
+ rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes"
+ txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes"
+
+ var rxBytes, txBytes uint64
+ if rxStr := readFirstLine(rxPath); rxStr != "" {
+ rxBytes, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64)
+ }
+ if txStr := readFirstLine(txPath); txStr != "" {
+ txBytes, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64)
+ }
+ firstReadings[ifName] = [2]uint64{rxBytes, txBytes}
+ }
+
+ // 等待500ms(所有接口一起等待,而不是每个接口单独等待)
+ time.Sleep(500 * time.Millisecond)
+
+ // 第二次批量读取并构建结果
+ for _, ifName := range validIfaces {
+ iface := NetworkInterface{
+ Name: ifName,
+ }
+
+ // 读取 MAC 地址
+ macPath := "/sys/class/net/" + ifName + "/address"
+ iface.MACAddress = strings.TrimSpace(readFirstLine(macPath))
+
+ // 读取 IP 地址 (使用 ip addr show)
+ cmd := exec.Command("ip", "addr", "show", ifName)
+ if out, err := cmd.Output(); err == nil {
+ lines := strings.Split(string(out), "\n")
+ for _, line := range lines {
+ line = strings.TrimSpace(line)
+ if strings.HasPrefix(line, "inet ") {
+ fields := strings.Fields(line)
+ if len(fields) >= 2 {
+ iface.IPAddress = strings.Split(fields[1], "/")[0]
+ break
+ }
+ }
+ }
+ }
+
+ // 读取第二次流量统计
+ rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes"
+ txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes"
+
+ var rxBytes2, txBytes2 uint64
+ if rxStr := readFirstLine(rxPath); rxStr != "" {
+ rxBytes2, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64)
+ }
+ if txStr := readFirstLine(txPath); txStr != "" {
+ txBytes2, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64)
+ }
+
+ // 设置累计流量
+ iface.RxBytes = rxBytes2
+ iface.TxBytes = txBytes2
+
+ // 计算瞬时速度 (bytes/s,乘以2因为采样间隔是0.5秒)
+ if first, ok := firstReadings[ifName]; ok {
+ iface.RxSpeed = float64(rxBytes2-first[0]) * 2
+ iface.TxSpeed = float64(txBytes2-first[1]) * 2
+ }
+
+ interfaces = append(interfaces, iface)
+ }
+
+ return interfaces
+}
diff --git a/mengyamonitor-backend/system.go b/mengyamonitor-backend/system.go
index e1d7bc4..0d81d1c 100644
--- a/mengyamonitor-backend/system.go
+++ b/mengyamonitor-backend/system.go
@@ -1,390 +1,390 @@
-package main
-
-import (
- "bufio"
- "context"
- "os"
- "os/exec"
- "strconv"
- "strings"
- "time"
-)
-
-// readSystemStats 读取系统统计信息
-func readSystemStats() SystemStats {
- stats := SystemStats{}
-
- // 读取进程数量
- stats.ProcessCount = countProcesses()
-
- // 读取已安装包数量和包管理器类型
- stats.PackageCount, stats.PackageManager = countPackages()
-
- // 读取系统温度
- stats.Temperature = readSystemTemperature()
-
- // 读取磁盘读写速度
- stats.DiskReadSpeed, stats.DiskWriteSpeed = readDiskSpeed()
-
- // 读取 Top 5 进程
- stats.TopProcesses = readTopProcesses()
-
- // 读取系统日志
- stats.SystemLogs = readSystemLogs(10)
-
- return stats
-}
-
-func countProcesses() int {
- entries, err := os.ReadDir("/proc")
- if err != nil {
- return 0
- }
- count := 0
- for _, entry := range entries {
- if entry.IsDir() {
- // 进程目录是数字命名的
- if _, err := strconv.Atoi(entry.Name()); err == nil {
- count++
- }
- }
- }
- return count
-}
-
-func countPackages() (int, string) {
- // 尝试不同的包管理器
- // dpkg (Debian/Ubuntu)
- if _, err := exec.LookPath("dpkg"); err == nil {
- cmd := exec.Command("dpkg", "-l")
- out, err := cmd.Output()
- if err == nil {
- lines := strings.Split(string(out), "\n")
- count := 0
- for _, line := range lines {
- if strings.HasPrefix(line, "ii ") {
- count++
- }
- }
- return count, "dpkg (apt)"
- }
- }
-
- // rpm (RedHat/CentOS/Fedora)
- if _, err := exec.LookPath("rpm"); err == nil {
- cmd := exec.Command("rpm", "-qa")
- out, err := cmd.Output()
- if err == nil {
- lines := strings.Split(strings.TrimSpace(string(out)), "\n")
- return len(lines), "rpm (yum/dnf)"
- }
- }
-
- // pacman (Arch Linux)
- if _, err := exec.LookPath("pacman"); err == nil {
- cmd := exec.Command("pacman", "-Q")
- out, err := cmd.Output()
- if err == nil {
- lines := strings.Split(strings.TrimSpace(string(out)), "\n")
- return len(lines), "pacman"
- }
- }
-
- return 0, "unknown"
-}
-
-func readSystemTemperature() float64 {
- var cpuTemp float64 = 0
- var fallbackTemp float64 = 0
-
- // 1. 优先读取 thermal_zone (通常是 CPU 温度)
- thermalDir := "/sys/class/thermal"
- entries, err := os.ReadDir(thermalDir)
- if err == nil {
- for _, entry := range entries {
- if !strings.HasPrefix(entry.Name(), "thermal_zone") {
- continue
- }
- tempPath := thermalDir + "/" + entry.Name() + "/temp"
- if temp := readTempFromFile(tempPath); temp > 0 && temp > 20 && temp < 120 {
- // thermal_zone0 通常是 CPU
- if entry.Name() == "thermal_zone0" {
- cpuTemp = temp
- break
- } else if fallbackTemp == 0 {
- fallbackTemp = temp
- }
- }
- }
- }
-
- // 2. 扫描所有 hwmon 设备,查找 CPU 温度
- hwmonDir := "/sys/class/hwmon"
- entries, err = os.ReadDir(hwmonDir)
- if err == nil {
- for _, entry := range entries {
- hwmonPath := hwmonDir + "/" + entry.Name()
-
- // 读取 name 文件,检查是否是 CPU 相关
- namePath := hwmonPath + "/name"
- name := strings.ToLower(strings.TrimSpace(readFirstLine(namePath)))
-
- // 检查是否是 CPU 温度传感器
- isCPU := strings.Contains(name, "cpu") ||
- strings.Contains(name, "core") ||
- strings.Contains(name, "k10temp") ||
- strings.Contains(name, "coretemp") ||
- strings.Contains(name, "zenpower")
-
- // 尝试读取 temp1_input (通常是 CPU)
- temp1Path := hwmonPath + "/temp1_input"
- if temp := readTempFromFile(temp1Path); temp > 0 && temp > 20 && temp < 120 {
- if isCPU {
- cpuTemp = temp
- break
- } else if fallbackTemp == 0 {
- fallbackTemp = temp
- }
- }
-
- // 也尝试 temp2_input
- temp2Path := hwmonPath + "/temp2_input"
- if temp := readTempFromFile(temp2Path); temp > 0 && temp > 20 && temp < 120 {
- if isCPU && cpuTemp == 0 {
- cpuTemp = temp
- } else if fallbackTemp == 0 {
- fallbackTemp = temp
- }
- }
- }
- }
-
- // 优先返回 CPU 温度,如果没有则返回其他温度
- if cpuTemp > 0 {
- return cpuTemp
- }
- return fallbackTemp
-}
-
-// readDiskSpeed 读取磁盘瞬时读写速度 (MB/s)
-func readDiskSpeed() (float64, float64) {
- // 第一次读取
- readSectors1, writeSectors1 := getDiskSectors()
- if readSectors1 == 0 && writeSectors1 == 0 {
- return 0, 0
- }
-
- // 等待1秒
- time.Sleep(1 * time.Second)
-
- // 第二次读取
- readSectors2, writeSectors2 := getDiskSectors()
-
- // 计算差值(扇区数)
- readDiff := readSectors2 - readSectors1
- writeDiff := writeSectors2 - writeSectors1
-
- // 扇区大小通常是 512 字节,转换为 MB/s
- readSpeed := float64(readDiff) * 512 / 1024 / 1024
- writeSpeed := float64(writeDiff) * 512 / 1024 / 1024
-
- return round(readSpeed, 2), round(writeSpeed, 2)
-}
-
-func getDiskSectors() (uint64, uint64) {
- f, err := os.Open("/proc/diskstats")
- if err != nil {
- return 0, 0
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
-
- var maxRead uint64 = 0
- var mainDevice string
-
- // 第一次遍历:找到读写量最大的主磁盘(通常是系统盘)
- for scanner.Scan() {
- line := scanner.Text()
- fields := strings.Fields(line)
- if len(fields) < 14 {
- continue
- }
-
- deviceName := fields[2]
- // 跳过分区(分区名通常包含数字,如 sda1, vda1, nvme0n1p1)
- if strings.ContainsAny(deviceName, "0123456789") &&
- !strings.HasPrefix(deviceName, "nvme") &&
- !strings.HasPrefix(deviceName, "loop") {
- continue
- }
-
- // 跳过虚拟设备
- if strings.HasPrefix(deviceName, "loop") ||
- strings.HasPrefix(deviceName, "ram") ||
- strings.HasPrefix(deviceName, "zram") {
- continue
- }
-
- readSectors, _ := strconv.ParseUint(fields[5], 10, 64)
- // 选择读写量最大的作为主磁盘
- if readSectors > maxRead {
- maxRead = readSectors
- mainDevice = deviceName
- }
- }
-
- // 第二次遍历:读取主磁盘的数据
- f.Close()
- f, err = os.Open("/proc/diskstats")
- if err != nil {
- return 0, 0
- }
- scanner = bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- fields := strings.Fields(line)
- if len(fields) < 14 {
- continue
- }
-
- if fields[2] == mainDevice {
- readSectors, _ := strconv.ParseUint(fields[5], 10, 64)
- writeSectors, _ := strconv.ParseUint(fields[9], 10, 64)
- return readSectors, writeSectors
- }
- }
-
- // 如果没找到,尝试常见的设备名(向后兼容)
- f.Close()
- f, err = os.Open("/proc/diskstats")
- if err != nil {
- return 0, 0
- }
- scanner = bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- fields := strings.Fields(line)
- if len(fields) < 14 {
- continue
- }
-
- deviceName := fields[2]
- if deviceName == "sda" || deviceName == "vda" || deviceName == "nvme0n1" {
- readSectors, _ := strconv.ParseUint(fields[5], 10, 64)
- writeSectors, _ := strconv.ParseUint(fields[9], 10, 64)
- return readSectors, writeSectors
- }
- }
-
- return 0, 0
-}
-
-// readTopProcesses 读取 Top 5 进程 (按 CPU 使用率)
-func readTopProcesses() []ProcessInfo {
- processes := []ProcessInfo{}
-
- // 读取系统总内存
- memInfo, _ := readMemory()
- totalMemGB := float64(memInfo.TotalBytes) / 1024 / 1024 / 1024
-
- // 使用 ps 命令获取进程信息,添加超时控制
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
- cmd := exec.CommandContext(ctx, "ps", "aux", "--sort=-%cpu", "--no-headers")
- out, err := cmd.Output()
- if err != nil {
- return processes
- }
-
- lines := strings.Split(string(out), "\n")
- count := 0
-
- for _, line := range lines {
- if count >= 5 { // 只取前5个
- break
- }
-
- line = strings.TrimSpace(line)
- if line == "" {
- continue
- }
-
- fields := strings.Fields(line)
- if len(fields) < 11 {
- continue
- }
-
- pid, _ := strconv.Atoi(fields[1])
- cpu, _ := strconv.ParseFloat(fields[2], 64)
- mem, _ := strconv.ParseFloat(fields[3], 64)
-
- // 计算内存MB数
- memoryMB := (mem / 100) * totalMemGB * 1024
-
- // 命令可能包含空格,从第11个字段开始拼接
- command := strings.Join(fields[10:], " ")
- if len(command) > 50 {
- command = command[:50] + "..."
- }
-
- processes = append(processes, ProcessInfo{
- PID: pid,
- Name: fields[10],
- CPU: round(cpu, 1),
- Memory: round(mem, 1),
- MemoryMB: round(memoryMB, 1),
- Command: command,
- })
- count++
- }
-
- return processes
-}
-
-// readSystemLogs 读取系统最新日志
-func readSystemLogs(count int) []string {
- logs := []string{}
-
- // 尝试使用 journalctl 读取系统日志
- if _, err := exec.LookPath("journalctl"); err == nil {
- cmd := exec.Command("journalctl", "-n", strconv.Itoa(count), "--no-pager", "-o", "short")
- out, err := cmd.Output()
- if err == nil {
- lines := strings.Split(strings.TrimSpace(string(out)), "\n")
- for _, line := range lines {
- if line != "" {
- logs = append(logs, line)
- }
- }
- return logs
- }
- }
-
- // 如果 journalctl 不可用,尝试读取 /var/log/syslog 或 /var/log/messages
- logFiles := []string{"/var/log/syslog", "/var/log/messages"}
- for _, logFile := range logFiles {
- f, err := os.Open(logFile)
- if err != nil {
- continue
- }
- defer f.Close()
-
- // 读取最后几行
- var lines []string
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- lines = append(lines, scanner.Text())
- }
-
- // 取最后count行
- start := len(lines) - count
- if start < 0 {
- start = 0
- }
- logs = lines[start:]
- break
- }
-
- return logs
-}
+package main
+
+import (
+ "bufio"
+ "context"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// readSystemStats 读取系统统计信息
+func readSystemStats() SystemStats {
+ stats := SystemStats{}
+
+ // 读取进程数量
+ stats.ProcessCount = countProcesses()
+
+ // 读取已安装包数量和包管理器类型
+ stats.PackageCount, stats.PackageManager = countPackages()
+
+ // 读取系统温度
+ stats.Temperature = readSystemTemperature()
+
+ // 读取磁盘读写速度
+ stats.DiskReadSpeed, stats.DiskWriteSpeed = readDiskSpeed()
+
+ // 读取 Top 5 进程
+ stats.TopProcesses = readTopProcesses()
+
+ // 读取系统日志
+ stats.SystemLogs = readSystemLogs(10)
+
+ return stats
+}
+
+func countProcesses() int {
+ entries, err := os.ReadDir("/proc")
+ if err != nil {
+ return 0
+ }
+ count := 0
+ for _, entry := range entries {
+ if entry.IsDir() {
+ // 进程目录是数字命名的
+ if _, err := strconv.Atoi(entry.Name()); err == nil {
+ count++
+ }
+ }
+ }
+ return count
+}
+
+func countPackages() (int, string) {
+ // 尝试不同的包管理器
+ // dpkg (Debian/Ubuntu)
+ if _, err := exec.LookPath("dpkg"); err == nil {
+ cmd := exec.Command("dpkg", "-l")
+ out, err := cmd.Output()
+ if err == nil {
+ lines := strings.Split(string(out), "\n")
+ count := 0
+ for _, line := range lines {
+ if strings.HasPrefix(line, "ii ") {
+ count++
+ }
+ }
+ return count, "dpkg (apt)"
+ }
+ }
+
+ // rpm (RedHat/CentOS/Fedora)
+ if _, err := exec.LookPath("rpm"); err == nil {
+ cmd := exec.Command("rpm", "-qa")
+ out, err := cmd.Output()
+ if err == nil {
+ lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+ return len(lines), "rpm (yum/dnf)"
+ }
+ }
+
+ // pacman (Arch Linux)
+ if _, err := exec.LookPath("pacman"); err == nil {
+ cmd := exec.Command("pacman", "-Q")
+ out, err := cmd.Output()
+ if err == nil {
+ lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+ return len(lines), "pacman"
+ }
+ }
+
+ return 0, "unknown"
+}
+
+func readSystemTemperature() float64 {
+ var cpuTemp float64 = 0
+ var fallbackTemp float64 = 0
+
+ // 1. 优先读取 thermal_zone (通常是 CPU 温度)
+ thermalDir := "/sys/class/thermal"
+ entries, err := os.ReadDir(thermalDir)
+ if err == nil {
+ for _, entry := range entries {
+ if !strings.HasPrefix(entry.Name(), "thermal_zone") {
+ continue
+ }
+ tempPath := thermalDir + "/" + entry.Name() + "/temp"
+ if temp := readTempFromFile(tempPath); temp > 0 && temp > 20 && temp < 120 {
+ // thermal_zone0 通常是 CPU
+ if entry.Name() == "thermal_zone0" {
+ cpuTemp = temp
+ break
+ } else if fallbackTemp == 0 {
+ fallbackTemp = temp
+ }
+ }
+ }
+ }
+
+ // 2. 扫描所有 hwmon 设备,查找 CPU 温度
+ hwmonDir := "/sys/class/hwmon"
+ entries, err = os.ReadDir(hwmonDir)
+ if err == nil {
+ for _, entry := range entries {
+ hwmonPath := hwmonDir + "/" + entry.Name()
+
+ // 读取 name 文件,检查是否是 CPU 相关
+ namePath := hwmonPath + "/name"
+ name := strings.ToLower(strings.TrimSpace(readFirstLine(namePath)))
+
+ // 检查是否是 CPU 温度传感器
+ isCPU := strings.Contains(name, "cpu") ||
+ strings.Contains(name, "core") ||
+ strings.Contains(name, "k10temp") ||
+ strings.Contains(name, "coretemp") ||
+ strings.Contains(name, "zenpower")
+
+ // 尝试读取 temp1_input (通常是 CPU)
+ temp1Path := hwmonPath + "/temp1_input"
+ if temp := readTempFromFile(temp1Path); temp > 0 && temp > 20 && temp < 120 {
+ if isCPU {
+ cpuTemp = temp
+ break
+ } else if fallbackTemp == 0 {
+ fallbackTemp = temp
+ }
+ }
+
+ // 也尝试 temp2_input
+ temp2Path := hwmonPath + "/temp2_input"
+ if temp := readTempFromFile(temp2Path); temp > 0 && temp > 20 && temp < 120 {
+ if isCPU && cpuTemp == 0 {
+ cpuTemp = temp
+ } else if fallbackTemp == 0 {
+ fallbackTemp = temp
+ }
+ }
+ }
+ }
+
+ // 优先返回 CPU 温度,如果没有则返回其他温度
+ if cpuTemp > 0 {
+ return cpuTemp
+ }
+ return fallbackTemp
+}
+
+// readDiskSpeed 读取磁盘瞬时读写速度 (MB/s)
+func readDiskSpeed() (float64, float64) {
+ // 第一次读取
+ readSectors1, writeSectors1 := getDiskSectors()
+ if readSectors1 == 0 && writeSectors1 == 0 {
+ return 0, 0
+ }
+
+ // 等待1秒
+ time.Sleep(1 * time.Second)
+
+ // 第二次读取
+ readSectors2, writeSectors2 := getDiskSectors()
+
+ // 计算差值(扇区数)
+ readDiff := readSectors2 - readSectors1
+ writeDiff := writeSectors2 - writeSectors1
+
+ // 扇区大小通常是 512 字节,转换为 MB/s
+ readSpeed := float64(readDiff) * 512 / 1024 / 1024
+ writeSpeed := float64(writeDiff) * 512 / 1024 / 1024
+
+ return round(readSpeed, 2), round(writeSpeed, 2)
+}
+
+func getDiskSectors() (uint64, uint64) {
+ f, err := os.Open("/proc/diskstats")
+ if err != nil {
+ return 0, 0
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+
+ var maxRead uint64 = 0
+ var mainDevice string
+
+ // 第一次遍历:找到读写量最大的主磁盘(通常是系统盘)
+ for scanner.Scan() {
+ line := scanner.Text()
+ fields := strings.Fields(line)
+ if len(fields) < 14 {
+ continue
+ }
+
+ deviceName := fields[2]
+ // 跳过分区(分区名通常包含数字,如 sda1, vda1, nvme0n1p1)
+ if strings.ContainsAny(deviceName, "0123456789") &&
+ !strings.HasPrefix(deviceName, "nvme") &&
+ !strings.HasPrefix(deviceName, "loop") {
+ continue
+ }
+
+ // 跳过虚拟设备
+ if strings.HasPrefix(deviceName, "loop") ||
+ strings.HasPrefix(deviceName, "ram") ||
+ strings.HasPrefix(deviceName, "zram") {
+ continue
+ }
+
+ readSectors, _ := strconv.ParseUint(fields[5], 10, 64)
+ // 选择读写量最大的作为主磁盘
+ if readSectors > maxRead {
+ maxRead = readSectors
+ mainDevice = deviceName
+ }
+ }
+
+ // 第二次遍历:读取主磁盘的数据
+ f.Close()
+ f, err = os.Open("/proc/diskstats")
+ if err != nil {
+ return 0, 0
+ }
+ scanner = bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ fields := strings.Fields(line)
+ if len(fields) < 14 {
+ continue
+ }
+
+ if fields[2] == mainDevice {
+ readSectors, _ := strconv.ParseUint(fields[5], 10, 64)
+ writeSectors, _ := strconv.ParseUint(fields[9], 10, 64)
+ return readSectors, writeSectors
+ }
+ }
+
+ // 如果没找到,尝试常见的设备名(向后兼容)
+ f.Close()
+ f, err = os.Open("/proc/diskstats")
+ if err != nil {
+ return 0, 0
+ }
+ scanner = bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ fields := strings.Fields(line)
+ if len(fields) < 14 {
+ continue
+ }
+
+ deviceName := fields[2]
+ if deviceName == "sda" || deviceName == "vda" || deviceName == "nvme0n1" {
+ readSectors, _ := strconv.ParseUint(fields[5], 10, 64)
+ writeSectors, _ := strconv.ParseUint(fields[9], 10, 64)
+ return readSectors, writeSectors
+ }
+ }
+
+ return 0, 0
+}
+
+// readTopProcesses 读取 Top 5 进程 (按 CPU 使用率)
+func readTopProcesses() []ProcessInfo {
+ processes := []ProcessInfo{}
+
+ // 读取系统总内存
+ memInfo, _ := readMemory()
+ totalMemGB := float64(memInfo.TotalBytes) / 1024 / 1024 / 1024
+
+ // 使用 ps 命令获取进程信息,添加超时控制
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ defer cancel()
+ cmd := exec.CommandContext(ctx, "ps", "aux", "--sort=-%cpu", "--no-headers")
+ out, err := cmd.Output()
+ if err != nil {
+ return processes
+ }
+
+ lines := strings.Split(string(out), "\n")
+ count := 0
+
+ for _, line := range lines {
+ if count >= 5 { // 只取前5个
+ break
+ }
+
+ line = strings.TrimSpace(line)
+ if line == "" {
+ continue
+ }
+
+ fields := strings.Fields(line)
+ if len(fields) < 11 {
+ continue
+ }
+
+ pid, _ := strconv.Atoi(fields[1])
+ cpu, _ := strconv.ParseFloat(fields[2], 64)
+ mem, _ := strconv.ParseFloat(fields[3], 64)
+
+ // 计算内存MB数
+ memoryMB := (mem / 100) * totalMemGB * 1024
+
+ // 命令可能包含空格,从第11个字段开始拼接
+ command := strings.Join(fields[10:], " ")
+ if len(command) > 50 {
+ command = command[:50] + "..."
+ }
+
+ processes = append(processes, ProcessInfo{
+ PID: pid,
+ Name: fields[10],
+ CPU: round(cpu, 1),
+ Memory: round(mem, 1),
+ MemoryMB: round(memoryMB, 1),
+ Command: command,
+ })
+ count++
+ }
+
+ return processes
+}
+
+// readSystemLogs 读取系统最新日志
+func readSystemLogs(count int) []string {
+ logs := []string{}
+
+ // 尝试使用 journalctl 读取系统日志
+ if _, err := exec.LookPath("journalctl"); err == nil {
+ cmd := exec.Command("journalctl", "-n", strconv.Itoa(count), "--no-pager", "-o", "short")
+ out, err := cmd.Output()
+ if err == nil {
+ lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+ for _, line := range lines {
+ if line != "" {
+ logs = append(logs, line)
+ }
+ }
+ return logs
+ }
+ }
+
+ // 如果 journalctl 不可用,尝试读取 /var/log/syslog 或 /var/log/messages
+ logFiles := []string{"/var/log/syslog", "/var/log/messages"}
+ for _, logFile := range logFiles {
+ f, err := os.Open(logFile)
+ if err != nil {
+ continue
+ }
+ defer f.Close()
+
+ // 读取最后几行
+ var lines []string
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ lines = append(lines, scanner.Text())
+ }
+
+ // 取最后count行
+ start := len(lines) - count
+ if start < 0 {
+ start = 0
+ }
+ logs = lines[start:]
+ break
+ }
+
+ return logs
+}
diff --git a/mengyamonitor-backend/systeminfo_linux.go b/mengyamonitor-backend/systeminfo_linux.go
index 8b531ae..8189b1d 100644
--- a/mengyamonitor-backend/systeminfo_linux.go
+++ b/mengyamonitor-backend/systeminfo_linux.go
@@ -1,113 +1,113 @@
-//go:build linux
-// +build linux
-
-package main
-
-import (
- "bufio"
- "os"
- "strings"
- "syscall"
-)
-
-func readStorage() ([]StorageMetrics, error) {
- // For simplicity, report root mount. Can be extended to iterate mounts.
- var stat syscall.Statfs_t
- if err := syscall.Statfs("/", &stat); err != nil {
- return nil, err
- }
- total := stat.Blocks * uint64(stat.Bsize)
- free := stat.Bfree * uint64(stat.Bsize)
- used := total - free
- usedPercent := 0.0
- if total > 0 {
- usedPercent = (float64(used) / float64(total)) * 100
- }
- return []StorageMetrics{{
- Mount: "/",
- TotalBytes: total,
- UsedBytes: used,
- FreeBytes: free,
- UsedPercent: round(usedPercent, 2),
- }}, nil
-}
-
-// readAllStorage 读取所有挂载的存储设备
-func readAllStorage() ([]StorageMetrics, error) {
- storages := []StorageMetrics{}
-
- // 读取 /proc/mounts 获取所有挂载点
- f, err := os.Open("/proc/mounts")
- if err != nil {
- return readStorage() // 降级到只读根目录
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- seen := make(map[string]bool)
-
- for scanner.Scan() {
- line := scanner.Text()
- fields := strings.Fields(line)
- if len(fields) < 3 {
- continue
- }
-
- device := fields[0]
- mountPoint := fields[1]
- fsType := fields[2]
-
- // 跳过虚拟文件系统
- if strings.HasPrefix(device, "/dev/") == false {
- continue
- }
-
- // 跳过特殊文件系统类型
- skipTypes := map[string]bool{
- "tmpfs": true, "devtmpfs": true, "squashfs": true,
- "overlay": true, "aufs": true, "proc": true,
- "sysfs": true, "devpts": true, "cgroup": true,
- }
- if skipTypes[fsType] {
- continue
- }
-
- // 避免重复挂载点
- if seen[mountPoint] {
- continue
- }
- seen[mountPoint] = true
-
- // 获取该挂载点的统计信息
- var stat syscall.Statfs_t
- if err := syscall.Statfs(mountPoint, &stat); err != nil {
- continue
- }
-
- total := stat.Blocks * uint64(stat.Bsize)
- free := stat.Bfree * uint64(stat.Bsize)
- used := total - free
- usedPercent := 0.0
- if total > 0 {
- usedPercent = (float64(used) / float64(total)) * 100
- }
-
- // 只添加有容量的存储
- if total > 0 {
- storages = append(storages, StorageMetrics{
- Mount: mountPoint,
- TotalBytes: total,
- UsedBytes: used,
- FreeBytes: free,
- UsedPercent: round(usedPercent, 2),
- })
- }
- }
-
- // 如果没有找到任何存储,至少返回根目录
- if len(storages) == 0 {
- return readStorage()
- }
-
- return storages, nil
-}
+//go:build linux
+// +build linux
+
+package main
+
+import (
+ "bufio"
+ "os"
+ "strings"
+ "syscall"
+)
+
+func readStorage() ([]StorageMetrics, error) {
+ // For simplicity, report root mount. Can be extended to iterate mounts.
+ var stat syscall.Statfs_t
+ if err := syscall.Statfs("/", &stat); err != nil {
+ return nil, err
+ }
+ total := stat.Blocks * uint64(stat.Bsize)
+ free := stat.Bfree * uint64(stat.Bsize)
+ used := total - free
+ usedPercent := 0.0
+ if total > 0 {
+ usedPercent = (float64(used) / float64(total)) * 100
+ }
+ return []StorageMetrics{{
+ Mount: "/",
+ TotalBytes: total,
+ UsedBytes: used,
+ FreeBytes: free,
+ UsedPercent: round(usedPercent, 2),
+ }}, nil
+}
+
+// readAllStorage 读取所有挂载的存储设备
+func readAllStorage() ([]StorageMetrics, error) {
+ storages := []StorageMetrics{}
+
+ // 读取 /proc/mounts 获取所有挂载点
+ f, err := os.Open("/proc/mounts")
+ if err != nil {
+ return readStorage() // 降级到只读根目录
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ seen := make(map[string]bool)
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ fields := strings.Fields(line)
+ if len(fields) < 3 {
+ continue
+ }
+
+ device := fields[0]
+ mountPoint := fields[1]
+ fsType := fields[2]
+
+ // 跳过虚拟文件系统
+ if strings.HasPrefix(device, "/dev/") == false {
+ continue
+ }
+
+ // 跳过特殊文件系统类型
+ skipTypes := map[string]bool{
+ "tmpfs": true, "devtmpfs": true, "squashfs": true,
+ "overlay": true, "aufs": true, "proc": true,
+ "sysfs": true, "devpts": true, "cgroup": true,
+ }
+ if skipTypes[fsType] {
+ continue
+ }
+
+ // 避免重复挂载点
+ if seen[mountPoint] {
+ continue
+ }
+ seen[mountPoint] = true
+
+ // 获取该挂载点的统计信息
+ var stat syscall.Statfs_t
+ if err := syscall.Statfs(mountPoint, &stat); err != nil {
+ continue
+ }
+
+ total := stat.Blocks * uint64(stat.Bsize)
+ free := stat.Bfree * uint64(stat.Bsize)
+ used := total - free
+ usedPercent := 0.0
+ if total > 0 {
+ usedPercent = (float64(used) / float64(total)) * 100
+ }
+
+ // 只添加有容量的存储
+ if total > 0 {
+ storages = append(storages, StorageMetrics{
+ Mount: mountPoint,
+ TotalBytes: total,
+ UsedBytes: used,
+ FreeBytes: free,
+ UsedPercent: round(usedPercent, 2),
+ })
+ }
+ }
+
+ // 如果没有找到任何存储,至少返回根目录
+ if len(storages) == 0 {
+ return readStorage()
+ }
+
+ return storages, nil
+}
diff --git a/mengyamonitor-backend/systeminfo_other.go b/mengyamonitor-backend/systeminfo_other.go
index f4c0924..2aaf8ac 100644
--- a/mengyamonitor-backend/systeminfo_other.go
+++ b/mengyamonitor-backend/systeminfo_other.go
@@ -1,14 +1,14 @@
-//go:build !linux
-// +build !linux
-
-package main
-
-import "errors"
-
-func readStorage() ([]StorageMetrics, error) {
- return nil, errors.New("storage monitoring is only supported on Linux")
-}
-
-func readAllStorage() ([]StorageMetrics, error) {
- return nil, errors.New("storage monitoring is only supported on Linux")
-}
+//go:build !linux
+// +build !linux
+
+package main
+
+import "errors"
+
+func readStorage() ([]StorageMetrics, error) {
+ return nil, errors.New("storage monitoring is only supported on Linux")
+}
+
+func readAllStorage() ([]StorageMetrics, error) {
+ return nil, errors.New("storage monitoring is only supported on Linux")
+}
diff --git a/mengyamonitor-backend/utils.go b/mengyamonitor-backend/utils.go
index 7a028e8..84f606a 100644
--- a/mengyamonitor-backend/utils.go
+++ b/mengyamonitor-backend/utils.go
@@ -1,66 +1,66 @@
-package main
-
-import (
- "bufio"
- "math"
- "os"
- "strconv"
- "strings"
-)
-
-// round 将浮点数四舍五入到指定小数位
-func round(v float64, places int) float64 {
- factor := math.Pow(10, float64(places))
- return math.Round(v*factor) / factor
-}
-
-// readFirstLine 读取文件的第一行
-func readFirstLine(path string) string {
- f, err := os.Open(path)
- if err != nil {
- return ""
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- if scanner.Scan() {
- return scanner.Text()
- }
- return ""
-}
-
-// firstMatchInFile 在文件中查找第一个匹配指定前缀的行,并返回冒号后的内容
-func firstMatchInFile(path, prefix string) string {
- f, err := os.Open(path)
- if err != nil {
- return ""
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- if strings.HasPrefix(strings.TrimSpace(line), prefix) {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- return strings.TrimSpace(parts[1])
- }
- }
- }
- return ""
-}
-
-// readTempFromFile 从文件读取温度值
-func readTempFromFile(path string) float64 {
- content := readFirstLine(path)
- if content == "" {
- return 0
- }
- val, err := strconv.ParseFloat(strings.TrimSpace(content), 64)
- if err != nil {
- return 0
- }
- // 温度通常以毫度为单位
- if val > 1000 {
- return round(val/1000, 1)
- }
- return round(val, 1)
-}
+package main
+
+import (
+ "bufio"
+ "math"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// round 将浮点数四舍五入到指定小数位
+func round(v float64, places int) float64 {
+ factor := math.Pow(10, float64(places))
+ return math.Round(v*factor) / factor
+}
+
+// readFirstLine 读取文件的第一行
+func readFirstLine(path string) string {
+ f, err := os.Open(path)
+ if err != nil {
+ return ""
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ if scanner.Scan() {
+ return scanner.Text()
+ }
+ return ""
+}
+
+// firstMatchInFile 在文件中查找第一个匹配指定前缀的行,并返回冒号后的内容
+func firstMatchInFile(path, prefix string) string {
+ f, err := os.Open(path)
+ if err != nil {
+ return ""
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.HasPrefix(strings.TrimSpace(line), prefix) {
+ parts := strings.SplitN(line, ":", 2)
+ if len(parts) == 2 {
+ return strings.TrimSpace(parts[1])
+ }
+ }
+ }
+ return ""
+}
+
+// readTempFromFile 从文件读取温度值
+func readTempFromFile(path string) float64 {
+ content := readFirstLine(path)
+ if content == "" {
+ return 0
+ }
+ val, err := strconv.ParseFloat(strings.TrimSpace(content), 64)
+ if err != nil {
+ return 0
+ }
+ // 温度通常以毫度为单位
+ if val > 1000 {
+ return round(val/1000, 1)
+ }
+ return round(val, 1)
+}
diff --git a/mengyamonitor-frontend/README.md b/mengyamonitor-frontend/README.md
index d17fa10..dcedbed 100644
--- a/mengyamonitor-frontend/README.md
+++ b/mengyamonitor-frontend/README.md
@@ -1,110 +1,110 @@
-# 萌芽监控面板 - 前端
-
-## 概述
-服务器监控面板前端应用,使用 React + TypeScript + Vite 构建。
-
-## 功能特性
-- 🖥️ 多服务器监控支持
-- 📊 实时数据展示(CPU、内存、存储、GPU)
-- 🔄 自动刷新(2秒轮询)
-- 📱 响应式设计
-- 🎨 白色柔和风格界面
-- 💾 本地存储配置
-
-## 开发
-
-### 安装依赖
-```bash
-npm install
-```
-
-### 启动开发服务器
-```bash
-npm run dev
-```
-访问 http://localhost:2929
-
-### 构建生产版本
-```bash
-npm run build
-```
-生产文件将输出到 `dist` 目录
-
-### 预览生产版本
-```bash
-npm run preview
-```
-
-## 使用说明
-
-### 添加服务器
-1. 点击右上角"添加服务器"按钮
-2. 输入服务器名称(如:生产服务器1)
-3. 输入服务器地址(如:http://192.168.1.100:9292)
-4. 点击"添加"按钮
-
-### 查看详情
-点击服务器卡片上的"查看详情"按钮,可以查看完整的系统信息:
-- 系统信息(主机名、操作系统、内核、架构、运行时间)
-- CPU 详细信息(型号、核心数、使用率、负载)
-- 内存详细信息(总容量、已使用、可用、使用率)
-- 存储详细信息(挂载点、容量、使用情况)
-- GPU 信息(名称、显存、利用率)
-
-### 移除服务器
-点击服务器卡片右上角的"×"按钮,确认后即可移除。
-
-## 项目结构
-```
-src/
-├── api/ # API 调用
-│ └── monitor.ts # 监控 API
-├── components/ # React 组件
-│ ├── ServerCard/ # 服务器卡片组件
-│ └── ServerDetail/ # 服务器详情弹窗
-├── hooks/ # 自定义 Hooks
-│ └── useServerMonitor.ts # 服务器监控 Hook
-├── types/ # TypeScript 类型定义
-│ └── index.ts
-├── utils/ # 工具函数
-│ ├── format.ts # 格式化函数
-│ └── storage.ts # 本地存储
-├── App.tsx # 主应用组件
-├── App.css # 主应用样式
-├── main.tsx # 应用入口
-└── index.css # 全局样式
-```
-
-## 配置说明
-
-### 修改端口
-编辑 `vite.config.ts` 文件中的 `server.port` 配置:
-```typescript
-server: {
- port: 2929, // 修改为你想要的端口
-}
-```
-
-### 修改轮询间隔
-编辑 `src/App.tsx` 文件中的 `useServerMonitor` 第二个参数:
-```typescript
-const statuses = useServerMonitor(servers, 2000); // 2000ms = 2秒
-```
-
-## 部署
-
-### 静态文件部署
-1. 构建项目:`npm run build`
-2. 将 `dist` 目录部署到 Web 服务器(如 Nginx、Apache)
-3. 或使用静态托管服务(如 Vercel、Netlify)
-
-### 桌面应用
-可以使用 Electron 或 Tauri 将前端打包成桌面应用:
-- Electron: https://www.electronjs.org/
-- Tauri: https://tauri.app/
-
-## 注意事项
-- 确保后端服务器已启动并可访问
-- 后端服务器需要配置 CORS 允许跨域访问
-- 服务器地址需要包含协议(http:// 或 https://)
-- 本地存储的服务器配置保存在浏览器 localStorage 中
+# 萌芽监控面板 - 前端
+
+## 概述
+服务器监控面板前端应用,使用 React + TypeScript + Vite 构建。
+
+## 功能特性
+- 🖥️ 多服务器监控支持
+- 📊 实时数据展示(CPU、内存、存储、GPU)
+- 🔄 自动刷新(2秒轮询)
+- 📱 响应式设计
+- 🎨 白色柔和风格界面
+- 💾 本地存储配置
+
+## 开发
+
+### 安装依赖
+```bash
+npm install
+```
+
+### 启动开发服务器
+```bash
+npm run dev
+```
+访问 http://localhost:2929
+
+### 构建生产版本
+```bash
+npm run build
+```
+生产文件将输出到 `dist` 目录
+
+### 预览生产版本
+```bash
+npm run preview
+```
+
+## 使用说明
+
+### 添加服务器
+1. 点击右上角"添加服务器"按钮
+2. 输入服务器名称(如:生产服务器1)
+3. 输入服务器地址(如:http://192.168.1.100:9292)
+4. 点击"添加"按钮
+
+### 查看详情
+点击服务器卡片上的"查看详情"按钮,可以查看完整的系统信息:
+- 系统信息(主机名、操作系统、内核、架构、运行时间)
+- CPU 详细信息(型号、核心数、使用率、负载)
+- 内存详细信息(总容量、已使用、可用、使用率)
+- 存储详细信息(挂载点、容量、使用情况)
+- GPU 信息(名称、显存、利用率)
+
+### 移除服务器
+点击服务器卡片右上角的"×"按钮,确认后即可移除。
+
+## 项目结构
+```
+src/
+├── api/ # API 调用
+│ └── monitor.ts # 监控 API
+├── components/ # React 组件
+│ ├── ServerCard/ # 服务器卡片组件
+│ └── ServerDetail/ # 服务器详情弹窗
+├── hooks/ # 自定义 Hooks
+│ └── useServerMonitor.ts # 服务器监控 Hook
+├── types/ # TypeScript 类型定义
+│ └── index.ts
+├── utils/ # 工具函数
+│ ├── format.ts # 格式化函数
+│ └── storage.ts # 本地存储
+├── App.tsx # 主应用组件
+├── App.css # 主应用样式
+├── main.tsx # 应用入口
+└── index.css # 全局样式
+```
+
+## 配置说明
+
+### 修改端口
+编辑 `vite.config.ts` 文件中的 `server.port` 配置:
+```typescript
+server: {
+ port: 2929, // 修改为你想要的端口
+}
+```
+
+### 修改轮询间隔
+编辑 `src/App.tsx` 文件中的 `useServerMonitor` 第二个参数:
+```typescript
+const statuses = useServerMonitor(servers, 2000); // 2000ms = 2秒
+```
+
+## 部署
+
+### 静态文件部署
+1. 构建项目:`npm run build`
+2. 将 `dist` 目录部署到 Web 服务器(如 Nginx、Apache)
+3. 或使用静态托管服务(如 Vercel、Netlify)
+
+### 桌面应用
+可以使用 Electron 或 Tauri 将前端打包成桌面应用:
+- Electron: https://www.electronjs.org/
+- Tauri: https://tauri.app/
+
+## 注意事项
+- 确保后端服务器已启动并可访问
+- 后端服务器需要配置 CORS 允许跨域访问
+- 服务器地址需要包含协议(http:// 或 https://)
+- 本地存储的服务器配置保存在浏览器 localStorage 中
diff --git a/mengyamonitor-frontend/index.html b/mengyamonitor-frontend/index.html
index 26c2ebe..3f0b36e 100644
--- a/mengyamonitor-frontend/index.html
+++ b/mengyamonitor-frontend/index.html
@@ -1,9 +1,15 @@
-
+
-
+
+
+
+
+
+
+
萌芽监控面板
diff --git a/mengyamonitor-frontend/package-lock.json b/mengyamonitor-frontend/package-lock.json
index 30bd1ff..7088438 100644
--- a/mengyamonitor-frontend/package-lock.json
+++ b/mengyamonitor-frontend/package-lock.json
@@ -8,6 +8,9 @@
"name": "mengyamonitor-frontend",
"version": "0.0.0",
"dependencies": {
+ "@dnd-kit/core": "^6.3.1",
+ "@dnd-kit/sortable": "^10.0.0",
+ "@dnd-kit/utilities": "^3.2.2",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
@@ -23,17 +26,18 @@
"globals": "^16.5.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
- "vite": "^7.2.4"
+ "vite": "^7.2.4",
+ "vite-plugin-pwa": "^1.2.0"
}
},
"node_modules/@babel/code-frame": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
- "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
},
@@ -42,9 +46,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
- "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
+ "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -57,7 +61,6 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -84,14 +87,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
- "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.28.5",
- "@babel/types": "^7.28.5",
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
"@jridgewell/gen-mapping": "^0.3.12",
"@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
@@ -100,14 +103,27 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.27.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
- "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.27.2",
+ "@babel/types": "^7.27.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
"@babel/helper-validator-option": "^7.27.1",
"browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
@@ -117,6 +133,63 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
+ "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/traverse": "^7.28.6",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz",
+ "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "regexpu-core": "^6.3.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz",
+ "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "debug": "^4.4.3",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.22.11"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
"node_modules/@babel/helper-globals": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
@@ -127,30 +200,44 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-module-imports": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
- "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
+ "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.27.1",
- "@babel/types": "^7.27.1"
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.28.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
- "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.27.1",
- "@babel/traverse": "^7.28.3"
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
@@ -159,12 +246,75 @@
"@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-plugin-utils": {
+ "node_modules/@babel/helper-optimise-call-expression": {
"version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
- "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-wrap-function": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
+ "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
"engines": {
"node": ">=6.9.0"
}
@@ -199,6 +349,21 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz",
+ "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helpers": {
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
@@ -214,13 +379,13 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
- "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
+ "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.28.5"
+ "@babel/types": "^7.29.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -229,6 +394,811 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz",
+ "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz",
+ "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz",
+ "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz",
+ "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-transform-optional-chaining": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz",
+ "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.21.0-placeholder-for-preset-env.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz",
+ "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
+ "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
+ "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz",
+ "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-remap-async-to-generator": "^7.27.1",
+ "@babel/traverse": "^7.29.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz",
+ "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-remap-async-to-generator": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz",
+ "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz",
+ "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz",
+ "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz",
+ "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz",
+ "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-replace-supers": "^7.28.6",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz",
+ "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/template": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
+ "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz",
+ "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz",
+ "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz",
+ "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz",
+ "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-explicit-resource-management": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz",
+ "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/plugin-transform-destructuring": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz",
+ "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+ "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+ "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+ "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-json-strings": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz",
+ "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+ "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz",
+ "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz",
+ "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz",
+ "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz",
+ "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz",
+ "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.29.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz",
+ "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz",
+ "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz",
+ "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz",
+ "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz",
+ "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz",
+ "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/plugin-transform-destructuring": "^7.28.5",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz",
+ "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz",
+ "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz",
+ "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
+ "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz",
+ "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz",
+ "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz",
+ "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-transform-react-jsx-self": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
@@ -261,34 +1231,341 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/template": {
- "version": "7.27.2",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
- "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz",
+ "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@babel/parser": "^7.27.2",
- "@babel/types": "^7.27.1"
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz",
+ "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz",
+ "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
+ "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz",
+ "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+ "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+ "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz",
+ "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz",
+ "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-property-regex": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz",
+ "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
+ "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz",
+ "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.0.tgz",
+ "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.0",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6",
+ "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+ "@babel/plugin-syntax-import-assertions": "^7.28.6",
+ "@babel/plugin-syntax-import-attributes": "^7.28.6",
+ "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+ "@babel/plugin-transform-arrow-functions": "^7.27.1",
+ "@babel/plugin-transform-async-generator-functions": "^7.29.0",
+ "@babel/plugin-transform-async-to-generator": "^7.28.6",
+ "@babel/plugin-transform-block-scoped-functions": "^7.27.1",
+ "@babel/plugin-transform-block-scoping": "^7.28.6",
+ "@babel/plugin-transform-class-properties": "^7.28.6",
+ "@babel/plugin-transform-class-static-block": "^7.28.6",
+ "@babel/plugin-transform-classes": "^7.28.6",
+ "@babel/plugin-transform-computed-properties": "^7.28.6",
+ "@babel/plugin-transform-destructuring": "^7.28.5",
+ "@babel/plugin-transform-dotall-regex": "^7.28.6",
+ "@babel/plugin-transform-duplicate-keys": "^7.27.1",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0",
+ "@babel/plugin-transform-dynamic-import": "^7.27.1",
+ "@babel/plugin-transform-explicit-resource-management": "^7.28.6",
+ "@babel/plugin-transform-exponentiation-operator": "^7.28.6",
+ "@babel/plugin-transform-export-namespace-from": "^7.27.1",
+ "@babel/plugin-transform-for-of": "^7.27.1",
+ "@babel/plugin-transform-function-name": "^7.27.1",
+ "@babel/plugin-transform-json-strings": "^7.28.6",
+ "@babel/plugin-transform-literals": "^7.27.1",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.28.6",
+ "@babel/plugin-transform-member-expression-literals": "^7.27.1",
+ "@babel/plugin-transform-modules-amd": "^7.27.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.28.6",
+ "@babel/plugin-transform-modules-systemjs": "^7.29.0",
+ "@babel/plugin-transform-modules-umd": "^7.27.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0",
+ "@babel/plugin-transform-new-target": "^7.27.1",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6",
+ "@babel/plugin-transform-numeric-separator": "^7.28.6",
+ "@babel/plugin-transform-object-rest-spread": "^7.28.6",
+ "@babel/plugin-transform-object-super": "^7.27.1",
+ "@babel/plugin-transform-optional-catch-binding": "^7.28.6",
+ "@babel/plugin-transform-optional-chaining": "^7.28.6",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/plugin-transform-private-methods": "^7.28.6",
+ "@babel/plugin-transform-private-property-in-object": "^7.28.6",
+ "@babel/plugin-transform-property-literals": "^7.27.1",
+ "@babel/plugin-transform-regenerator": "^7.29.0",
+ "@babel/plugin-transform-regexp-modifiers": "^7.28.6",
+ "@babel/plugin-transform-reserved-words": "^7.27.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.27.1",
+ "@babel/plugin-transform-spread": "^7.28.6",
+ "@babel/plugin-transform-sticky-regex": "^7.27.1",
+ "@babel/plugin-transform-template-literals": "^7.27.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.27.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.27.1",
+ "@babel/plugin-transform-unicode-property-regex": "^7.28.6",
+ "@babel/plugin-transform-unicode-regex": "^7.27.1",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.28.6",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "babel-plugin-polyfill-corejs2": "^0.4.15",
+ "babel-plugin-polyfill-corejs3": "^0.14.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.6",
+ "core-js-compat": "^3.48.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
+ "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
- "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.28.5",
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
"@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.28.5",
- "@babel/template": "^7.27.2",
- "@babel/types": "^7.28.5",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0",
"debug": "^4.3.1"
},
"engines": {
@@ -296,9 +1573,9 @@
}
},
"node_modules/@babel/types": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
- "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -309,6 +1586,59 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@dnd-kit/accessibility": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
+ "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@dnd-kit/core": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
+ "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@dnd-kit/accessibility": "^3.1.1",
+ "@dnd-kit/utilities": "^3.2.2",
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@dnd-kit/sortable": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz",
+ "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==",
+ "license": "MIT",
+ "dependencies": {
+ "@dnd-kit/utilities": "^3.2.2",
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "@dnd-kit/core": "^6.3.0",
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@dnd-kit/utilities": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
+ "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
@@ -960,6 +2290,16 @@
"url": "https://github.com/sponsors/nzakas"
}
},
+ "node_modules/@isaacs/cliui": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz",
+ "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -992,6 +2332,17 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -1017,6 +2368,77 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
+ "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-terser": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
+ "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "serialize-javascript": "^6.0.1",
+ "smob": "^1.0.0",
+ "terser": "^5.17.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
+ "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.53.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
@@ -1325,6 +2747,19 @@
"win32"
]
},
+ "node_modules/@surma/rollup-plugin-off-main-thread": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
+ "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "ejs": "^3.1.6",
+ "json5": "^2.2.0",
+ "magic-string": "^0.25.0",
+ "string.prototype.matchall": "^4.0.6"
+ }
+ },
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -1390,7 +2825,6 @@
"integrity": "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -1401,7 +2835,6 @@
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -1416,6 +2849,20 @@
"@types/react": "^19.2.0"
}
},
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.49.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.49.0.tgz",
@@ -1461,7 +2908,6 @@
"integrity": "sha512-N9lBGA9o9aqb1hVMc9hzySbhKibHmB+N3IpoShyV6HyQYRGIhlrO5rQgttypi+yEeKsKI4idxC8Jw6gXKD4THA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.49.0",
"@typescript-eslint/types": "8.49.0",
@@ -1713,7 +3159,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -1771,6 +3216,130 @@
"dev": true,
"license": "Python-2.0"
},
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.15",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz",
+ "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-define-polyfill-provider": "^0.6.6",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz",
+ "integrity": "sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.6",
+ "core-js-compat": "^3.48.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz",
+ "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.6"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1819,7 +3388,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -1834,6 +3402,63 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -1902,6 +3527,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/common-tags": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1916,6 +3558,20 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/core-js-compat": {
+ "version": "3.48.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz",
+ "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -1931,6 +3587,16 @@
"node": ">= 8"
}
},
+ "node_modules/crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@@ -1938,6 +3604,60 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
@@ -1963,6 +3683,83 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.267",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
@@ -1970,6 +3767,142 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/es-abstract": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
+ "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "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/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/esbuild": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
@@ -2041,7 +3974,6 @@
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -2210,6 +4142,13 @@
"node": ">=4.0"
}
},
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -2241,6 +4180,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
@@ -2272,6 +4228,39 @@
"node": ">=16.0.0"
}
},
+ "node_modules/filelist": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
+ "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
+ "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -2310,6 +4299,55 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -2325,6 +4363,57 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -2335,6 +4424,95 @@
"node": ">=6.9.0"
}
},
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-own-enumerable-property-symbols": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
+ "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "foreground-child": "^3.3.1",
+ "jackspeak": "^4.1.1",
+ "minimatch": "^10.1.1",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -2348,6 +4526,45 @@
"node": ">=10.13.0"
}
},
+ "node_modules/glob/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
+ "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "10.2.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
+ "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/globals": {
"version": "16.5.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
@@ -2361,6 +4578,56 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -2371,6 +4638,77 @@
"node": ">=8"
}
},
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "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.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/hermes-estree": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
@@ -2388,6 +4726,13 @@
"hermes-estree": "0.25.1"
}
},
+ "node_modules/idb": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
+ "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -2425,6 +4770,156 @@
"node": ">=0.8.19"
}
},
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -2435,6 +4930,42 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -2448,6 +4979,241 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -2455,6 +5221,40 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/jackspeak": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz",
+ "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^9.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/jake": {
+ "version": "10.9.4",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
+ "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.6",
+ "filelist": "^1.0.4",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2495,6 +5295,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true,
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
+ },
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2522,6 +5329,29 @@
"node": ">=6"
}
},
+ "node_modules/jsonfile": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
+ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonpointer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
+ "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -2532,6 +5362,16 @@
"json-buffer": "3.0.1"
}
},
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -2562,6 +5402,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.23",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
+ "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -2569,6 +5423,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -2579,6 +5440,26 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -2592,6 +5473,16 @@
"node": "*"
}
},
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -2632,6 +5523,50 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -2650,6 +5585,24 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -2682,6 +5635,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -2715,6 +5675,40 @@
"node": ">=8"
}
},
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "11.2.6",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
+ "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -2728,7 +5722,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -2736,6 +5729,16 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@@ -2775,6 +5778,19 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/pretty-bytes": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
+ "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -2785,12 +5801,21 @@
"node": ">=6"
}
},
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
"node_modules/react": {
"version": "19.2.1",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz",
"integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -2817,6 +5842,139 @@
"node": ">=0.10.0"
}
},
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz",
+ "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz",
+ "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.2.2",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.13.0",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regjsparser": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz",
+ "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "jsesc": "~3.1.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.11",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
+ "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -2869,6 +6027,82 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/scheduler": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
@@ -2885,6 +6119,65 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -2908,6 +6201,119 @@
"node": ">=8"
}
},
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "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.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "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.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/smob": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz",
+ "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "deprecated": "The work that was done in this beta branch won't be included in future versions",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -2918,6 +6324,161 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sourcemap-codec": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "deprecated": "Please use @jridgewell/sourcemap-codec instead",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.3",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/stringify-object": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
+ "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "get-own-enumerable-property-symbols": "^3.0.0",
+ "is-obj": "^1.0.1",
+ "is-regexp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
+ "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -2944,6 +6505,67 @@
"node": ">=8"
}
},
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/temp-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
+ "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tempy": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz",
+ "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-stream": "^2.0.0",
+ "temp-dir": "^2.0.0",
+ "type-fest": "^0.16.0",
+ "unique-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.46.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
+ "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
@@ -2961,6 +6583,16 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
+ "node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
"node_modules/ts-api-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
@@ -2974,6 +6606,12 @@
"typescript": ">=4.8.4"
}
},
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -2987,13 +6625,103 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/type-fest": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
+ "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -3026,6 +6754,25 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
@@ -3033,6 +6780,84 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
+ "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "crypto-random-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
@@ -3080,7 +6905,6 @@
"integrity": "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -3150,6 +6974,56 @@
}
}
},
+ "node_modules/vite-plugin-pwa": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz",
+ "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.6",
+ "pretty-bytes": "^6.1.1",
+ "tinyglobby": "^0.2.10",
+ "workbox-build": "^7.4.0",
+ "workbox-window": "^7.4.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vite-pwa/assets-generator": "^1.0.0",
+ "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
+ "workbox-build": "^7.4.0",
+ "workbox-window": "^7.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@vite-pwa/assets-generator": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -3166,6 +7040,95 @@
"node": ">= 8"
}
},
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.20",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
+ "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
@@ -3176,6 +7139,367 @@
"node": ">=0.10.0"
}
},
+ "node_modules/workbox-background-sync": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz",
+ "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "idb": "^7.0.1",
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-broadcast-update": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz",
+ "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-build": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz",
+ "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@apideck/better-ajv-errors": "^0.3.1",
+ "@babel/core": "^7.24.4",
+ "@babel/preset-env": "^7.11.0",
+ "@babel/runtime": "^7.11.2",
+ "@rollup/plugin-babel": "^5.2.0",
+ "@rollup/plugin-node-resolve": "^15.2.3",
+ "@rollup/plugin-replace": "^2.4.1",
+ "@rollup/plugin-terser": "^0.4.3",
+ "@surma/rollup-plugin-off-main-thread": "^2.2.3",
+ "ajv": "^8.6.0",
+ "common-tags": "^1.8.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "fs-extra": "^9.0.1",
+ "glob": "^11.0.1",
+ "lodash": "^4.17.20",
+ "pretty-bytes": "^5.3.0",
+ "rollup": "^2.79.2",
+ "source-map": "^0.8.0-beta.0",
+ "stringify-object": "^3.3.0",
+ "strip-comments": "^2.0.1",
+ "tempy": "^0.6.0",
+ "upath": "^1.2.0",
+ "workbox-background-sync": "7.4.0",
+ "workbox-broadcast-update": "7.4.0",
+ "workbox-cacheable-response": "7.4.0",
+ "workbox-core": "7.4.0",
+ "workbox-expiration": "7.4.0",
+ "workbox-google-analytics": "7.4.0",
+ "workbox-navigation-preload": "7.4.0",
+ "workbox-precaching": "7.4.0",
+ "workbox-range-requests": "7.4.0",
+ "workbox-recipes": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0",
+ "workbox-streams": "7.4.0",
+ "workbox-sw": "7.4.0",
+ "workbox-window": "7.4.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
+ "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-schema": "^0.4.0",
+ "jsonpointer": "^5.0.0",
+ "leven": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "ajv": ">=8"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@rollup/plugin-babel": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
+ "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.10.4",
+ "@rollup/pluginutils": "^3.1.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "@types/babel__core": "^7.1.9",
+ "rollup": "^1.20.0||^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/babel__core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/workbox-build/node_modules/@rollup/plugin-replace": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
+ "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^3.1.0",
+ "magic-string": "^0.25.7"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0 || ^2.0.0"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/workbox-build/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/workbox-build/node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/workbox-build/node_modules/rollup": {
+ "version": "2.80.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz",
+ "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/workbox-cacheable-response": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz",
+ "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-core": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz",
+ "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-expiration": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz",
+ "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "idb": "^7.0.1",
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-google-analytics": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz",
+ "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-background-sync": "7.4.0",
+ "workbox-core": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0"
+ }
+ },
+ "node_modules/workbox-navigation-preload": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz",
+ "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-precaching": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz",
+ "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0"
+ }
+ },
+ "node_modules/workbox-range-requests": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz",
+ "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-recipes": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz",
+ "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-cacheable-response": "7.4.0",
+ "workbox-core": "7.4.0",
+ "workbox-expiration": "7.4.0",
+ "workbox-precaching": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0"
+ }
+ },
+ "node_modules/workbox-routing": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz",
+ "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-strategies": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz",
+ "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0"
+ }
+ },
+ "node_modules/workbox-streams": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz",
+ "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.4.0",
+ "workbox-routing": "7.4.0"
+ }
+ },
+ "node_modules/workbox-sw": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz",
+ "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-window": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz",
+ "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2",
+ "workbox-core": "7.4.0"
+ }
+ },
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -3202,7 +7526,6 @@
"integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==",
"dev": true,
"license": "MIT",
- "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/mengyamonitor-frontend/package.json b/mengyamonitor-frontend/package.json
index 17acb5b..8903a70 100644
--- a/mengyamonitor-frontend/package.json
+++ b/mengyamonitor-frontend/package.json
@@ -10,6 +10,9 @@
"preview": "vite preview"
},
"dependencies": {
+ "@dnd-kit/core": "^6.3.1",
+ "@dnd-kit/sortable": "^10.0.0",
+ "@dnd-kit/utilities": "^3.2.2",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
@@ -25,6 +28,7 @@
"globals": "^16.5.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
- "vite": "^7.2.4"
+ "vite": "^7.2.4",
+ "vite-plugin-pwa": "^1.2.0"
}
}
diff --git a/mengyamonitor-frontend/public/logo.svg b/mengyamonitor-frontend/public/logo.svg
new file mode 100644
index 0000000..70974ae
--- /dev/null
+++ b/mengyamonitor-frontend/public/logo.svg
@@ -0,0 +1,16 @@
+
diff --git a/mengyamonitor-frontend/src/App.css b/mengyamonitor-frontend/src/App.css
index b8bc260..7522e95 100644
--- a/mengyamonitor-frontend/src/App.css
+++ b/mengyamonitor-frontend/src/App.css
@@ -16,25 +16,87 @@
border-radius: var(--radius-md);
box-shadow: var(--shadow-sm);
border: 1px solid var(--border-color);
+ transition: all 0.3s ease;
+}
+
+.header-actions {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
}
.app-header h1 {
margin: 0;
- font-size: 0.75rem;
- color: var(--text-light);
+ font-size: 1.5rem;
+ color: var(--text-main);
display: flex;
align-items: center;
- gap: 0.25rem;
- font-weight: 400;
+ gap: 0.75rem;
+ font-weight: 600;
+ transform: translateY(-3px);
}
.app-logo {
- width: 16px;
- height: 16px;
- border-radius: 4px;
+ width: 36px;
+ height: 36px;
+ border-radius: 6px;
display: inline-block;
}
+.btn-icon {
+ background: var(--surface-color);
+ color: var(--text-main);
+ border: 1px solid var(--border-color);
+ padding: 0.5rem;
+ width: 32px;
+ height: 32px;
+ border-radius: var(--radius-md);
+ font-size: 1rem;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ box-shadow: var(--shadow-sm);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ line-height: 1;
+}
+
+.btn-icon:hover {
+ background: var(--bg-color);
+ border-color: var(--primary-color);
+ transform: translateY(-1px);
+ box-shadow: var(--shadow-md);
+}
+
+.btn-show-header {
+ position: fixed;
+ top: 5px;
+ right: 5px;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.5);
+ border: 1px solid var(--border-color);
+ color: var(--text-secondary);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.75rem;
+ z-index: 1000;
+ opacity: 0.5;
+ transition: all 0.2s;
+ padding: 0;
+}
+
+.btn-show-header:hover {
+ opacity: 1;
+ background: var(--surface-color);
+ box-shadow: var(--shadow-sm);
+ transform: scale(1.1);
+ color: var(--primary-color);
+}
+
.btn-add {
background: var(--primary-color);
color: white;
@@ -163,16 +225,7 @@
justify-content: center;
}
- .server-grid {
- grid-template-columns: 1fr;
- }
-
- .add-form {
- flex-direction: column;
- padding: 1.5rem;
- }
-
- .add-form input {
- min-width: 100%;
+ .header-actions {
+ justify-content: center;
}
}
diff --git a/mengyamonitor-frontend/src/App.tsx b/mengyamonitor-frontend/src/App.tsx
index 891f866..151abe4 100644
--- a/mengyamonitor-frontend/src/App.tsx
+++ b/mengyamonitor-frontend/src/App.tsx
@@ -1,34 +1,80 @@
import { useState, useEffect } from 'react';
import type { ServerConfig } from './types';
-import { loadServers, saveServers, removeServer } from './utils/storage';
+import { loadServers, saveServers, removeServer, exportServersToClipboard, importServersFromClipboard } from './utils/storage';
import { useServerMonitor } from './hooks/useServerMonitor';
import { ServerCard } from './components/ServerCard/ServerCard';
import { ServerDetail } from './components/ServerDetail/ServerDetail';
+import {
+ DndContext,
+ closestCenter,
+ KeyboardSensor,
+ PointerSensor,
+ useSensor,
+ useSensors,
+} from '@dnd-kit/core';
+import type { DragEndEvent } from '@dnd-kit/core';
+import {
+ arrayMove,
+ SortableContext,
+ sortableKeyboardCoordinates,
+ rectSortingStrategy,
+} from '@dnd-kit/sortable';
import './App.css';
+const formatServerUrl = (url: string) => {
+ let formatted = url.trim();
+
+ // Fix common typo .op -> .top based on user requirement
+ if (formatted.endsWith('.op')) {
+ formatted = formatted.slice(0, -3) + '.top';
+ }
+
+ if (formatted && !/^https?:\/\//i.test(formatted)) {
+ return `http://${formatted}`;
+ }
+ return formatted;
+};
+
function App() {
const [servers, setServers] = useState([]);
const [showAddForm, setShowAddForm] = useState(false);
const [selectedServerId, setSelectedServerId] = useState(null);
const [newServerForm, setNewServerForm] = useState({ name: '', url: '' });
+ const [showHeader, setShowHeader] = useState(true);
const statuses = useServerMonitor(servers, 2000);
+ const sensors = useSensors(
+ useSensor(PointerSensor),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates,
+ })
+ );
+
useEffect(() => {
const loaded = loadServers();
setServers(loaded);
}, []);
+ const handleUrlBlur = () => {
+ const formatted = formatServerUrl(newServerForm.url);
+ if (formatted !== newServerForm.url) {
+ setNewServerForm(prev => ({ ...prev, url: formatted }));
+ }
+ };
+
const handleAddServer = () => {
if (!newServerForm.name || !newServerForm.url) {
alert('请填写服务器名称和地址');
return;
}
+ const formattedUrl = formatServerUrl(newServerForm.url);
+
const newServer: ServerConfig = {
id: Date.now().toString(),
name: newServerForm.name,
- url: newServerForm.url,
+ url: formattedUrl,
enabled: true,
};
@@ -51,20 +97,94 @@ function App() {
setSelectedServerId(serverId);
};
+ const handleExportServers = async () => {
+ try {
+ await exportServersToClipboard();
+ alert('服务器配置已复制到剪贴板!');
+ } catch (error) {
+ alert(error instanceof Error ? error.message : '导出失败');
+ }
+ };
+
+ const handleImportServers = async () => {
+ if (!confirm('导入服务器配置将添加到现有服务器列表中,是否继续?')) {
+ return;
+ }
+
+ try {
+ const importedServers = await importServersFromClipboard();
+ const updated = [...servers, ...importedServers];
+ setServers(updated);
+ saveServers(updated);
+ alert(`成功导入 ${importedServers.length} 个服务器配置!`);
+ } catch (error) {
+ alert(error instanceof Error ? error.message : '导入失败');
+ }
+ };
+
+ const handleDragEnd = (event: DragEndEvent) => {
+ const { active, over } = event;
+
+ if (over && active.id !== over.id) {
+ setServers((items) => {
+ const oldIndex = items.findIndex((item) => item.id === active.id);
+ const newIndex = items.findIndex((item) => item.id === over.id);
+ const newOrder = arrayMove(items, oldIndex, newIndex);
+ saveServers(newOrder);
+ return newOrder;
+ });
+ }
+ };
+
const selectedStatus = selectedServerId ? statuses[selectedServerId] : null;
const selectedServer = servers.find(s => s.id === selectedServerId);
return (
-
-
-
- 萌芽监控面板
-
-