StarrySkyWorld commited on
Commit
8820bb8
·
0 Parent(s):
.dockerignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ .git
2
+ .gitignore
3
+ node_modules
4
+ frontend/node_modules
5
+ frontend/dist
6
+ backend/data
7
+ *.log
.env.example ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ PORT=7860
2
+ ADMIN_PASSWORD=
.gitignore ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ backend/data/
2
+ backend/web/dist/
3
+ frontend/node_modules/
4
+ frontend/dist/
5
+
6
+ *.exe
Dockerfile ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:24-alpine AS frontend-builder
2
+ WORKDIR /app/frontend
3
+ COPY frontend/package.json ./
4
+ RUN npm install
5
+ COPY frontend ./
6
+ RUN npm run build
7
+
8
+ FROM golang:1.25-alpine AS backend-builder
9
+ WORKDIR /app/backend
10
+ COPY backend/go.mod ./
11
+ RUN go mod download
12
+ COPY backend ./
13
+ COPY --from=frontend-builder /app/frontend/dist ./web/dist
14
+ RUN go build -o /out/fastfileviewer ./cmd/server
15
+
16
+ FROM alpine:3.22
17
+ WORKDIR /app
18
+ ENV PORT=7860
19
+ COPY --from=backend-builder /out/fastfileviewer /app/fastfileviewer
20
+ EXPOSE 7860
21
+ CMD ["/app/fastfileviewer"]
README.md ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FastFileViewer
2
+
3
+ `FastFileViewer` 是一个基于 `Golang + Gin + React` 的 Web 文件浏览器,支持服务端异步任务:
4
+
5
+ - 在沙箱根目录内浏览、上传、删除、移动、重命名文件
6
+ - 发起服务端 URL 下载任务
7
+ - 发起压缩包解压任务(支持 `.zip`、`.tar.gz`、`.tgz`)
8
+ - 使用 SQLite 持久化任务状态并展示进度
9
+
10
+ ## 项目结构
11
+
12
+ - `backend/`:Gin API、鉴权、文件操作、任务执行器
13
+ - `frontend/`:React + Vite + Ant Design 前端界面
14
+ - `Dockerfile`:单容器生产镜像
15
+
16
+ ## 本地运行(Windows PowerShell)
17
+
18
+ 1. 确保 Go SDK 可用。你当前机器上可用路径是:
19
+ - `C:\Users\liu_q\sdk\go1.25.0\bin\go.exe`
20
+ 2. 直接启动后端(默认零配置):
21
+
22
+ ```powershell
23
+ cd backend
24
+ C:\Users\liu_q\sdk\go1.25.0\bin\go.exe mod tidy
25
+ C:\Users\liu_q\sdk\go1.25.0\bin\go.exe run ./cmd/server
26
+ ```
27
+
28
+ 3. 启动前端(新开一个终端):
29
+
30
+ ```powershell
31
+ cd frontend
32
+ npm install
33
+ npm run dev
34
+ ```
35
+
36
+ 浏览器访问:`http://localhost:5173`
37
+
38
+ 说明:
39
+ - 如果没有设置 `ADMIN_PASSWORD`,服务启动时会自动生成一个临时管理员密码,并打印在后端日志中。
40
+ - `JWT_SECRET`、`ROOT_DIR`、`DB_PATH`、`MAX_WORKERS` 都由程序自动生成或自动创建,无需手动配置。
41
+
42
+ ## API 一览
43
+
44
+ - `POST /api/login`
45
+ - `GET /api/fs/list?path=.`
46
+ - `POST /api/fs/upload`(form-data:`dir`、`file`)
47
+ - `POST /api/fs/move`
48
+ - `POST /api/fs/rename`
49
+ - `POST /api/fs/delete`
50
+ - `GET /api/fs/download?path=...`
51
+ - `POST /api/tasks/download`
52
+ - `POST /api/tasks/extract`
53
+ - `GET /api/tasks`
54
+ - `GET /api/tasks/:id`
55
+ - `GET /api/tasks/:id/stream`(SSE)
56
+
57
+ ## 部署到 Hugging Face Space
58
+
59
+ 项目已经按单容器部署方式配置:
60
+
61
+ 1. 使用 `Dockerfile` 构建镜像
62
+ 2. 环境变量只建议配置两个:
63
+ - `PORT`(默认 `7860`)
64
+ - `ADMIN_PASSWORD`(可选,不配则启动时自动生成)
65
+ 3. 暴露端口:`PORT=7860`(或你自定义的端口)
66
+
67
+ ## 安全说明
68
+
69
+ - 所有文件操作都限制在 `ROOT_DIR` 目录内
70
+ - 除登录与健康检查外,`/api/*` 都需要 JWT 鉴权
71
+ - 解压逻辑包含路径穿越防护
backend/cmd/server/main.go ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package main
2
+
3
+ import (
4
+ "context"
5
+ "log"
6
+ "net/http"
7
+ "os"
8
+ "path/filepath"
9
+
10
+ "fastfileviewer/backend/internal/config"
11
+ "fastfileviewer/backend/internal/db"
12
+ "fastfileviewer/backend/internal/handlers"
13
+ "fastfileviewer/backend/internal/middleware"
14
+ "fastfileviewer/backend/internal/services"
15
+ "github.com/gin-gonic/gin"
16
+ )
17
+
18
+ func main() {
19
+ cfg := config.Load()
20
+ if cfg.AutoPassword {
21
+ log.Printf("ADMIN_PASSWORD 未设置,已自动生成临时密码: %s", cfg.AdminPassword)
22
+ }
23
+
24
+ if err := os.MkdirAll(cfg.RootDir, 0o755); err != nil {
25
+ log.Fatalf("create root dir failed: %v", err)
26
+ }
27
+
28
+ database, err := db.New(cfg.DBPath)
29
+ if err != nil {
30
+ log.Fatalf("db init failed: %v", err)
31
+ }
32
+
33
+ fsSvc := services.NewFSService(cfg.RootDir)
34
+ taskSvc := services.NewTaskService(database, fsSvc, cfg.MaxWorkers)
35
+ taskSvc.Start(context.Background())
36
+
37
+ authHandler := handlers.NewAuthHandler(cfg)
38
+ fileHandler := handlers.NewFileHandler(fsSvc)
39
+ taskHandler := handlers.NewTaskHandler(taskSvc)
40
+
41
+ router := gin.Default()
42
+ router.GET("/healthz", func(ctx *gin.Context) {
43
+ ctx.JSON(http.StatusOK, gin.H{"ok": true})
44
+ })
45
+ router.POST("/api/login", authHandler.Login)
46
+
47
+ api := router.Group("/api")
48
+ api.Use(middleware.AuthRequired(cfg.JWTSecret))
49
+ {
50
+ api.GET("/fs/list", fileHandler.List)
51
+ api.POST("/fs/upload", fileHandler.Upload)
52
+ api.POST("/fs/move", fileHandler.Move)
53
+ api.POST("/fs/rename", fileHandler.Rename)
54
+ api.POST("/fs/delete", fileHandler.Delete)
55
+ api.GET("/fs/download", fileHandler.Download)
56
+
57
+ api.POST("/tasks/download", taskHandler.CreateDownload)
58
+ api.POST("/tasks/extract", taskHandler.CreateExtract)
59
+ api.GET("/tasks", taskHandler.List)
60
+ api.GET("/tasks/:id", taskHandler.Get)
61
+ api.GET("/tasks/:id/stream", taskHandler.Stream)
62
+ }
63
+
64
+ frontendDist := filepath.Join("web", "dist")
65
+ if _, err := os.Stat(frontendDist); err == nil {
66
+ router.Static("/assets", filepath.Join(frontendDist, "assets"))
67
+ router.NoRoute(func(ctx *gin.Context) {
68
+ ctx.File(filepath.Join(frontendDist, "index.html"))
69
+ })
70
+ }
71
+
72
+ log.Printf("server listening on :%s", cfg.Port)
73
+ log.Printf("storage root: %s", cfg.RootDir)
74
+ if err := router.Run(":" + cfg.Port); err != nil {
75
+ log.Fatalf("server failed: %v", err)
76
+ }
77
+ }
backend/go.mod ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module fastfileviewer/backend
2
+
3
+ go 1.25.0
4
+
5
+ require (
6
+ github.com/gin-gonic/gin v1.11.0
7
+ github.com/golang-jwt/jwt/v5 v5.2.3
8
+ gorm.io/driver/sqlite v1.6.0
9
+ gorm.io/gorm v1.31.1
10
+ )
11
+
12
+ require (
13
+ github.com/bytedance/sonic v1.14.0 // indirect
14
+ github.com/bytedance/sonic/loader v0.3.0 // indirect
15
+ github.com/cloudwego/base64x v0.1.6 // indirect
16
+ github.com/gabriel-vasile/mimetype v1.4.8 // indirect
17
+ github.com/gin-contrib/sse v1.1.0 // indirect
18
+ github.com/go-playground/locales v0.14.1 // indirect
19
+ github.com/go-playground/universal-translator v0.18.1 // indirect
20
+ github.com/go-playground/validator/v10 v10.27.0 // indirect
21
+ github.com/goccy/go-json v0.10.2 // indirect
22
+ github.com/goccy/go-yaml v1.18.0 // indirect
23
+ github.com/jinzhu/inflection v1.0.0 // indirect
24
+ github.com/jinzhu/now v1.1.5 // indirect
25
+ github.com/json-iterator/go v1.1.12 // indirect
26
+ github.com/klauspost/cpuid/v2 v2.3.0 // indirect
27
+ github.com/leodido/go-urn v1.4.0 // indirect
28
+ github.com/mattn/go-isatty v0.0.20 // indirect
29
+ github.com/mattn/go-sqlite3 v1.14.22 // indirect
30
+ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
31
+ github.com/modern-go/reflect2 v1.0.2 // indirect
32
+ github.com/pelletier/go-toml/v2 v2.2.4 // indirect
33
+ github.com/quic-go/qpack v0.5.1 // indirect
34
+ github.com/quic-go/quic-go v0.54.0 // indirect
35
+ github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
36
+ github.com/ugorji/go/codec v1.3.0 // indirect
37
+ go.uber.org/mock v0.5.0 // indirect
38
+ golang.org/x/arch v0.20.0 // indirect
39
+ golang.org/x/crypto v0.40.0 // indirect
40
+ golang.org/x/mod v0.25.0 // indirect
41
+ golang.org/x/net v0.42.0 // indirect
42
+ golang.org/x/sync v0.16.0 // indirect
43
+ golang.org/x/sys v0.35.0 // indirect
44
+ golang.org/x/text v0.27.0 // indirect
45
+ golang.org/x/tools v0.34.0 // indirect
46
+ google.golang.org/protobuf v1.36.9 // indirect
47
+ )
backend/go.sum ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
2
+ github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
3
+ github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
4
+ github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
5
+ github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
6
+ github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
7
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8
+ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9
+ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10
+ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
11
+ github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
12
+ github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
13
+ github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
14
+ github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
15
+ github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
16
+ github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
17
+ github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
18
+ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
19
+ github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
20
+ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
21
+ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
22
+ github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
23
+ github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
24
+ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
25
+ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
26
+ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
27
+ github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
28
+ github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0=
29
+ github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
30
+ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
31
+ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
32
+ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
33
+ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
34
+ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
35
+ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
36
+ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
37
+ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
38
+ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
39
+ github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
40
+ github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
41
+ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
42
+ github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
43
+ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
44
+ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
45
+ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
46
+ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
47
+ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
48
+ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
49
+ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
50
+ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
51
+ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
52
+ github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
53
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
54
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
55
+ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
56
+ github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
57
+ github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
58
+ github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
59
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
60
+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
61
+ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
62
+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
63
+ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
64
+ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
65
+ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
66
+ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
67
+ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
68
+ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
69
+ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
70
+ github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
71
+ github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
72
+ go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
73
+ go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
74
+ golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
75
+ golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
76
+ golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
77
+ golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
78
+ golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
79
+ golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
80
+ golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
81
+ golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
82
+ golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
83
+ golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
84
+ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
85
+ golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
86
+ golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
87
+ golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
88
+ golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
89
+ golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
90
+ golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
91
+ google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
92
+ google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
93
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
94
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
95
+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
96
+ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
97
+ gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
98
+ gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
99
+ gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
100
+ gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
backend/internal/config/config.go ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package config
2
+
3
+ import (
4
+ "crypto/rand"
5
+ "encoding/base64"
6
+ "os"
7
+ "path/filepath"
8
+ "runtime"
9
+ "time"
10
+ )
11
+
12
+ type Config struct {
13
+ Port string
14
+ AdminPassword string
15
+ JWTSecret string
16
+ RootDir string
17
+ DBPath string
18
+ MaxWorkers int
19
+ TokenTTL time.Duration
20
+ AutoPassword bool
21
+ }
22
+
23
+ func Load() Config {
24
+ adminPassword := os.Getenv("ADMIN_PASSWORD")
25
+ autoPassword := false
26
+ if adminPassword == "" {
27
+ adminPassword = mustRandomToken(18)
28
+ autoPassword = true
29
+ }
30
+
31
+ rootDir := filepath.Clean(filepath.Join(".", "data"))
32
+ maxWorkers := runtime.NumCPU() / 2
33
+ if maxWorkers < 2 {
34
+ maxWorkers = 2
35
+ }
36
+
37
+ return Config{
38
+ Port: getEnv("PORT", "7860"),
39
+ AdminPassword: adminPassword,
40
+ JWTSecret: mustRandomToken(32),
41
+ RootDir: rootDir,
42
+ DBPath: filepath.Join(rootDir, "tasks.db"),
43
+ MaxWorkers: maxWorkers,
44
+ TokenTTL: 24 * time.Hour,
45
+ AutoPassword: autoPassword,
46
+ }
47
+ }
48
+
49
+ func getEnv(key, fallback string) string {
50
+ if value := os.Getenv(key); value != "" {
51
+ return value
52
+ }
53
+ return fallback
54
+ }
55
+
56
+ func mustRandomToken(numBytes int) string {
57
+ buf := make([]byte, numBytes)
58
+ _, err := rand.Read(buf)
59
+ if err != nil {
60
+ panic(err)
61
+ }
62
+ return base64.RawURLEncoding.EncodeToString(buf)
63
+ }
backend/internal/db/db.go ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package db
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "path/filepath"
7
+
8
+ "fastfileviewer/backend/internal/models"
9
+ "gorm.io/driver/sqlite"
10
+ "gorm.io/gorm"
11
+ )
12
+
13
+ func New(dbPath string) (*gorm.DB, error) {
14
+ if err := os.MkdirAll(filepath.Dir(dbPath), 0o755); err != nil {
15
+ return nil, fmt.Errorf("create db dir: %w", err)
16
+ }
17
+
18
+ database, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
19
+ if err != nil {
20
+ return nil, fmt.Errorf("open db: %w", err)
21
+ }
22
+
23
+ if err := database.AutoMigrate(&models.Task{}); err != nil {
24
+ return nil, fmt.Errorf("migrate: %w", err)
25
+ }
26
+
27
+ return database, nil
28
+ }
backend/internal/handlers/auth.go ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package handlers
2
+
3
+ import (
4
+ "net/http"
5
+
6
+ "fastfileviewer/backend/internal/config"
7
+ "fastfileviewer/backend/internal/middleware"
8
+ "github.com/gin-gonic/gin"
9
+ )
10
+
11
+ type AuthHandler struct {
12
+ cfg config.Config
13
+ }
14
+
15
+ func NewAuthHandler(cfg config.Config) *AuthHandler {
16
+ return &AuthHandler{cfg: cfg}
17
+ }
18
+
19
+ type loginRequest struct {
20
+ Password string `json:"password"`
21
+ }
22
+
23
+ func (h *AuthHandler) Login(ctx *gin.Context) {
24
+ var req loginRequest
25
+ if err := ctx.ShouldBindJSON(&req); err != nil {
26
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
27
+ return
28
+ }
29
+ if req.Password != h.cfg.AdminPassword {
30
+ ctx.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"})
31
+ return
32
+ }
33
+
34
+ token, err := middleware.IssueToken(h.cfg.JWTSecret, h.cfg.TokenTTL)
35
+ if err != nil {
36
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": "failed to issue token"})
37
+ return
38
+ }
39
+ ctx.JSON(http.StatusOK, gin.H{"token": token})
40
+ }
backend/internal/handlers/filesystem.go ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package handlers
2
+
3
+ import (
4
+ "net/http"
5
+ "os"
6
+ "path/filepath"
7
+
8
+ "fastfileviewer/backend/internal/services"
9
+ "github.com/gin-gonic/gin"
10
+ )
11
+
12
+ type FileHandler struct {
13
+ fs *services.FSService
14
+ }
15
+
16
+ func NewFileHandler(fs *services.FSService) *FileHandler {
17
+ return &FileHandler{fs: fs}
18
+ }
19
+
20
+ func (h *FileHandler) List(ctx *gin.Context) {
21
+ path := ctx.DefaultQuery("path", ".")
22
+ entries, err := h.fs.List(path)
23
+ if err != nil {
24
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
25
+ return
26
+ }
27
+ ctx.JSON(http.StatusOK, gin.H{
28
+ "path": filepath.ToSlash(path),
29
+ "entries": entries,
30
+ })
31
+ }
32
+
33
+ func (h *FileHandler) Delete(ctx *gin.Context) {
34
+ var req struct {
35
+ Path string `json:"path"`
36
+ }
37
+ if err := ctx.ShouldBindJSON(&req); err != nil || req.Path == "" {
38
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
39
+ return
40
+ }
41
+ if err := h.fs.Delete(req.Path); err != nil {
42
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
43
+ return
44
+ }
45
+ ctx.JSON(http.StatusOK, gin.H{"ok": true})
46
+ }
47
+
48
+ func (h *FileHandler) Rename(ctx *gin.Context) {
49
+ var req struct {
50
+ Path string `json:"path"`
51
+ NewName string `json:"newName"`
52
+ }
53
+ if err := ctx.ShouldBindJSON(&req); err != nil || req.Path == "" || req.NewName == "" {
54
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
55
+ return
56
+ }
57
+ if err := h.fs.Rename(req.Path, req.NewName); err != nil {
58
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
59
+ return
60
+ }
61
+ ctx.JSON(http.StatusOK, gin.H{"ok": true})
62
+ }
63
+
64
+ func (h *FileHandler) Move(ctx *gin.Context) {
65
+ var req struct {
66
+ From string `json:"from"`
67
+ To string `json:"to"`
68
+ }
69
+ if err := ctx.ShouldBindJSON(&req); err != nil || req.From == "" || req.To == "" {
70
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
71
+ return
72
+ }
73
+ if err := h.fs.Move(req.From, req.To); err != nil {
74
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
75
+ return
76
+ }
77
+ ctx.JSON(http.StatusOK, gin.H{"ok": true})
78
+ }
79
+
80
+ func (h *FileHandler) Upload(ctx *gin.Context) {
81
+ dir := ctx.DefaultPostForm("dir", ".")
82
+ file, err := ctx.FormFile("file")
83
+ if err != nil {
84
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "missing file"})
85
+ return
86
+ }
87
+ src, err := file.Open()
88
+ if err != nil {
89
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "failed to open upload"})
90
+ return
91
+ }
92
+ defer src.Close()
93
+
94
+ target := filepath.ToSlash(filepath.Join(dir, file.Filename))
95
+ if err := h.fs.SaveUploadedFile(src, target); err != nil {
96
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
97
+ return
98
+ }
99
+ ctx.JSON(http.StatusOK, gin.H{"ok": true, "path": target})
100
+ }
101
+
102
+ func (h *FileHandler) Download(ctx *gin.Context) {
103
+ raw := ctx.Query("path")
104
+ if raw == "" {
105
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "path is required"})
106
+ return
107
+ }
108
+ resolved, err := h.fs.ResolvePath(raw)
109
+ if err != nil {
110
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
111
+ return
112
+ }
113
+ stat, err := os.Stat(resolved)
114
+ if err != nil || stat.IsDir() {
115
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "file not found"})
116
+ return
117
+ }
118
+ ctx.FileAttachment(resolved, filepath.Base(resolved))
119
+ }
backend/internal/handlers/tasks.go ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package handlers
2
+
3
+ import (
4
+ "encoding/json"
5
+ "net/http"
6
+ "strconv"
7
+ "time"
8
+
9
+ "fastfileviewer/backend/internal/services"
10
+ "github.com/gin-gonic/gin"
11
+ )
12
+
13
+ type TaskHandler struct {
14
+ tasks *services.TaskService
15
+ }
16
+
17
+ func NewTaskHandler(tasks *services.TaskService) *TaskHandler {
18
+ return &TaskHandler{tasks: tasks}
19
+ }
20
+
21
+ func (h *TaskHandler) CreateDownload(ctx *gin.Context) {
22
+ var req struct {
23
+ URL string `json:"url"`
24
+ TargetPath string `json:"targetPath"`
25
+ }
26
+ if err := ctx.ShouldBindJSON(&req); err != nil || req.URL == "" || req.TargetPath == "" {
27
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
28
+ return
29
+ }
30
+ task, err := h.tasks.CreateDownloadTask(req.URL, req.TargetPath)
31
+ if err != nil {
32
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
33
+ return
34
+ }
35
+ ctx.JSON(http.StatusAccepted, task)
36
+ }
37
+
38
+ func (h *TaskHandler) CreateExtract(ctx *gin.Context) {
39
+ var req struct {
40
+ SourcePath string `json:"sourcePath"`
41
+ TargetPath string `json:"targetPath"`
42
+ }
43
+ if err := ctx.ShouldBindJSON(&req); err != nil || req.SourcePath == "" || req.TargetPath == "" {
44
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
45
+ return
46
+ }
47
+ task, err := h.tasks.CreateExtractTask(req.SourcePath, req.TargetPath)
48
+ if err != nil {
49
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
50
+ return
51
+ }
52
+ ctx.JSON(http.StatusAccepted, task)
53
+ }
54
+
55
+ func (h *TaskHandler) List(ctx *gin.Context) {
56
+ limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "50"))
57
+ tasks, err := h.tasks.ListTasks(limit)
58
+ if err != nil {
59
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
60
+ return
61
+ }
62
+ ctx.JSON(http.StatusOK, gin.H{"tasks": tasks})
63
+ }
64
+
65
+ func (h *TaskHandler) Get(ctx *gin.Context) {
66
+ id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
67
+ if err != nil {
68
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
69
+ return
70
+ }
71
+ task, err := h.tasks.GetTask(uint(id))
72
+ if err != nil {
73
+ ctx.JSON(http.StatusNotFound, gin.H{"error": "task not found"})
74
+ return
75
+ }
76
+ ctx.JSON(http.StatusOK, task)
77
+ }
78
+
79
+ func (h *TaskHandler) Stream(ctx *gin.Context) {
80
+ id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
81
+ if err != nil {
82
+ ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
83
+ return
84
+ }
85
+
86
+ ch, cancel := h.tasks.Subscribe(uint(id))
87
+ defer cancel()
88
+
89
+ ctx.Header("Content-Type", "text/event-stream")
90
+ ctx.Header("Cache-Control", "no-cache")
91
+ ctx.Header("Connection", "keep-alive")
92
+ ctx.Writer.Flush()
93
+
94
+ ticker := time.NewTicker(15 * time.Second)
95
+ defer ticker.Stop()
96
+
97
+ for {
98
+ select {
99
+ case <-ctx.Request.Context().Done():
100
+ return
101
+ case ev := <-ch:
102
+ payload, _ := json.Marshal(ev)
103
+ ctx.SSEvent("task", string(payload))
104
+ ctx.Writer.Flush()
105
+ case <-ticker.C:
106
+ ctx.SSEvent("heartbeat", "ok")
107
+ ctx.Writer.Flush()
108
+ }
109
+ }
110
+ }
backend/internal/middleware/auth.go ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package middleware
2
+
3
+ import (
4
+ "net/http"
5
+ "strings"
6
+ "time"
7
+
8
+ "github.com/gin-gonic/gin"
9
+ "github.com/golang-jwt/jwt/v5"
10
+ )
11
+
12
+ func IssueToken(secret string, ttl time.Duration) (string, error) {
13
+ now := time.Now()
14
+ claims := jwt.RegisteredClaims{
15
+ Subject: "admin",
16
+ IssuedAt: jwt.NewNumericDate(now),
17
+ ExpiresAt: jwt.NewNumericDate(now.Add(ttl)),
18
+ }
19
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
20
+ return token.SignedString([]byte(secret))
21
+ }
22
+
23
+ func AuthRequired(secret string) gin.HandlerFunc {
24
+ return func(ctx *gin.Context) {
25
+ header := ctx.GetHeader("Authorization")
26
+ if !strings.HasPrefix(header, "Bearer ") {
27
+ ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "missing bearer token"})
28
+ return
29
+ }
30
+
31
+ raw := strings.TrimPrefix(header, "Bearer ")
32
+ _, err := jwt.Parse(raw, func(token *jwt.Token) (interface{}, error) {
33
+ return []byte(secret), nil
34
+ }, jwt.WithValidMethods([]string{"HS256"}))
35
+ if err != nil {
36
+ ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
37
+ return
38
+ }
39
+
40
+ ctx.Next()
41
+ }
42
+ }
backend/internal/models/task.go ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package models
2
+
3
+ import "time"
4
+
5
+ type TaskType string
6
+
7
+ const (
8
+ TaskTypeDownload TaskType = "download"
9
+ TaskTypeExtract TaskType = "extract"
10
+ )
11
+
12
+ type TaskStatus string
13
+
14
+ const (
15
+ TaskStatusQueued TaskStatus = "queued"
16
+ TaskStatusRunning TaskStatus = "running"
17
+ TaskStatusSuccess TaskStatus = "success"
18
+ TaskStatusFailed TaskStatus = "failed"
19
+ )
20
+
21
+ type Task struct {
22
+ ID uint `json:"id" gorm:"primaryKey"`
23
+ Type TaskType `json:"type"`
24
+ Status TaskStatus `json:"status"`
25
+ Source string `json:"source"`
26
+ TargetPath string `json:"targetPath"`
27
+ Progress int `json:"progress"`
28
+ Logs string `json:"logs" gorm:"type:text"`
29
+ Error string `json:"error"`
30
+ CreatedAt time.Time `json:"createdAt"`
31
+ UpdatedAt time.Time `json:"updatedAt"`
32
+ }
backend/internal/services/filesystem.go ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package services
2
+
3
+ import (
4
+ "errors"
5
+ "fmt"
6
+ "io"
7
+ "os"
8
+ "path/filepath"
9
+ "sort"
10
+ "strings"
11
+ "time"
12
+ )
13
+
14
+ type FSService struct {
15
+ root string
16
+ }
17
+
18
+ type Entry struct {
19
+ Name string `json:"name"`
20
+ Path string `json:"path"`
21
+ Size int64 `json:"size"`
22
+ IsDir bool `json:"isDir"`
23
+ ModTime time.Time `json:"modTime"`
24
+ }
25
+
26
+ func NewFSService(root string) *FSService {
27
+ return &FSService{root: filepath.Clean(root)}
28
+ }
29
+
30
+ func (s *FSService) ResolvePath(raw string) (string, error) {
31
+ clean := filepath.Clean(filepath.Join(s.root, raw))
32
+ rootWithSep := s.root + string(os.PathSeparator)
33
+ if clean != s.root && !strings.HasPrefix(clean, rootWithSep) {
34
+ return "", errors.New("path out of root directory")
35
+ }
36
+ return clean, nil
37
+ }
38
+
39
+ func (s *FSService) List(raw string) ([]Entry, error) {
40
+ path, err := s.ResolvePath(raw)
41
+ if err != nil {
42
+ return nil, err
43
+ }
44
+ entries, err := os.ReadDir(path)
45
+ if err != nil {
46
+ return nil, fmt.Errorf("read dir: %w", err)
47
+ }
48
+
49
+ result := make([]Entry, 0, len(entries))
50
+ for _, e := range entries {
51
+ info, err := e.Info()
52
+ if err != nil {
53
+ continue
54
+ }
55
+ full := filepath.Join(path, e.Name())
56
+ rel, _ := filepath.Rel(s.root, full)
57
+ result = append(result, Entry{
58
+ Name: e.Name(),
59
+ Path: filepath.ToSlash(rel),
60
+ Size: info.Size(),
61
+ IsDir: e.IsDir(),
62
+ ModTime: info.ModTime(),
63
+ })
64
+ }
65
+
66
+ sort.Slice(result, func(i, j int) bool {
67
+ if result[i].IsDir != result[j].IsDir {
68
+ return result[i].IsDir
69
+ }
70
+ return strings.ToLower(result[i].Name) < strings.ToLower(result[j].Name)
71
+ })
72
+ return result, nil
73
+ }
74
+
75
+ func (s *FSService) Delete(raw string) error {
76
+ path, err := s.ResolvePath(raw)
77
+ if err != nil {
78
+ return err
79
+ }
80
+ return os.RemoveAll(path)
81
+ }
82
+
83
+ func (s *FSService) Rename(rawPath, newName string) error {
84
+ if strings.Contains(newName, "/") || strings.Contains(newName, "\\") {
85
+ return errors.New("invalid name")
86
+ }
87
+ path, err := s.ResolvePath(rawPath)
88
+ if err != nil {
89
+ return err
90
+ }
91
+ target := filepath.Join(filepath.Dir(path), newName)
92
+ target, err = s.ResolvePath(mustRel(s.root, target))
93
+ if err != nil {
94
+ return err
95
+ }
96
+ return os.Rename(path, target)
97
+ }
98
+
99
+ func (s *FSService) Move(fromRaw, toRaw string) error {
100
+ fromPath, err := s.ResolvePath(fromRaw)
101
+ if err != nil {
102
+ return err
103
+ }
104
+ toPath, err := s.ResolvePath(toRaw)
105
+ if err != nil {
106
+ return err
107
+ }
108
+ if err := os.MkdirAll(filepath.Dir(toPath), 0o755); err != nil {
109
+ return err
110
+ }
111
+ return os.Rename(fromPath, toPath)
112
+ }
113
+
114
+ func (s *FSService) SaveUploadedFile(src io.Reader, targetRaw string) error {
115
+ targetPath, err := s.ResolvePath(targetRaw)
116
+ if err != nil {
117
+ return err
118
+ }
119
+ if err := os.MkdirAll(filepath.Dir(targetPath), 0o755); err != nil {
120
+ return err
121
+ }
122
+ dst, err := os.Create(targetPath)
123
+ if err != nil {
124
+ return err
125
+ }
126
+ defer dst.Close()
127
+
128
+ _, err = io.Copy(dst, src)
129
+ return err
130
+ }
131
+
132
+ func mustRel(root, target string) string {
133
+ rel, err := filepath.Rel(root, target)
134
+ if err != nil {
135
+ return "."
136
+ }
137
+ return rel
138
+ }
backend/internal/services/tasks.go ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package services
2
+
3
+ import (
4
+ "archive/tar"
5
+ "archive/zip"
6
+ "bufio"
7
+ "compress/gzip"
8
+ "context"
9
+ "errors"
10
+ "fmt"
11
+ "io"
12
+ "net/http"
13
+ "os"
14
+ "path/filepath"
15
+ "strings"
16
+ "sync"
17
+ "time"
18
+
19
+ "fastfileviewer/backend/internal/models"
20
+ "gorm.io/gorm"
21
+ )
22
+
23
+ type taskEvent struct {
24
+ TaskID uint
25
+ Status models.TaskStatus
26
+ Progress int
27
+ LogLine string
28
+ Error string
29
+ }
30
+
31
+ type TaskService struct {
32
+ db *gorm.DB
33
+ fs *FSService
34
+ queue chan uint
35
+ workers int
36
+
37
+ mu sync.RWMutex
38
+ subscribers map[uint]map[chan taskEvent]struct{}
39
+ }
40
+
41
+ func NewTaskService(database *gorm.DB, fs *FSService, workers int) *TaskService {
42
+ if workers < 1 {
43
+ workers = 1
44
+ }
45
+ return &TaskService{
46
+ db: database,
47
+ fs: fs,
48
+ queue: make(chan uint, 256),
49
+ workers: workers,
50
+ subscribers: map[uint]map[chan taskEvent]struct{}{},
51
+ }
52
+ }
53
+
54
+ func (s *TaskService) Start(ctx context.Context) {
55
+ for i := 0; i < s.workers; i++ {
56
+ go s.worker(ctx)
57
+ }
58
+ }
59
+
60
+ func (s *TaskService) CreateDownloadTask(url, targetPath string) (*models.Task, error) {
61
+ task := &models.Task{
62
+ Type: models.TaskTypeDownload,
63
+ Status: models.TaskStatusQueued,
64
+ Source: url,
65
+ TargetPath: targetPath,
66
+ Progress: 0,
67
+ }
68
+ if err := s.db.Create(task).Error; err != nil {
69
+ return nil, err
70
+ }
71
+ s.queue <- task.ID
72
+ return task, nil
73
+ }
74
+
75
+ func (s *TaskService) CreateExtractTask(sourceArchive, targetPath string) (*models.Task, error) {
76
+ task := &models.Task{
77
+ Type: models.TaskTypeExtract,
78
+ Status: models.TaskStatusQueued,
79
+ Source: sourceArchive,
80
+ TargetPath: targetPath,
81
+ Progress: 0,
82
+ }
83
+ if err := s.db.Create(task).Error; err != nil {
84
+ return nil, err
85
+ }
86
+ s.queue <- task.ID
87
+ return task, nil
88
+ }
89
+
90
+ func (s *TaskService) ListTasks(limit int) ([]models.Task, error) {
91
+ if limit <= 0 || limit > 100 {
92
+ limit = 50
93
+ }
94
+ var tasks []models.Task
95
+ err := s.db.Order("id desc").Limit(limit).Find(&tasks).Error
96
+ return tasks, err
97
+ }
98
+
99
+ func (s *TaskService) GetTask(id uint) (*models.Task, error) {
100
+ var task models.Task
101
+ if err := s.db.First(&task, id).Error; err != nil {
102
+ return nil, err
103
+ }
104
+ return &task, nil
105
+ }
106
+
107
+ func (s *TaskService) Subscribe(taskID uint) (chan taskEvent, func()) {
108
+ ch := make(chan taskEvent, 16)
109
+ s.mu.Lock()
110
+ if s.subscribers[taskID] == nil {
111
+ s.subscribers[taskID] = map[chan taskEvent]struct{}{}
112
+ }
113
+ s.subscribers[taskID][ch] = struct{}{}
114
+ s.mu.Unlock()
115
+
116
+ cancel := func() {
117
+ s.mu.Lock()
118
+ defer s.mu.Unlock()
119
+ delete(s.subscribers[taskID], ch)
120
+ close(ch)
121
+ if len(s.subscribers[taskID]) == 0 {
122
+ delete(s.subscribers, taskID)
123
+ }
124
+ }
125
+ return ch, cancel
126
+ }
127
+
128
+ func (s *TaskService) worker(ctx context.Context) {
129
+ for {
130
+ select {
131
+ case <-ctx.Done():
132
+ return
133
+ case id := <-s.queue:
134
+ _ = s.runTask(id)
135
+ }
136
+ }
137
+ }
138
+
139
+ func (s *TaskService) runTask(id uint) error {
140
+ task, err := s.GetTask(id)
141
+ if err != nil {
142
+ return err
143
+ }
144
+
145
+ s.setStatus(task, models.TaskStatusRunning, 1, "task started", "")
146
+ switch task.Type {
147
+ case models.TaskTypeDownload:
148
+ err = s.handleDownload(task)
149
+ case models.TaskTypeExtract:
150
+ err = s.handleExtract(task)
151
+ default:
152
+ err = errors.New("unsupported task type")
153
+ }
154
+
155
+ if err != nil {
156
+ s.setStatus(task, models.TaskStatusFailed, task.Progress, "", err.Error())
157
+ return err
158
+ }
159
+ s.setStatus(task, models.TaskStatusSuccess, 100, "task completed", "")
160
+ return nil
161
+ }
162
+
163
+ func (s *TaskService) handleDownload(task *models.Task) error {
164
+ target, err := s.fs.ResolvePath(task.TargetPath)
165
+ if err != nil {
166
+ return err
167
+ }
168
+ if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
169
+ return err
170
+ }
171
+
172
+ s.appendLog(task, "starting download: "+task.Source)
173
+ resp, err := http.Get(task.Source) // #nosec G107 user-provided URLs are expected in this app design
174
+ if err != nil {
175
+ return err
176
+ }
177
+ defer resp.Body.Close()
178
+
179
+ if resp.StatusCode < 200 || resp.StatusCode >= 300 {
180
+ return fmt.Errorf("download failed: %s", resp.Status)
181
+ }
182
+
183
+ out, err := os.Create(target)
184
+ if err != nil {
185
+ return err
186
+ }
187
+ defer out.Close()
188
+
189
+ total := resp.ContentLength
190
+ var copied int64
191
+ reader := bufio.NewReader(resp.Body)
192
+ buf := make([]byte, 256*1024)
193
+ lastTick := time.Now()
194
+
195
+ for {
196
+ n, readErr := reader.Read(buf)
197
+ if n > 0 {
198
+ if _, err := out.Write(buf[:n]); err != nil {
199
+ return err
200
+ }
201
+ copied += int64(n)
202
+ if total > 0 && time.Since(lastTick) > 500*time.Millisecond {
203
+ progress := int((copied * 100) / total)
204
+ if progress > 99 {
205
+ progress = 99
206
+ }
207
+ s.setProgress(task, progress)
208
+ lastTick = time.Now()
209
+ }
210
+ }
211
+ if readErr == io.EOF {
212
+ break
213
+ }
214
+ if readErr != nil {
215
+ return readErr
216
+ }
217
+ }
218
+
219
+ s.appendLog(task, "download complete")
220
+ return nil
221
+ }
222
+
223
+ func (s *TaskService) handleExtract(task *models.Task) error {
224
+ src, err := s.fs.ResolvePath(task.Source)
225
+ if err != nil {
226
+ return err
227
+ }
228
+ target, err := s.fs.ResolvePath(task.TargetPath)
229
+ if err != nil {
230
+ return err
231
+ }
232
+ if err := os.MkdirAll(target, 0o755); err != nil {
233
+ return err
234
+ }
235
+
236
+ lower := strings.ToLower(src)
237
+ switch {
238
+ case strings.HasSuffix(lower, ".zip"):
239
+ return s.extractZip(task, src, target)
240
+ case strings.HasSuffix(lower, ".tar.gz"), strings.HasSuffix(lower, ".tgz"):
241
+ return s.extractTarGz(task, src, target)
242
+ default:
243
+ return errors.New("unsupported archive format")
244
+ }
245
+ }
246
+
247
+ func (s *TaskService) extractZip(task *models.Task, src, target string) error {
248
+ r, err := zip.OpenReader(src)
249
+ if err != nil {
250
+ return err
251
+ }
252
+ defer r.Close()
253
+
254
+ total := len(r.File)
255
+ if total == 0 {
256
+ return nil
257
+ }
258
+
259
+ for i, f := range r.File {
260
+ dest := filepath.Join(target, f.Name)
261
+ if !isSubPath(target, dest) {
262
+ return fmt.Errorf("zip slip detected: %s", f.Name)
263
+ }
264
+ if f.FileInfo().IsDir() {
265
+ if err := os.MkdirAll(dest, 0o755); err != nil {
266
+ return err
267
+ }
268
+ } else {
269
+ if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
270
+ return err
271
+ }
272
+ in, err := f.Open()
273
+ if err != nil {
274
+ return err
275
+ }
276
+ out, err := os.Create(dest)
277
+ if err != nil {
278
+ in.Close()
279
+ return err
280
+ }
281
+ _, copyErr := io.Copy(out, in)
282
+ in.Close()
283
+ out.Close()
284
+ if copyErr != nil {
285
+ return copyErr
286
+ }
287
+ }
288
+ progress := int((int64(i+1) * 100) / int64(total))
289
+ if progress > 99 {
290
+ progress = 99
291
+ }
292
+ s.setProgress(task, progress)
293
+ }
294
+ s.appendLog(task, "zip extract complete")
295
+ return nil
296
+ }
297
+
298
+ func (s *TaskService) extractTarGz(task *models.Task, src, target string) error {
299
+ f, err := os.Open(src)
300
+ if err != nil {
301
+ return err
302
+ }
303
+ defer f.Close()
304
+
305
+ gzr, err := gzip.NewReader(f)
306
+ if err != nil {
307
+ return err
308
+ }
309
+ defer gzr.Close()
310
+
311
+ tr := tar.NewReader(gzr)
312
+ for {
313
+ hdr, err := tr.Next()
314
+ if err == io.EOF {
315
+ break
316
+ }
317
+ if err != nil {
318
+ return err
319
+ }
320
+ dest := filepath.Join(target, hdr.Name)
321
+ if !isSubPath(target, dest) {
322
+ return fmt.Errorf("tar path escape detected: %s", hdr.Name)
323
+ }
324
+
325
+ switch hdr.Typeflag {
326
+ case tar.TypeDir:
327
+ if err := os.MkdirAll(dest, 0o755); err != nil {
328
+ return err
329
+ }
330
+ case tar.TypeReg:
331
+ if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
332
+ return err
333
+ }
334
+ out, err := os.Create(dest)
335
+ if err != nil {
336
+ return err
337
+ }
338
+ if _, err := io.Copy(out, tr); err != nil {
339
+ out.Close()
340
+ return err
341
+ }
342
+ out.Close()
343
+ }
344
+ }
345
+ s.setProgress(task, 99)
346
+ s.appendLog(task, "tar.gz extract complete")
347
+ return nil
348
+ }
349
+
350
+ func isSubPath(root, maybeChild string) bool {
351
+ root = filepath.Clean(root)
352
+ maybeChild = filepath.Clean(maybeChild)
353
+ if root == maybeChild {
354
+ return true
355
+ }
356
+ return strings.HasPrefix(maybeChild, root+string(os.PathSeparator))
357
+ }
358
+
359
+ func (s *TaskService) setProgress(task *models.Task, progress int) {
360
+ task.Progress = progress
361
+ s.db.Model(task).Updates(map[string]interface{}{
362
+ "progress": progress,
363
+ })
364
+ s.publish(task.ID, taskEvent{
365
+ TaskID: task.ID,
366
+ Status: task.Status,
367
+ Progress: progress,
368
+ })
369
+ }
370
+
371
+ func (s *TaskService) appendLog(task *models.Task, line string) {
372
+ task.Logs = strings.TrimSpace(task.Logs + "\n" + line)
373
+ s.db.Model(task).Update("logs", task.Logs)
374
+ s.publish(task.ID, taskEvent{
375
+ TaskID: task.ID,
376
+ Status: task.Status,
377
+ Progress: task.Progress,
378
+ LogLine: line,
379
+ })
380
+ }
381
+
382
+ func (s *TaskService) setStatus(task *models.Task, status models.TaskStatus, progress int, logLine, errorMsg string) {
383
+ task.Status = status
384
+ task.Progress = progress
385
+ task.Error = errorMsg
386
+ updates := map[string]interface{}{
387
+ "status": status,
388
+ "progress": progress,
389
+ "error": errorMsg,
390
+ }
391
+ if logLine != "" {
392
+ task.Logs = strings.TrimSpace(task.Logs + "\n" + logLine)
393
+ updates["logs"] = task.Logs
394
+ }
395
+ s.db.Model(task).Updates(updates)
396
+ s.publish(task.ID, taskEvent{
397
+ TaskID: task.ID,
398
+ Status: status,
399
+ Progress: progress,
400
+ LogLine: logLine,
401
+ Error: errorMsg,
402
+ })
403
+ }
404
+
405
+ func (s *TaskService) publish(taskID uint, event taskEvent) {
406
+ s.mu.RLock()
407
+ defer s.mu.RUnlock()
408
+ for ch := range s.subscribers[taskID] {
409
+ select {
410
+ case ch <- event:
411
+ default:
412
+ }
413
+ }
414
+ }
frontend/index.html ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>FastFileViewer</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.jsx"></script>
11
+ </body>
12
+ </html>
frontend/package-lock.json ADDED
@@ -0,0 +1,2807 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "fastfileviewer-frontend",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "fastfileviewer-frontend",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "antd": "^5.28.0",
12
+ "react": "^19.1.1",
13
+ "react-dom": "^19.1.1"
14
+ },
15
+ "devDependencies": {
16
+ "@vitejs/plugin-react": "^5.0.2",
17
+ "vite": "^7.1.5"
18
+ }
19
+ },
20
+ "node_modules/@ant-design/colors": {
21
+ "version": "7.2.1",
22
+ "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.2.1.tgz",
23
+ "integrity": "sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "@ant-design/fast-color": "^2.0.6"
27
+ }
28
+ },
29
+ "node_modules/@ant-design/cssinjs": {
30
+ "version": "1.24.0",
31
+ "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.24.0.tgz",
32
+ "integrity": "sha512-K4cYrJBsgvL+IoozUXYjbT6LHHNt+19a9zkvpBPxLjFHas1UpPM2A5MlhROb0BT8N8WoavM5VsP9MeSeNK/3mg==",
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "@babel/runtime": "^7.11.1",
36
+ "@emotion/hash": "^0.8.0",
37
+ "@emotion/unitless": "^0.7.5",
38
+ "classnames": "^2.3.1",
39
+ "csstype": "^3.1.3",
40
+ "rc-util": "^5.35.0",
41
+ "stylis": "^4.3.4"
42
+ },
43
+ "peerDependencies": {
44
+ "react": ">=16.0.0",
45
+ "react-dom": ">=16.0.0"
46
+ }
47
+ },
48
+ "node_modules/@ant-design/cssinjs-utils": {
49
+ "version": "1.1.3",
50
+ "resolved": "https://registry.npmjs.org/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.3.tgz",
51
+ "integrity": "sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==",
52
+ "license": "MIT",
53
+ "dependencies": {
54
+ "@ant-design/cssinjs": "^1.21.0",
55
+ "@babel/runtime": "^7.23.2",
56
+ "rc-util": "^5.38.0"
57
+ },
58
+ "peerDependencies": {
59
+ "react": ">=16.9.0",
60
+ "react-dom": ">=16.9.0"
61
+ }
62
+ },
63
+ "node_modules/@ant-design/fast-color": {
64
+ "version": "2.0.6",
65
+ "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-2.0.6.tgz",
66
+ "integrity": "sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==",
67
+ "license": "MIT",
68
+ "dependencies": {
69
+ "@babel/runtime": "^7.24.7"
70
+ },
71
+ "engines": {
72
+ "node": ">=8.x"
73
+ }
74
+ },
75
+ "node_modules/@ant-design/icons": {
76
+ "version": "5.6.1",
77
+ "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.6.1.tgz",
78
+ "integrity": "sha512-0/xS39c91WjPAZOWsvi1//zjx6kAp4kxWwctR6kuU6p133w8RU0D2dSCvZC19uQyharg/sAvYxGYWl01BbZZfg==",
79
+ "license": "MIT",
80
+ "dependencies": {
81
+ "@ant-design/colors": "^7.0.0",
82
+ "@ant-design/icons-svg": "^4.4.0",
83
+ "@babel/runtime": "^7.24.8",
84
+ "classnames": "^2.2.6",
85
+ "rc-util": "^5.31.1"
86
+ },
87
+ "engines": {
88
+ "node": ">=8"
89
+ },
90
+ "peerDependencies": {
91
+ "react": ">=16.0.0",
92
+ "react-dom": ">=16.0.0"
93
+ }
94
+ },
95
+ "node_modules/@ant-design/icons-svg": {
96
+ "version": "4.4.2",
97
+ "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz",
98
+ "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==",
99
+ "license": "MIT"
100
+ },
101
+ "node_modules/@ant-design/react-slick": {
102
+ "version": "1.1.2",
103
+ "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.1.2.tgz",
104
+ "integrity": "sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==",
105
+ "license": "MIT",
106
+ "dependencies": {
107
+ "@babel/runtime": "^7.10.4",
108
+ "classnames": "^2.2.5",
109
+ "json2mq": "^0.2.0",
110
+ "resize-observer-polyfill": "^1.5.1",
111
+ "throttle-debounce": "^5.0.0"
112
+ },
113
+ "peerDependencies": {
114
+ "react": ">=16.9.0"
115
+ }
116
+ },
117
+ "node_modules/@babel/code-frame": {
118
+ "version": "7.29.0",
119
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
120
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
121
+ "dev": true,
122
+ "license": "MIT",
123
+ "dependencies": {
124
+ "@babel/helper-validator-identifier": "^7.28.5",
125
+ "js-tokens": "^4.0.0",
126
+ "picocolors": "^1.1.1"
127
+ },
128
+ "engines": {
129
+ "node": ">=6.9.0"
130
+ }
131
+ },
132
+ "node_modules/@babel/compat-data": {
133
+ "version": "7.29.0",
134
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
135
+ "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
136
+ "dev": true,
137
+ "license": "MIT",
138
+ "engines": {
139
+ "node": ">=6.9.0"
140
+ }
141
+ },
142
+ "node_modules/@babel/core": {
143
+ "version": "7.29.0",
144
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
145
+ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
146
+ "dev": true,
147
+ "license": "MIT",
148
+ "peer": true,
149
+ "dependencies": {
150
+ "@babel/code-frame": "^7.29.0",
151
+ "@babel/generator": "^7.29.0",
152
+ "@babel/helper-compilation-targets": "^7.28.6",
153
+ "@babel/helper-module-transforms": "^7.28.6",
154
+ "@babel/helpers": "^7.28.6",
155
+ "@babel/parser": "^7.29.0",
156
+ "@babel/template": "^7.28.6",
157
+ "@babel/traverse": "^7.29.0",
158
+ "@babel/types": "^7.29.0",
159
+ "@jridgewell/remapping": "^2.3.5",
160
+ "convert-source-map": "^2.0.0",
161
+ "debug": "^4.1.0",
162
+ "gensync": "^1.0.0-beta.2",
163
+ "json5": "^2.2.3",
164
+ "semver": "^6.3.1"
165
+ },
166
+ "engines": {
167
+ "node": ">=6.9.0"
168
+ },
169
+ "funding": {
170
+ "type": "opencollective",
171
+ "url": "https://opencollective.com/babel"
172
+ }
173
+ },
174
+ "node_modules/@babel/generator": {
175
+ "version": "7.29.1",
176
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
177
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
178
+ "dev": true,
179
+ "license": "MIT",
180
+ "dependencies": {
181
+ "@babel/parser": "^7.29.0",
182
+ "@babel/types": "^7.29.0",
183
+ "@jridgewell/gen-mapping": "^0.3.12",
184
+ "@jridgewell/trace-mapping": "^0.3.28",
185
+ "jsesc": "^3.0.2"
186
+ },
187
+ "engines": {
188
+ "node": ">=6.9.0"
189
+ }
190
+ },
191
+ "node_modules/@babel/helper-compilation-targets": {
192
+ "version": "7.28.6",
193
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
194
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
195
+ "dev": true,
196
+ "license": "MIT",
197
+ "dependencies": {
198
+ "@babel/compat-data": "^7.28.6",
199
+ "@babel/helper-validator-option": "^7.27.1",
200
+ "browserslist": "^4.24.0",
201
+ "lru-cache": "^5.1.1",
202
+ "semver": "^6.3.1"
203
+ },
204
+ "engines": {
205
+ "node": ">=6.9.0"
206
+ }
207
+ },
208
+ "node_modules/@babel/helper-globals": {
209
+ "version": "7.28.0",
210
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
211
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
212
+ "dev": true,
213
+ "license": "MIT",
214
+ "engines": {
215
+ "node": ">=6.9.0"
216
+ }
217
+ },
218
+ "node_modules/@babel/helper-module-imports": {
219
+ "version": "7.28.6",
220
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
221
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
222
+ "dev": true,
223
+ "license": "MIT",
224
+ "dependencies": {
225
+ "@babel/traverse": "^7.28.6",
226
+ "@babel/types": "^7.28.6"
227
+ },
228
+ "engines": {
229
+ "node": ">=6.9.0"
230
+ }
231
+ },
232
+ "node_modules/@babel/helper-module-transforms": {
233
+ "version": "7.28.6",
234
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
235
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
236
+ "dev": true,
237
+ "license": "MIT",
238
+ "dependencies": {
239
+ "@babel/helper-module-imports": "^7.28.6",
240
+ "@babel/helper-validator-identifier": "^7.28.5",
241
+ "@babel/traverse": "^7.28.6"
242
+ },
243
+ "engines": {
244
+ "node": ">=6.9.0"
245
+ },
246
+ "peerDependencies": {
247
+ "@babel/core": "^7.0.0"
248
+ }
249
+ },
250
+ "node_modules/@babel/helper-plugin-utils": {
251
+ "version": "7.28.6",
252
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
253
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
254
+ "dev": true,
255
+ "license": "MIT",
256
+ "engines": {
257
+ "node": ">=6.9.0"
258
+ }
259
+ },
260
+ "node_modules/@babel/helper-string-parser": {
261
+ "version": "7.27.1",
262
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
263
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
264
+ "dev": true,
265
+ "license": "MIT",
266
+ "engines": {
267
+ "node": ">=6.9.0"
268
+ }
269
+ },
270
+ "node_modules/@babel/helper-validator-identifier": {
271
+ "version": "7.28.5",
272
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
273
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
274
+ "dev": true,
275
+ "license": "MIT",
276
+ "engines": {
277
+ "node": ">=6.9.0"
278
+ }
279
+ },
280
+ "node_modules/@babel/helper-validator-option": {
281
+ "version": "7.27.1",
282
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
283
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
284
+ "dev": true,
285
+ "license": "MIT",
286
+ "engines": {
287
+ "node": ">=6.9.0"
288
+ }
289
+ },
290
+ "node_modules/@babel/helpers": {
291
+ "version": "7.28.6",
292
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
293
+ "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
294
+ "dev": true,
295
+ "license": "MIT",
296
+ "dependencies": {
297
+ "@babel/template": "^7.28.6",
298
+ "@babel/types": "^7.28.6"
299
+ },
300
+ "engines": {
301
+ "node": ">=6.9.0"
302
+ }
303
+ },
304
+ "node_modules/@babel/parser": {
305
+ "version": "7.29.0",
306
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
307
+ "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
308
+ "dev": true,
309
+ "license": "MIT",
310
+ "dependencies": {
311
+ "@babel/types": "^7.29.0"
312
+ },
313
+ "bin": {
314
+ "parser": "bin/babel-parser.js"
315
+ },
316
+ "engines": {
317
+ "node": ">=6.0.0"
318
+ }
319
+ },
320
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
321
+ "version": "7.27.1",
322
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
323
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
324
+ "dev": true,
325
+ "license": "MIT",
326
+ "dependencies": {
327
+ "@babel/helper-plugin-utils": "^7.27.1"
328
+ },
329
+ "engines": {
330
+ "node": ">=6.9.0"
331
+ },
332
+ "peerDependencies": {
333
+ "@babel/core": "^7.0.0-0"
334
+ }
335
+ },
336
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
337
+ "version": "7.27.1",
338
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
339
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
340
+ "dev": true,
341
+ "license": "MIT",
342
+ "dependencies": {
343
+ "@babel/helper-plugin-utils": "^7.27.1"
344
+ },
345
+ "engines": {
346
+ "node": ">=6.9.0"
347
+ },
348
+ "peerDependencies": {
349
+ "@babel/core": "^7.0.0-0"
350
+ }
351
+ },
352
+ "node_modules/@babel/runtime": {
353
+ "version": "7.28.6",
354
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
355
+ "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
356
+ "license": "MIT",
357
+ "engines": {
358
+ "node": ">=6.9.0"
359
+ }
360
+ },
361
+ "node_modules/@babel/template": {
362
+ "version": "7.28.6",
363
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
364
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
365
+ "dev": true,
366
+ "license": "MIT",
367
+ "dependencies": {
368
+ "@babel/code-frame": "^7.28.6",
369
+ "@babel/parser": "^7.28.6",
370
+ "@babel/types": "^7.28.6"
371
+ },
372
+ "engines": {
373
+ "node": ">=6.9.0"
374
+ }
375
+ },
376
+ "node_modules/@babel/traverse": {
377
+ "version": "7.29.0",
378
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
379
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
380
+ "dev": true,
381
+ "license": "MIT",
382
+ "dependencies": {
383
+ "@babel/code-frame": "^7.29.0",
384
+ "@babel/generator": "^7.29.0",
385
+ "@babel/helper-globals": "^7.28.0",
386
+ "@babel/parser": "^7.29.0",
387
+ "@babel/template": "^7.28.6",
388
+ "@babel/types": "^7.29.0",
389
+ "debug": "^4.3.1"
390
+ },
391
+ "engines": {
392
+ "node": ">=6.9.0"
393
+ }
394
+ },
395
+ "node_modules/@babel/types": {
396
+ "version": "7.29.0",
397
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
398
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
399
+ "dev": true,
400
+ "license": "MIT",
401
+ "dependencies": {
402
+ "@babel/helper-string-parser": "^7.27.1",
403
+ "@babel/helper-validator-identifier": "^7.28.5"
404
+ },
405
+ "engines": {
406
+ "node": ">=6.9.0"
407
+ }
408
+ },
409
+ "node_modules/@emotion/hash": {
410
+ "version": "0.8.0",
411
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
412
+ "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
413
+ "license": "MIT"
414
+ },
415
+ "node_modules/@emotion/unitless": {
416
+ "version": "0.7.5",
417
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
418
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
419
+ "license": "MIT"
420
+ },
421
+ "node_modules/@esbuild/aix-ppc64": {
422
+ "version": "0.27.3",
423
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
424
+ "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
425
+ "cpu": [
426
+ "ppc64"
427
+ ],
428
+ "dev": true,
429
+ "license": "MIT",
430
+ "optional": true,
431
+ "os": [
432
+ "aix"
433
+ ],
434
+ "engines": {
435
+ "node": ">=18"
436
+ }
437
+ },
438
+ "node_modules/@esbuild/android-arm": {
439
+ "version": "0.27.3",
440
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
441
+ "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
442
+ "cpu": [
443
+ "arm"
444
+ ],
445
+ "dev": true,
446
+ "license": "MIT",
447
+ "optional": true,
448
+ "os": [
449
+ "android"
450
+ ],
451
+ "engines": {
452
+ "node": ">=18"
453
+ }
454
+ },
455
+ "node_modules/@esbuild/android-arm64": {
456
+ "version": "0.27.3",
457
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
458
+ "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
459
+ "cpu": [
460
+ "arm64"
461
+ ],
462
+ "dev": true,
463
+ "license": "MIT",
464
+ "optional": true,
465
+ "os": [
466
+ "android"
467
+ ],
468
+ "engines": {
469
+ "node": ">=18"
470
+ }
471
+ },
472
+ "node_modules/@esbuild/android-x64": {
473
+ "version": "0.27.3",
474
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
475
+ "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
476
+ "cpu": [
477
+ "x64"
478
+ ],
479
+ "dev": true,
480
+ "license": "MIT",
481
+ "optional": true,
482
+ "os": [
483
+ "android"
484
+ ],
485
+ "engines": {
486
+ "node": ">=18"
487
+ }
488
+ },
489
+ "node_modules/@esbuild/darwin-arm64": {
490
+ "version": "0.27.3",
491
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
492
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
493
+ "cpu": [
494
+ "arm64"
495
+ ],
496
+ "dev": true,
497
+ "license": "MIT",
498
+ "optional": true,
499
+ "os": [
500
+ "darwin"
501
+ ],
502
+ "engines": {
503
+ "node": ">=18"
504
+ }
505
+ },
506
+ "node_modules/@esbuild/darwin-x64": {
507
+ "version": "0.27.3",
508
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
509
+ "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
510
+ "cpu": [
511
+ "x64"
512
+ ],
513
+ "dev": true,
514
+ "license": "MIT",
515
+ "optional": true,
516
+ "os": [
517
+ "darwin"
518
+ ],
519
+ "engines": {
520
+ "node": ">=18"
521
+ }
522
+ },
523
+ "node_modules/@esbuild/freebsd-arm64": {
524
+ "version": "0.27.3",
525
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
526
+ "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
527
+ "cpu": [
528
+ "arm64"
529
+ ],
530
+ "dev": true,
531
+ "license": "MIT",
532
+ "optional": true,
533
+ "os": [
534
+ "freebsd"
535
+ ],
536
+ "engines": {
537
+ "node": ">=18"
538
+ }
539
+ },
540
+ "node_modules/@esbuild/freebsd-x64": {
541
+ "version": "0.27.3",
542
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
543
+ "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
544
+ "cpu": [
545
+ "x64"
546
+ ],
547
+ "dev": true,
548
+ "license": "MIT",
549
+ "optional": true,
550
+ "os": [
551
+ "freebsd"
552
+ ],
553
+ "engines": {
554
+ "node": ">=18"
555
+ }
556
+ },
557
+ "node_modules/@esbuild/linux-arm": {
558
+ "version": "0.27.3",
559
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
560
+ "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
561
+ "cpu": [
562
+ "arm"
563
+ ],
564
+ "dev": true,
565
+ "license": "MIT",
566
+ "optional": true,
567
+ "os": [
568
+ "linux"
569
+ ],
570
+ "engines": {
571
+ "node": ">=18"
572
+ }
573
+ },
574
+ "node_modules/@esbuild/linux-arm64": {
575
+ "version": "0.27.3",
576
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
577
+ "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
578
+ "cpu": [
579
+ "arm64"
580
+ ],
581
+ "dev": true,
582
+ "license": "MIT",
583
+ "optional": true,
584
+ "os": [
585
+ "linux"
586
+ ],
587
+ "engines": {
588
+ "node": ">=18"
589
+ }
590
+ },
591
+ "node_modules/@esbuild/linux-ia32": {
592
+ "version": "0.27.3",
593
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
594
+ "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
595
+ "cpu": [
596
+ "ia32"
597
+ ],
598
+ "dev": true,
599
+ "license": "MIT",
600
+ "optional": true,
601
+ "os": [
602
+ "linux"
603
+ ],
604
+ "engines": {
605
+ "node": ">=18"
606
+ }
607
+ },
608
+ "node_modules/@esbuild/linux-loong64": {
609
+ "version": "0.27.3",
610
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
611
+ "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
612
+ "cpu": [
613
+ "loong64"
614
+ ],
615
+ "dev": true,
616
+ "license": "MIT",
617
+ "optional": true,
618
+ "os": [
619
+ "linux"
620
+ ],
621
+ "engines": {
622
+ "node": ">=18"
623
+ }
624
+ },
625
+ "node_modules/@esbuild/linux-mips64el": {
626
+ "version": "0.27.3",
627
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
628
+ "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
629
+ "cpu": [
630
+ "mips64el"
631
+ ],
632
+ "dev": true,
633
+ "license": "MIT",
634
+ "optional": true,
635
+ "os": [
636
+ "linux"
637
+ ],
638
+ "engines": {
639
+ "node": ">=18"
640
+ }
641
+ },
642
+ "node_modules/@esbuild/linux-ppc64": {
643
+ "version": "0.27.3",
644
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
645
+ "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
646
+ "cpu": [
647
+ "ppc64"
648
+ ],
649
+ "dev": true,
650
+ "license": "MIT",
651
+ "optional": true,
652
+ "os": [
653
+ "linux"
654
+ ],
655
+ "engines": {
656
+ "node": ">=18"
657
+ }
658
+ },
659
+ "node_modules/@esbuild/linux-riscv64": {
660
+ "version": "0.27.3",
661
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
662
+ "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
663
+ "cpu": [
664
+ "riscv64"
665
+ ],
666
+ "dev": true,
667
+ "license": "MIT",
668
+ "optional": true,
669
+ "os": [
670
+ "linux"
671
+ ],
672
+ "engines": {
673
+ "node": ">=18"
674
+ }
675
+ },
676
+ "node_modules/@esbuild/linux-s390x": {
677
+ "version": "0.27.3",
678
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
679
+ "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
680
+ "cpu": [
681
+ "s390x"
682
+ ],
683
+ "dev": true,
684
+ "license": "MIT",
685
+ "optional": true,
686
+ "os": [
687
+ "linux"
688
+ ],
689
+ "engines": {
690
+ "node": ">=18"
691
+ }
692
+ },
693
+ "node_modules/@esbuild/linux-x64": {
694
+ "version": "0.27.3",
695
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
696
+ "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
697
+ "cpu": [
698
+ "x64"
699
+ ],
700
+ "dev": true,
701
+ "license": "MIT",
702
+ "optional": true,
703
+ "os": [
704
+ "linux"
705
+ ],
706
+ "engines": {
707
+ "node": ">=18"
708
+ }
709
+ },
710
+ "node_modules/@esbuild/netbsd-arm64": {
711
+ "version": "0.27.3",
712
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
713
+ "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
714
+ "cpu": [
715
+ "arm64"
716
+ ],
717
+ "dev": true,
718
+ "license": "MIT",
719
+ "optional": true,
720
+ "os": [
721
+ "netbsd"
722
+ ],
723
+ "engines": {
724
+ "node": ">=18"
725
+ }
726
+ },
727
+ "node_modules/@esbuild/netbsd-x64": {
728
+ "version": "0.27.3",
729
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
730
+ "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
731
+ "cpu": [
732
+ "x64"
733
+ ],
734
+ "dev": true,
735
+ "license": "MIT",
736
+ "optional": true,
737
+ "os": [
738
+ "netbsd"
739
+ ],
740
+ "engines": {
741
+ "node": ">=18"
742
+ }
743
+ },
744
+ "node_modules/@esbuild/openbsd-arm64": {
745
+ "version": "0.27.3",
746
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
747
+ "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
748
+ "cpu": [
749
+ "arm64"
750
+ ],
751
+ "dev": true,
752
+ "license": "MIT",
753
+ "optional": true,
754
+ "os": [
755
+ "openbsd"
756
+ ],
757
+ "engines": {
758
+ "node": ">=18"
759
+ }
760
+ },
761
+ "node_modules/@esbuild/openbsd-x64": {
762
+ "version": "0.27.3",
763
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
764
+ "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
765
+ "cpu": [
766
+ "x64"
767
+ ],
768
+ "dev": true,
769
+ "license": "MIT",
770
+ "optional": true,
771
+ "os": [
772
+ "openbsd"
773
+ ],
774
+ "engines": {
775
+ "node": ">=18"
776
+ }
777
+ },
778
+ "node_modules/@esbuild/openharmony-arm64": {
779
+ "version": "0.27.3",
780
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
781
+ "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
782
+ "cpu": [
783
+ "arm64"
784
+ ],
785
+ "dev": true,
786
+ "license": "MIT",
787
+ "optional": true,
788
+ "os": [
789
+ "openharmony"
790
+ ],
791
+ "engines": {
792
+ "node": ">=18"
793
+ }
794
+ },
795
+ "node_modules/@esbuild/sunos-x64": {
796
+ "version": "0.27.3",
797
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
798
+ "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
799
+ "cpu": [
800
+ "x64"
801
+ ],
802
+ "dev": true,
803
+ "license": "MIT",
804
+ "optional": true,
805
+ "os": [
806
+ "sunos"
807
+ ],
808
+ "engines": {
809
+ "node": ">=18"
810
+ }
811
+ },
812
+ "node_modules/@esbuild/win32-arm64": {
813
+ "version": "0.27.3",
814
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
815
+ "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
816
+ "cpu": [
817
+ "arm64"
818
+ ],
819
+ "dev": true,
820
+ "license": "MIT",
821
+ "optional": true,
822
+ "os": [
823
+ "win32"
824
+ ],
825
+ "engines": {
826
+ "node": ">=18"
827
+ }
828
+ },
829
+ "node_modules/@esbuild/win32-ia32": {
830
+ "version": "0.27.3",
831
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
832
+ "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
833
+ "cpu": [
834
+ "ia32"
835
+ ],
836
+ "dev": true,
837
+ "license": "MIT",
838
+ "optional": true,
839
+ "os": [
840
+ "win32"
841
+ ],
842
+ "engines": {
843
+ "node": ">=18"
844
+ }
845
+ },
846
+ "node_modules/@esbuild/win32-x64": {
847
+ "version": "0.27.3",
848
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
849
+ "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
850
+ "cpu": [
851
+ "x64"
852
+ ],
853
+ "dev": true,
854
+ "license": "MIT",
855
+ "optional": true,
856
+ "os": [
857
+ "win32"
858
+ ],
859
+ "engines": {
860
+ "node": ">=18"
861
+ }
862
+ },
863
+ "node_modules/@jridgewell/gen-mapping": {
864
+ "version": "0.3.13",
865
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
866
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
867
+ "dev": true,
868
+ "license": "MIT",
869
+ "dependencies": {
870
+ "@jridgewell/sourcemap-codec": "^1.5.0",
871
+ "@jridgewell/trace-mapping": "^0.3.24"
872
+ }
873
+ },
874
+ "node_modules/@jridgewell/remapping": {
875
+ "version": "2.3.5",
876
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
877
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
878
+ "dev": true,
879
+ "license": "MIT",
880
+ "dependencies": {
881
+ "@jridgewell/gen-mapping": "^0.3.5",
882
+ "@jridgewell/trace-mapping": "^0.3.24"
883
+ }
884
+ },
885
+ "node_modules/@jridgewell/resolve-uri": {
886
+ "version": "3.1.2",
887
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
888
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
889
+ "dev": true,
890
+ "license": "MIT",
891
+ "engines": {
892
+ "node": ">=6.0.0"
893
+ }
894
+ },
895
+ "node_modules/@jridgewell/sourcemap-codec": {
896
+ "version": "1.5.5",
897
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
898
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
899
+ "dev": true,
900
+ "license": "MIT"
901
+ },
902
+ "node_modules/@jridgewell/trace-mapping": {
903
+ "version": "0.3.31",
904
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
905
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
906
+ "dev": true,
907
+ "license": "MIT",
908
+ "dependencies": {
909
+ "@jridgewell/resolve-uri": "^3.1.0",
910
+ "@jridgewell/sourcemap-codec": "^1.4.14"
911
+ }
912
+ },
913
+ "node_modules/@rc-component/async-validator": {
914
+ "version": "5.1.0",
915
+ "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.1.0.tgz",
916
+ "integrity": "sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA==",
917
+ "license": "MIT",
918
+ "dependencies": {
919
+ "@babel/runtime": "^7.24.4"
920
+ },
921
+ "engines": {
922
+ "node": ">=14.x"
923
+ }
924
+ },
925
+ "node_modules/@rc-component/color-picker": {
926
+ "version": "2.0.1",
927
+ "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-2.0.1.tgz",
928
+ "integrity": "sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==",
929
+ "license": "MIT",
930
+ "dependencies": {
931
+ "@ant-design/fast-color": "^2.0.6",
932
+ "@babel/runtime": "^7.23.6",
933
+ "classnames": "^2.2.6",
934
+ "rc-util": "^5.38.1"
935
+ },
936
+ "peerDependencies": {
937
+ "react": ">=16.9.0",
938
+ "react-dom": ">=16.9.0"
939
+ }
940
+ },
941
+ "node_modules/@rc-component/context": {
942
+ "version": "1.4.0",
943
+ "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz",
944
+ "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==",
945
+ "license": "MIT",
946
+ "dependencies": {
947
+ "@babel/runtime": "^7.10.1",
948
+ "rc-util": "^5.27.0"
949
+ },
950
+ "peerDependencies": {
951
+ "react": ">=16.9.0",
952
+ "react-dom": ">=16.9.0"
953
+ }
954
+ },
955
+ "node_modules/@rc-component/mini-decimal": {
956
+ "version": "1.1.0",
957
+ "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz",
958
+ "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==",
959
+ "license": "MIT",
960
+ "dependencies": {
961
+ "@babel/runtime": "^7.18.0"
962
+ },
963
+ "engines": {
964
+ "node": ">=8.x"
965
+ }
966
+ },
967
+ "node_modules/@rc-component/mutate-observer": {
968
+ "version": "1.1.0",
969
+ "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz",
970
+ "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==",
971
+ "license": "MIT",
972
+ "dependencies": {
973
+ "@babel/runtime": "^7.18.0",
974
+ "classnames": "^2.3.2",
975
+ "rc-util": "^5.24.4"
976
+ },
977
+ "engines": {
978
+ "node": ">=8.x"
979
+ },
980
+ "peerDependencies": {
981
+ "react": ">=16.9.0",
982
+ "react-dom": ">=16.9.0"
983
+ }
984
+ },
985
+ "node_modules/@rc-component/portal": {
986
+ "version": "1.1.2",
987
+ "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz",
988
+ "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==",
989
+ "license": "MIT",
990
+ "dependencies": {
991
+ "@babel/runtime": "^7.18.0",
992
+ "classnames": "^2.3.2",
993
+ "rc-util": "^5.24.4"
994
+ },
995
+ "engines": {
996
+ "node": ">=8.x"
997
+ },
998
+ "peerDependencies": {
999
+ "react": ">=16.9.0",
1000
+ "react-dom": ">=16.9.0"
1001
+ }
1002
+ },
1003
+ "node_modules/@rc-component/qrcode": {
1004
+ "version": "1.1.1",
1005
+ "resolved": "https://registry.npmjs.org/@rc-component/qrcode/-/qrcode-1.1.1.tgz",
1006
+ "integrity": "sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==",
1007
+ "license": "MIT",
1008
+ "dependencies": {
1009
+ "@babel/runtime": "^7.24.7"
1010
+ },
1011
+ "engines": {
1012
+ "node": ">=8.x"
1013
+ },
1014
+ "peerDependencies": {
1015
+ "react": ">=16.9.0",
1016
+ "react-dom": ">=16.9.0"
1017
+ }
1018
+ },
1019
+ "node_modules/@rc-component/tour": {
1020
+ "version": "1.15.1",
1021
+ "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.1.tgz",
1022
+ "integrity": "sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==",
1023
+ "license": "MIT",
1024
+ "dependencies": {
1025
+ "@babel/runtime": "^7.18.0",
1026
+ "@rc-component/portal": "^1.0.0-9",
1027
+ "@rc-component/trigger": "^2.0.0",
1028
+ "classnames": "^2.3.2",
1029
+ "rc-util": "^5.24.4"
1030
+ },
1031
+ "engines": {
1032
+ "node": ">=8.x"
1033
+ },
1034
+ "peerDependencies": {
1035
+ "react": ">=16.9.0",
1036
+ "react-dom": ">=16.9.0"
1037
+ }
1038
+ },
1039
+ "node_modules/@rc-component/trigger": {
1040
+ "version": "2.3.1",
1041
+ "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.3.1.tgz",
1042
+ "integrity": "sha512-ORENF39PeXTzM+gQEshuk460Z8N4+6DkjpxlpE7Q3gYy1iBpLrx0FOJz3h62ryrJZ/3zCAUIkT1Pb/8hHWpb3A==",
1043
+ "license": "MIT",
1044
+ "dependencies": {
1045
+ "@babel/runtime": "^7.23.2",
1046
+ "@rc-component/portal": "^1.1.0",
1047
+ "classnames": "^2.3.2",
1048
+ "rc-motion": "^2.0.0",
1049
+ "rc-resize-observer": "^1.3.1",
1050
+ "rc-util": "^5.44.0"
1051
+ },
1052
+ "engines": {
1053
+ "node": ">=8.x"
1054
+ },
1055
+ "peerDependencies": {
1056
+ "react": ">=16.9.0",
1057
+ "react-dom": ">=16.9.0"
1058
+ }
1059
+ },
1060
+ "node_modules/@rolldown/pluginutils": {
1061
+ "version": "1.0.0-rc.3",
1062
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
1063
+ "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==",
1064
+ "dev": true,
1065
+ "license": "MIT"
1066
+ },
1067
+ "node_modules/@rollup/rollup-android-arm-eabi": {
1068
+ "version": "4.57.1",
1069
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
1070
+ "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==",
1071
+ "cpu": [
1072
+ "arm"
1073
+ ],
1074
+ "dev": true,
1075
+ "license": "MIT",
1076
+ "optional": true,
1077
+ "os": [
1078
+ "android"
1079
+ ]
1080
+ },
1081
+ "node_modules/@rollup/rollup-android-arm64": {
1082
+ "version": "4.57.1",
1083
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz",
1084
+ "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==",
1085
+ "cpu": [
1086
+ "arm64"
1087
+ ],
1088
+ "dev": true,
1089
+ "license": "MIT",
1090
+ "optional": true,
1091
+ "os": [
1092
+ "android"
1093
+ ]
1094
+ },
1095
+ "node_modules/@rollup/rollup-darwin-arm64": {
1096
+ "version": "4.57.1",
1097
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz",
1098
+ "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==",
1099
+ "cpu": [
1100
+ "arm64"
1101
+ ],
1102
+ "dev": true,
1103
+ "license": "MIT",
1104
+ "optional": true,
1105
+ "os": [
1106
+ "darwin"
1107
+ ]
1108
+ },
1109
+ "node_modules/@rollup/rollup-darwin-x64": {
1110
+ "version": "4.57.1",
1111
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz",
1112
+ "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==",
1113
+ "cpu": [
1114
+ "x64"
1115
+ ],
1116
+ "dev": true,
1117
+ "license": "MIT",
1118
+ "optional": true,
1119
+ "os": [
1120
+ "darwin"
1121
+ ]
1122
+ },
1123
+ "node_modules/@rollup/rollup-freebsd-arm64": {
1124
+ "version": "4.57.1",
1125
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz",
1126
+ "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==",
1127
+ "cpu": [
1128
+ "arm64"
1129
+ ],
1130
+ "dev": true,
1131
+ "license": "MIT",
1132
+ "optional": true,
1133
+ "os": [
1134
+ "freebsd"
1135
+ ]
1136
+ },
1137
+ "node_modules/@rollup/rollup-freebsd-x64": {
1138
+ "version": "4.57.1",
1139
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz",
1140
+ "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==",
1141
+ "cpu": [
1142
+ "x64"
1143
+ ],
1144
+ "dev": true,
1145
+ "license": "MIT",
1146
+ "optional": true,
1147
+ "os": [
1148
+ "freebsd"
1149
+ ]
1150
+ },
1151
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
1152
+ "version": "4.57.1",
1153
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz",
1154
+ "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==",
1155
+ "cpu": [
1156
+ "arm"
1157
+ ],
1158
+ "dev": true,
1159
+ "license": "MIT",
1160
+ "optional": true,
1161
+ "os": [
1162
+ "linux"
1163
+ ]
1164
+ },
1165
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
1166
+ "version": "4.57.1",
1167
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz",
1168
+ "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==",
1169
+ "cpu": [
1170
+ "arm"
1171
+ ],
1172
+ "dev": true,
1173
+ "license": "MIT",
1174
+ "optional": true,
1175
+ "os": [
1176
+ "linux"
1177
+ ]
1178
+ },
1179
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
1180
+ "version": "4.57.1",
1181
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz",
1182
+ "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==",
1183
+ "cpu": [
1184
+ "arm64"
1185
+ ],
1186
+ "dev": true,
1187
+ "license": "MIT",
1188
+ "optional": true,
1189
+ "os": [
1190
+ "linux"
1191
+ ]
1192
+ },
1193
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
1194
+ "version": "4.57.1",
1195
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz",
1196
+ "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==",
1197
+ "cpu": [
1198
+ "arm64"
1199
+ ],
1200
+ "dev": true,
1201
+ "license": "MIT",
1202
+ "optional": true,
1203
+ "os": [
1204
+ "linux"
1205
+ ]
1206
+ },
1207
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
1208
+ "version": "4.57.1",
1209
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz",
1210
+ "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==",
1211
+ "cpu": [
1212
+ "loong64"
1213
+ ],
1214
+ "dev": true,
1215
+ "license": "MIT",
1216
+ "optional": true,
1217
+ "os": [
1218
+ "linux"
1219
+ ]
1220
+ },
1221
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
1222
+ "version": "4.57.1",
1223
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz",
1224
+ "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==",
1225
+ "cpu": [
1226
+ "loong64"
1227
+ ],
1228
+ "dev": true,
1229
+ "license": "MIT",
1230
+ "optional": true,
1231
+ "os": [
1232
+ "linux"
1233
+ ]
1234
+ },
1235
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
1236
+ "version": "4.57.1",
1237
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz",
1238
+ "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==",
1239
+ "cpu": [
1240
+ "ppc64"
1241
+ ],
1242
+ "dev": true,
1243
+ "license": "MIT",
1244
+ "optional": true,
1245
+ "os": [
1246
+ "linux"
1247
+ ]
1248
+ },
1249
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
1250
+ "version": "4.57.1",
1251
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz",
1252
+ "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==",
1253
+ "cpu": [
1254
+ "ppc64"
1255
+ ],
1256
+ "dev": true,
1257
+ "license": "MIT",
1258
+ "optional": true,
1259
+ "os": [
1260
+ "linux"
1261
+ ]
1262
+ },
1263
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1264
+ "version": "4.57.1",
1265
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz",
1266
+ "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==",
1267
+ "cpu": [
1268
+ "riscv64"
1269
+ ],
1270
+ "dev": true,
1271
+ "license": "MIT",
1272
+ "optional": true,
1273
+ "os": [
1274
+ "linux"
1275
+ ]
1276
+ },
1277
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
1278
+ "version": "4.57.1",
1279
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz",
1280
+ "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==",
1281
+ "cpu": [
1282
+ "riscv64"
1283
+ ],
1284
+ "dev": true,
1285
+ "license": "MIT",
1286
+ "optional": true,
1287
+ "os": [
1288
+ "linux"
1289
+ ]
1290
+ },
1291
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
1292
+ "version": "4.57.1",
1293
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz",
1294
+ "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==",
1295
+ "cpu": [
1296
+ "s390x"
1297
+ ],
1298
+ "dev": true,
1299
+ "license": "MIT",
1300
+ "optional": true,
1301
+ "os": [
1302
+ "linux"
1303
+ ]
1304
+ },
1305
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
1306
+ "version": "4.57.1",
1307
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz",
1308
+ "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==",
1309
+ "cpu": [
1310
+ "x64"
1311
+ ],
1312
+ "dev": true,
1313
+ "license": "MIT",
1314
+ "optional": true,
1315
+ "os": [
1316
+ "linux"
1317
+ ]
1318
+ },
1319
+ "node_modules/@rollup/rollup-linux-x64-musl": {
1320
+ "version": "4.57.1",
1321
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz",
1322
+ "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==",
1323
+ "cpu": [
1324
+ "x64"
1325
+ ],
1326
+ "dev": true,
1327
+ "license": "MIT",
1328
+ "optional": true,
1329
+ "os": [
1330
+ "linux"
1331
+ ]
1332
+ },
1333
+ "node_modules/@rollup/rollup-openbsd-x64": {
1334
+ "version": "4.57.1",
1335
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz",
1336
+ "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==",
1337
+ "cpu": [
1338
+ "x64"
1339
+ ],
1340
+ "dev": true,
1341
+ "license": "MIT",
1342
+ "optional": true,
1343
+ "os": [
1344
+ "openbsd"
1345
+ ]
1346
+ },
1347
+ "node_modules/@rollup/rollup-openharmony-arm64": {
1348
+ "version": "4.57.1",
1349
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz",
1350
+ "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==",
1351
+ "cpu": [
1352
+ "arm64"
1353
+ ],
1354
+ "dev": true,
1355
+ "license": "MIT",
1356
+ "optional": true,
1357
+ "os": [
1358
+ "openharmony"
1359
+ ]
1360
+ },
1361
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
1362
+ "version": "4.57.1",
1363
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz",
1364
+ "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==",
1365
+ "cpu": [
1366
+ "arm64"
1367
+ ],
1368
+ "dev": true,
1369
+ "license": "MIT",
1370
+ "optional": true,
1371
+ "os": [
1372
+ "win32"
1373
+ ]
1374
+ },
1375
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
1376
+ "version": "4.57.1",
1377
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz",
1378
+ "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==",
1379
+ "cpu": [
1380
+ "ia32"
1381
+ ],
1382
+ "dev": true,
1383
+ "license": "MIT",
1384
+ "optional": true,
1385
+ "os": [
1386
+ "win32"
1387
+ ]
1388
+ },
1389
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
1390
+ "version": "4.57.1",
1391
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz",
1392
+ "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==",
1393
+ "cpu": [
1394
+ "x64"
1395
+ ],
1396
+ "dev": true,
1397
+ "license": "MIT",
1398
+ "optional": true,
1399
+ "os": [
1400
+ "win32"
1401
+ ]
1402
+ },
1403
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
1404
+ "version": "4.57.1",
1405
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz",
1406
+ "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==",
1407
+ "cpu": [
1408
+ "x64"
1409
+ ],
1410
+ "dev": true,
1411
+ "license": "MIT",
1412
+ "optional": true,
1413
+ "os": [
1414
+ "win32"
1415
+ ]
1416
+ },
1417
+ "node_modules/@types/babel__core": {
1418
+ "version": "7.20.5",
1419
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
1420
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
1421
+ "dev": true,
1422
+ "license": "MIT",
1423
+ "dependencies": {
1424
+ "@babel/parser": "^7.20.7",
1425
+ "@babel/types": "^7.20.7",
1426
+ "@types/babel__generator": "*",
1427
+ "@types/babel__template": "*",
1428
+ "@types/babel__traverse": "*"
1429
+ }
1430
+ },
1431
+ "node_modules/@types/babel__generator": {
1432
+ "version": "7.27.0",
1433
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
1434
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
1435
+ "dev": true,
1436
+ "license": "MIT",
1437
+ "dependencies": {
1438
+ "@babel/types": "^7.0.0"
1439
+ }
1440
+ },
1441
+ "node_modules/@types/babel__template": {
1442
+ "version": "7.4.4",
1443
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
1444
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
1445
+ "dev": true,
1446
+ "license": "MIT",
1447
+ "dependencies": {
1448
+ "@babel/parser": "^7.1.0",
1449
+ "@babel/types": "^7.0.0"
1450
+ }
1451
+ },
1452
+ "node_modules/@types/babel__traverse": {
1453
+ "version": "7.28.0",
1454
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
1455
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
1456
+ "dev": true,
1457
+ "license": "MIT",
1458
+ "dependencies": {
1459
+ "@babel/types": "^7.28.2"
1460
+ }
1461
+ },
1462
+ "node_modules/@types/estree": {
1463
+ "version": "1.0.8",
1464
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
1465
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
1466
+ "dev": true,
1467
+ "license": "MIT"
1468
+ },
1469
+ "node_modules/@vitejs/plugin-react": {
1470
+ "version": "5.1.4",
1471
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz",
1472
+ "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==",
1473
+ "dev": true,
1474
+ "license": "MIT",
1475
+ "dependencies": {
1476
+ "@babel/core": "^7.29.0",
1477
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
1478
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
1479
+ "@rolldown/pluginutils": "1.0.0-rc.3",
1480
+ "@types/babel__core": "^7.20.5",
1481
+ "react-refresh": "^0.18.0"
1482
+ },
1483
+ "engines": {
1484
+ "node": "^20.19.0 || >=22.12.0"
1485
+ },
1486
+ "peerDependencies": {
1487
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
1488
+ }
1489
+ },
1490
+ "node_modules/antd": {
1491
+ "version": "5.29.3",
1492
+ "resolved": "https://registry.npmjs.org/antd/-/antd-5.29.3.tgz",
1493
+ "integrity": "sha512-3DdbGCa9tWAJGcCJ6rzR8EJFsv2CtyEbkVabZE14pfgUHfCicWCj0/QzQVLDYg8CPfQk9BH7fHCoTXHTy7MP/A==",
1494
+ "license": "MIT",
1495
+ "dependencies": {
1496
+ "@ant-design/colors": "^7.2.1",
1497
+ "@ant-design/cssinjs": "^1.23.0",
1498
+ "@ant-design/cssinjs-utils": "^1.1.3",
1499
+ "@ant-design/fast-color": "^2.0.6",
1500
+ "@ant-design/icons": "^5.6.1",
1501
+ "@ant-design/react-slick": "~1.1.2",
1502
+ "@babel/runtime": "^7.26.0",
1503
+ "@rc-component/color-picker": "~2.0.1",
1504
+ "@rc-component/mutate-observer": "^1.1.0",
1505
+ "@rc-component/qrcode": "~1.1.0",
1506
+ "@rc-component/tour": "~1.15.1",
1507
+ "@rc-component/trigger": "^2.3.0",
1508
+ "classnames": "^2.5.1",
1509
+ "copy-to-clipboard": "^3.3.3",
1510
+ "dayjs": "^1.11.11",
1511
+ "rc-cascader": "~3.34.0",
1512
+ "rc-checkbox": "~3.5.0",
1513
+ "rc-collapse": "~3.9.0",
1514
+ "rc-dialog": "~9.6.0",
1515
+ "rc-drawer": "~7.3.0",
1516
+ "rc-dropdown": "~4.2.1",
1517
+ "rc-field-form": "~2.7.1",
1518
+ "rc-image": "~7.12.0",
1519
+ "rc-input": "~1.8.0",
1520
+ "rc-input-number": "~9.5.0",
1521
+ "rc-mentions": "~2.20.0",
1522
+ "rc-menu": "~9.16.1",
1523
+ "rc-motion": "^2.9.5",
1524
+ "rc-notification": "~5.6.4",
1525
+ "rc-pagination": "~5.1.0",
1526
+ "rc-picker": "~4.11.3",
1527
+ "rc-progress": "~4.0.0",
1528
+ "rc-rate": "~2.13.1",
1529
+ "rc-resize-observer": "^1.4.3",
1530
+ "rc-segmented": "~2.7.0",
1531
+ "rc-select": "~14.16.8",
1532
+ "rc-slider": "~11.1.9",
1533
+ "rc-steps": "~6.0.1",
1534
+ "rc-switch": "~4.1.0",
1535
+ "rc-table": "~7.54.0",
1536
+ "rc-tabs": "~15.7.0",
1537
+ "rc-textarea": "~1.10.2",
1538
+ "rc-tooltip": "~6.4.0",
1539
+ "rc-tree": "~5.13.1",
1540
+ "rc-tree-select": "~5.27.0",
1541
+ "rc-upload": "~4.11.0",
1542
+ "rc-util": "^5.44.4",
1543
+ "scroll-into-view-if-needed": "^3.1.0",
1544
+ "throttle-debounce": "^5.0.2"
1545
+ },
1546
+ "funding": {
1547
+ "type": "opencollective",
1548
+ "url": "https://opencollective.com/ant-design"
1549
+ },
1550
+ "peerDependencies": {
1551
+ "react": ">=16.9.0",
1552
+ "react-dom": ">=16.9.0"
1553
+ }
1554
+ },
1555
+ "node_modules/baseline-browser-mapping": {
1556
+ "version": "2.9.19",
1557
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
1558
+ "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
1559
+ "dev": true,
1560
+ "license": "Apache-2.0",
1561
+ "bin": {
1562
+ "baseline-browser-mapping": "dist/cli.js"
1563
+ }
1564
+ },
1565
+ "node_modules/browserslist": {
1566
+ "version": "4.28.1",
1567
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
1568
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
1569
+ "dev": true,
1570
+ "funding": [
1571
+ {
1572
+ "type": "opencollective",
1573
+ "url": "https://opencollective.com/browserslist"
1574
+ },
1575
+ {
1576
+ "type": "tidelift",
1577
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
1578
+ },
1579
+ {
1580
+ "type": "github",
1581
+ "url": "https://github.com/sponsors/ai"
1582
+ }
1583
+ ],
1584
+ "license": "MIT",
1585
+ "peer": true,
1586
+ "dependencies": {
1587
+ "baseline-browser-mapping": "^2.9.0",
1588
+ "caniuse-lite": "^1.0.30001759",
1589
+ "electron-to-chromium": "^1.5.263",
1590
+ "node-releases": "^2.0.27",
1591
+ "update-browserslist-db": "^1.2.0"
1592
+ },
1593
+ "bin": {
1594
+ "browserslist": "cli.js"
1595
+ },
1596
+ "engines": {
1597
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
1598
+ }
1599
+ },
1600
+ "node_modules/caniuse-lite": {
1601
+ "version": "1.0.30001770",
1602
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz",
1603
+ "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==",
1604
+ "dev": true,
1605
+ "funding": [
1606
+ {
1607
+ "type": "opencollective",
1608
+ "url": "https://opencollective.com/browserslist"
1609
+ },
1610
+ {
1611
+ "type": "tidelift",
1612
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1613
+ },
1614
+ {
1615
+ "type": "github",
1616
+ "url": "https://github.com/sponsors/ai"
1617
+ }
1618
+ ],
1619
+ "license": "CC-BY-4.0"
1620
+ },
1621
+ "node_modules/classnames": {
1622
+ "version": "2.5.1",
1623
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
1624
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
1625
+ "license": "MIT"
1626
+ },
1627
+ "node_modules/compute-scroll-into-view": {
1628
+ "version": "3.1.1",
1629
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz",
1630
+ "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
1631
+ "license": "MIT"
1632
+ },
1633
+ "node_modules/convert-source-map": {
1634
+ "version": "2.0.0",
1635
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
1636
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
1637
+ "dev": true,
1638
+ "license": "MIT"
1639
+ },
1640
+ "node_modules/copy-to-clipboard": {
1641
+ "version": "3.3.3",
1642
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
1643
+ "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
1644
+ "license": "MIT",
1645
+ "dependencies": {
1646
+ "toggle-selection": "^1.0.6"
1647
+ }
1648
+ },
1649
+ "node_modules/csstype": {
1650
+ "version": "3.2.3",
1651
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
1652
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
1653
+ "license": "MIT"
1654
+ },
1655
+ "node_modules/dayjs": {
1656
+ "version": "1.11.19",
1657
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
1658
+ "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
1659
+ "license": "MIT",
1660
+ "peer": true
1661
+ },
1662
+ "node_modules/debug": {
1663
+ "version": "4.4.3",
1664
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1665
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1666
+ "dev": true,
1667
+ "license": "MIT",
1668
+ "dependencies": {
1669
+ "ms": "^2.1.3"
1670
+ },
1671
+ "engines": {
1672
+ "node": ">=6.0"
1673
+ },
1674
+ "peerDependenciesMeta": {
1675
+ "supports-color": {
1676
+ "optional": true
1677
+ }
1678
+ }
1679
+ },
1680
+ "node_modules/electron-to-chromium": {
1681
+ "version": "1.5.286",
1682
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
1683
+ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
1684
+ "dev": true,
1685
+ "license": "ISC"
1686
+ },
1687
+ "node_modules/esbuild": {
1688
+ "version": "0.27.3",
1689
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
1690
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
1691
+ "dev": true,
1692
+ "hasInstallScript": true,
1693
+ "license": "MIT",
1694
+ "bin": {
1695
+ "esbuild": "bin/esbuild"
1696
+ },
1697
+ "engines": {
1698
+ "node": ">=18"
1699
+ },
1700
+ "optionalDependencies": {
1701
+ "@esbuild/aix-ppc64": "0.27.3",
1702
+ "@esbuild/android-arm": "0.27.3",
1703
+ "@esbuild/android-arm64": "0.27.3",
1704
+ "@esbuild/android-x64": "0.27.3",
1705
+ "@esbuild/darwin-arm64": "0.27.3",
1706
+ "@esbuild/darwin-x64": "0.27.3",
1707
+ "@esbuild/freebsd-arm64": "0.27.3",
1708
+ "@esbuild/freebsd-x64": "0.27.3",
1709
+ "@esbuild/linux-arm": "0.27.3",
1710
+ "@esbuild/linux-arm64": "0.27.3",
1711
+ "@esbuild/linux-ia32": "0.27.3",
1712
+ "@esbuild/linux-loong64": "0.27.3",
1713
+ "@esbuild/linux-mips64el": "0.27.3",
1714
+ "@esbuild/linux-ppc64": "0.27.3",
1715
+ "@esbuild/linux-riscv64": "0.27.3",
1716
+ "@esbuild/linux-s390x": "0.27.3",
1717
+ "@esbuild/linux-x64": "0.27.3",
1718
+ "@esbuild/netbsd-arm64": "0.27.3",
1719
+ "@esbuild/netbsd-x64": "0.27.3",
1720
+ "@esbuild/openbsd-arm64": "0.27.3",
1721
+ "@esbuild/openbsd-x64": "0.27.3",
1722
+ "@esbuild/openharmony-arm64": "0.27.3",
1723
+ "@esbuild/sunos-x64": "0.27.3",
1724
+ "@esbuild/win32-arm64": "0.27.3",
1725
+ "@esbuild/win32-ia32": "0.27.3",
1726
+ "@esbuild/win32-x64": "0.27.3"
1727
+ }
1728
+ },
1729
+ "node_modules/escalade": {
1730
+ "version": "3.2.0",
1731
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1732
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1733
+ "dev": true,
1734
+ "license": "MIT",
1735
+ "engines": {
1736
+ "node": ">=6"
1737
+ }
1738
+ },
1739
+ "node_modules/fdir": {
1740
+ "version": "6.5.0",
1741
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
1742
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
1743
+ "dev": true,
1744
+ "license": "MIT",
1745
+ "engines": {
1746
+ "node": ">=12.0.0"
1747
+ },
1748
+ "peerDependencies": {
1749
+ "picomatch": "^3 || ^4"
1750
+ },
1751
+ "peerDependenciesMeta": {
1752
+ "picomatch": {
1753
+ "optional": true
1754
+ }
1755
+ }
1756
+ },
1757
+ "node_modules/fsevents": {
1758
+ "version": "2.3.3",
1759
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1760
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1761
+ "dev": true,
1762
+ "hasInstallScript": true,
1763
+ "license": "MIT",
1764
+ "optional": true,
1765
+ "os": [
1766
+ "darwin"
1767
+ ],
1768
+ "engines": {
1769
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1770
+ }
1771
+ },
1772
+ "node_modules/gensync": {
1773
+ "version": "1.0.0-beta.2",
1774
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
1775
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
1776
+ "dev": true,
1777
+ "license": "MIT",
1778
+ "engines": {
1779
+ "node": ">=6.9.0"
1780
+ }
1781
+ },
1782
+ "node_modules/js-tokens": {
1783
+ "version": "4.0.0",
1784
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1785
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1786
+ "dev": true,
1787
+ "license": "MIT"
1788
+ },
1789
+ "node_modules/jsesc": {
1790
+ "version": "3.1.0",
1791
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
1792
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
1793
+ "dev": true,
1794
+ "license": "MIT",
1795
+ "bin": {
1796
+ "jsesc": "bin/jsesc"
1797
+ },
1798
+ "engines": {
1799
+ "node": ">=6"
1800
+ }
1801
+ },
1802
+ "node_modules/json2mq": {
1803
+ "version": "0.2.0",
1804
+ "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
1805
+ "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
1806
+ "license": "MIT",
1807
+ "dependencies": {
1808
+ "string-convert": "^0.2.0"
1809
+ }
1810
+ },
1811
+ "node_modules/json5": {
1812
+ "version": "2.2.3",
1813
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
1814
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
1815
+ "dev": true,
1816
+ "license": "MIT",
1817
+ "bin": {
1818
+ "json5": "lib/cli.js"
1819
+ },
1820
+ "engines": {
1821
+ "node": ">=6"
1822
+ }
1823
+ },
1824
+ "node_modules/lru-cache": {
1825
+ "version": "5.1.1",
1826
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
1827
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
1828
+ "dev": true,
1829
+ "license": "ISC",
1830
+ "dependencies": {
1831
+ "yallist": "^3.0.2"
1832
+ }
1833
+ },
1834
+ "node_modules/ms": {
1835
+ "version": "2.1.3",
1836
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1837
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1838
+ "dev": true,
1839
+ "license": "MIT"
1840
+ },
1841
+ "node_modules/nanoid": {
1842
+ "version": "3.3.11",
1843
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1844
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1845
+ "dev": true,
1846
+ "funding": [
1847
+ {
1848
+ "type": "github",
1849
+ "url": "https://github.com/sponsors/ai"
1850
+ }
1851
+ ],
1852
+ "license": "MIT",
1853
+ "bin": {
1854
+ "nanoid": "bin/nanoid.cjs"
1855
+ },
1856
+ "engines": {
1857
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1858
+ }
1859
+ },
1860
+ "node_modules/node-releases": {
1861
+ "version": "2.0.27",
1862
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
1863
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
1864
+ "dev": true,
1865
+ "license": "MIT"
1866
+ },
1867
+ "node_modules/picocolors": {
1868
+ "version": "1.1.1",
1869
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1870
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1871
+ "dev": true,
1872
+ "license": "ISC"
1873
+ },
1874
+ "node_modules/picomatch": {
1875
+ "version": "4.0.3",
1876
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
1877
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
1878
+ "dev": true,
1879
+ "license": "MIT",
1880
+ "peer": true,
1881
+ "engines": {
1882
+ "node": ">=12"
1883
+ },
1884
+ "funding": {
1885
+ "url": "https://github.com/sponsors/jonschlinkert"
1886
+ }
1887
+ },
1888
+ "node_modules/postcss": {
1889
+ "version": "8.5.6",
1890
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
1891
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
1892
+ "dev": true,
1893
+ "funding": [
1894
+ {
1895
+ "type": "opencollective",
1896
+ "url": "https://opencollective.com/postcss/"
1897
+ },
1898
+ {
1899
+ "type": "tidelift",
1900
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1901
+ },
1902
+ {
1903
+ "type": "github",
1904
+ "url": "https://github.com/sponsors/ai"
1905
+ }
1906
+ ],
1907
+ "license": "MIT",
1908
+ "dependencies": {
1909
+ "nanoid": "^3.3.11",
1910
+ "picocolors": "^1.1.1",
1911
+ "source-map-js": "^1.2.1"
1912
+ },
1913
+ "engines": {
1914
+ "node": "^10 || ^12 || >=14"
1915
+ }
1916
+ },
1917
+ "node_modules/rc-cascader": {
1918
+ "version": "3.34.0",
1919
+ "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.34.0.tgz",
1920
+ "integrity": "sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==",
1921
+ "license": "MIT",
1922
+ "dependencies": {
1923
+ "@babel/runtime": "^7.25.7",
1924
+ "classnames": "^2.3.1",
1925
+ "rc-select": "~14.16.2",
1926
+ "rc-tree": "~5.13.0",
1927
+ "rc-util": "^5.43.0"
1928
+ },
1929
+ "peerDependencies": {
1930
+ "react": ">=16.9.0",
1931
+ "react-dom": ">=16.9.0"
1932
+ }
1933
+ },
1934
+ "node_modules/rc-checkbox": {
1935
+ "version": "3.5.0",
1936
+ "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.5.0.tgz",
1937
+ "integrity": "sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==",
1938
+ "license": "MIT",
1939
+ "dependencies": {
1940
+ "@babel/runtime": "^7.10.1",
1941
+ "classnames": "^2.3.2",
1942
+ "rc-util": "^5.25.2"
1943
+ },
1944
+ "peerDependencies": {
1945
+ "react": ">=16.9.0",
1946
+ "react-dom": ">=16.9.0"
1947
+ }
1948
+ },
1949
+ "node_modules/rc-collapse": {
1950
+ "version": "3.9.0",
1951
+ "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.9.0.tgz",
1952
+ "integrity": "sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==",
1953
+ "license": "MIT",
1954
+ "dependencies": {
1955
+ "@babel/runtime": "^7.10.1",
1956
+ "classnames": "2.x",
1957
+ "rc-motion": "^2.3.4",
1958
+ "rc-util": "^5.27.0"
1959
+ },
1960
+ "peerDependencies": {
1961
+ "react": ">=16.9.0",
1962
+ "react-dom": ">=16.9.0"
1963
+ }
1964
+ },
1965
+ "node_modules/rc-dialog": {
1966
+ "version": "9.6.0",
1967
+ "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.6.0.tgz",
1968
+ "integrity": "sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==",
1969
+ "license": "MIT",
1970
+ "dependencies": {
1971
+ "@babel/runtime": "^7.10.1",
1972
+ "@rc-component/portal": "^1.0.0-8",
1973
+ "classnames": "^2.2.6",
1974
+ "rc-motion": "^2.3.0",
1975
+ "rc-util": "^5.21.0"
1976
+ },
1977
+ "peerDependencies": {
1978
+ "react": ">=16.9.0",
1979
+ "react-dom": ">=16.9.0"
1980
+ }
1981
+ },
1982
+ "node_modules/rc-drawer": {
1983
+ "version": "7.3.0",
1984
+ "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.3.0.tgz",
1985
+ "integrity": "sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==",
1986
+ "license": "MIT",
1987
+ "dependencies": {
1988
+ "@babel/runtime": "^7.23.9",
1989
+ "@rc-component/portal": "^1.1.1",
1990
+ "classnames": "^2.2.6",
1991
+ "rc-motion": "^2.6.1",
1992
+ "rc-util": "^5.38.1"
1993
+ },
1994
+ "peerDependencies": {
1995
+ "react": ">=16.9.0",
1996
+ "react-dom": ">=16.9.0"
1997
+ }
1998
+ },
1999
+ "node_modules/rc-dropdown": {
2000
+ "version": "4.2.1",
2001
+ "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.1.tgz",
2002
+ "integrity": "sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==",
2003
+ "license": "MIT",
2004
+ "dependencies": {
2005
+ "@babel/runtime": "^7.18.3",
2006
+ "@rc-component/trigger": "^2.0.0",
2007
+ "classnames": "^2.2.6",
2008
+ "rc-util": "^5.44.1"
2009
+ },
2010
+ "peerDependencies": {
2011
+ "react": ">=16.11.0",
2012
+ "react-dom": ">=16.11.0"
2013
+ }
2014
+ },
2015
+ "node_modules/rc-field-form": {
2016
+ "version": "2.7.1",
2017
+ "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.7.1.tgz",
2018
+ "integrity": "sha512-vKeSifSJ6HoLaAB+B8aq/Qgm8a3dyxROzCtKNCsBQgiverpc4kWDQihoUwzUj+zNWJOykwSY4dNX3QrGwtVb9A==",
2019
+ "license": "MIT",
2020
+ "dependencies": {
2021
+ "@babel/runtime": "^7.18.0",
2022
+ "@rc-component/async-validator": "^5.0.3",
2023
+ "rc-util": "^5.32.2"
2024
+ },
2025
+ "engines": {
2026
+ "node": ">=8.x"
2027
+ },
2028
+ "peerDependencies": {
2029
+ "react": ">=16.9.0",
2030
+ "react-dom": ">=16.9.0"
2031
+ }
2032
+ },
2033
+ "node_modules/rc-image": {
2034
+ "version": "7.12.0",
2035
+ "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.12.0.tgz",
2036
+ "integrity": "sha512-cZ3HTyyckPnNnUb9/DRqduqzLfrQRyi+CdHjdqgsyDpI3Ln5UX1kXnAhPBSJj9pVRzwRFgqkN7p9b6HBDjmu/Q==",
2037
+ "license": "MIT",
2038
+ "dependencies": {
2039
+ "@babel/runtime": "^7.11.2",
2040
+ "@rc-component/portal": "^1.0.2",
2041
+ "classnames": "^2.2.6",
2042
+ "rc-dialog": "~9.6.0",
2043
+ "rc-motion": "^2.6.2",
2044
+ "rc-util": "^5.34.1"
2045
+ },
2046
+ "peerDependencies": {
2047
+ "react": ">=16.9.0",
2048
+ "react-dom": ">=16.9.0"
2049
+ }
2050
+ },
2051
+ "node_modules/rc-input": {
2052
+ "version": "1.8.0",
2053
+ "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.8.0.tgz",
2054
+ "integrity": "sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==",
2055
+ "license": "MIT",
2056
+ "dependencies": {
2057
+ "@babel/runtime": "^7.11.1",
2058
+ "classnames": "^2.2.1",
2059
+ "rc-util": "^5.18.1"
2060
+ },
2061
+ "peerDependencies": {
2062
+ "react": ">=16.0.0",
2063
+ "react-dom": ">=16.0.0"
2064
+ }
2065
+ },
2066
+ "node_modules/rc-input-number": {
2067
+ "version": "9.5.0",
2068
+ "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.5.0.tgz",
2069
+ "integrity": "sha512-bKaEvB5tHebUURAEXw35LDcnRZLq3x1k7GxfAqBMzmpHkDGzjAtnUL8y4y5N15rIFIg5IJgwr211jInl3cipag==",
2070
+ "license": "MIT",
2071
+ "dependencies": {
2072
+ "@babel/runtime": "^7.10.1",
2073
+ "@rc-component/mini-decimal": "^1.0.1",
2074
+ "classnames": "^2.2.5",
2075
+ "rc-input": "~1.8.0",
2076
+ "rc-util": "^5.40.1"
2077
+ },
2078
+ "peerDependencies": {
2079
+ "react": ">=16.9.0",
2080
+ "react-dom": ">=16.9.0"
2081
+ }
2082
+ },
2083
+ "node_modules/rc-mentions": {
2084
+ "version": "2.20.0",
2085
+ "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.20.0.tgz",
2086
+ "integrity": "sha512-w8HCMZEh3f0nR8ZEd466ATqmXFCMGMN5UFCzEUL0bM/nGw/wOS2GgRzKBcm19K++jDyuWCOJOdgcKGXU3fXfbQ==",
2087
+ "license": "MIT",
2088
+ "dependencies": {
2089
+ "@babel/runtime": "^7.22.5",
2090
+ "@rc-component/trigger": "^2.0.0",
2091
+ "classnames": "^2.2.6",
2092
+ "rc-input": "~1.8.0",
2093
+ "rc-menu": "~9.16.0",
2094
+ "rc-textarea": "~1.10.0",
2095
+ "rc-util": "^5.34.1"
2096
+ },
2097
+ "peerDependencies": {
2098
+ "react": ">=16.9.0",
2099
+ "react-dom": ">=16.9.0"
2100
+ }
2101
+ },
2102
+ "node_modules/rc-menu": {
2103
+ "version": "9.16.1",
2104
+ "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.16.1.tgz",
2105
+ "integrity": "sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==",
2106
+ "license": "MIT",
2107
+ "dependencies": {
2108
+ "@babel/runtime": "^7.10.1",
2109
+ "@rc-component/trigger": "^2.0.0",
2110
+ "classnames": "2.x",
2111
+ "rc-motion": "^2.4.3",
2112
+ "rc-overflow": "^1.3.1",
2113
+ "rc-util": "^5.27.0"
2114
+ },
2115
+ "peerDependencies": {
2116
+ "react": ">=16.9.0",
2117
+ "react-dom": ">=16.9.0"
2118
+ }
2119
+ },
2120
+ "node_modules/rc-motion": {
2121
+ "version": "2.9.5",
2122
+ "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.5.tgz",
2123
+ "integrity": "sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==",
2124
+ "license": "MIT",
2125
+ "dependencies": {
2126
+ "@babel/runtime": "^7.11.1",
2127
+ "classnames": "^2.2.1",
2128
+ "rc-util": "^5.44.0"
2129
+ },
2130
+ "peerDependencies": {
2131
+ "react": ">=16.9.0",
2132
+ "react-dom": ">=16.9.0"
2133
+ }
2134
+ },
2135
+ "node_modules/rc-notification": {
2136
+ "version": "5.6.4",
2137
+ "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.4.tgz",
2138
+ "integrity": "sha512-KcS4O6B4qzM3KH7lkwOB7ooLPZ4b6J+VMmQgT51VZCeEcmghdeR4IrMcFq0LG+RPdnbe/ArT086tGM8Snimgiw==",
2139
+ "license": "MIT",
2140
+ "dependencies": {
2141
+ "@babel/runtime": "^7.10.1",
2142
+ "classnames": "2.x",
2143
+ "rc-motion": "^2.9.0",
2144
+ "rc-util": "^5.20.1"
2145
+ },
2146
+ "engines": {
2147
+ "node": ">=8.x"
2148
+ },
2149
+ "peerDependencies": {
2150
+ "react": ">=16.9.0",
2151
+ "react-dom": ">=16.9.0"
2152
+ }
2153
+ },
2154
+ "node_modules/rc-overflow": {
2155
+ "version": "1.5.0",
2156
+ "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.5.0.tgz",
2157
+ "integrity": "sha512-Lm/v9h0LymeUYJf0x39OveU52InkdRXqnn2aYXfWmo8WdOonIKB2kfau+GF0fWq6jPgtdO9yMqveGcK6aIhJmg==",
2158
+ "license": "MIT",
2159
+ "dependencies": {
2160
+ "@babel/runtime": "^7.11.1",
2161
+ "classnames": "^2.2.1",
2162
+ "rc-resize-observer": "^1.0.0",
2163
+ "rc-util": "^5.37.0"
2164
+ },
2165
+ "peerDependencies": {
2166
+ "react": ">=16.9.0",
2167
+ "react-dom": ">=16.9.0"
2168
+ }
2169
+ },
2170
+ "node_modules/rc-pagination": {
2171
+ "version": "5.1.0",
2172
+ "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-5.1.0.tgz",
2173
+ "integrity": "sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==",
2174
+ "license": "MIT",
2175
+ "dependencies": {
2176
+ "@babel/runtime": "^7.10.1",
2177
+ "classnames": "^2.3.2",
2178
+ "rc-util": "^5.38.0"
2179
+ },
2180
+ "peerDependencies": {
2181
+ "react": ">=16.9.0",
2182
+ "react-dom": ">=16.9.0"
2183
+ }
2184
+ },
2185
+ "node_modules/rc-picker": {
2186
+ "version": "4.11.3",
2187
+ "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.11.3.tgz",
2188
+ "integrity": "sha512-MJ5teb7FlNE0NFHTncxXQ62Y5lytq6sh5nUw0iH8OkHL/TjARSEvSHpr940pWgjGANpjCwyMdvsEV55l5tYNSg==",
2189
+ "license": "MIT",
2190
+ "dependencies": {
2191
+ "@babel/runtime": "^7.24.7",
2192
+ "@rc-component/trigger": "^2.0.0",
2193
+ "classnames": "^2.2.1",
2194
+ "rc-overflow": "^1.3.2",
2195
+ "rc-resize-observer": "^1.4.0",
2196
+ "rc-util": "^5.43.0"
2197
+ },
2198
+ "engines": {
2199
+ "node": ">=8.x"
2200
+ },
2201
+ "peerDependencies": {
2202
+ "date-fns": ">= 2.x",
2203
+ "dayjs": ">= 1.x",
2204
+ "luxon": ">= 3.x",
2205
+ "moment": ">= 2.x",
2206
+ "react": ">=16.9.0",
2207
+ "react-dom": ">=16.9.0"
2208
+ },
2209
+ "peerDependenciesMeta": {
2210
+ "date-fns": {
2211
+ "optional": true
2212
+ },
2213
+ "dayjs": {
2214
+ "optional": true
2215
+ },
2216
+ "luxon": {
2217
+ "optional": true
2218
+ },
2219
+ "moment": {
2220
+ "optional": true
2221
+ }
2222
+ }
2223
+ },
2224
+ "node_modules/rc-progress": {
2225
+ "version": "4.0.0",
2226
+ "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-4.0.0.tgz",
2227
+ "integrity": "sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==",
2228
+ "license": "MIT",
2229
+ "dependencies": {
2230
+ "@babel/runtime": "^7.10.1",
2231
+ "classnames": "^2.2.6",
2232
+ "rc-util": "^5.16.1"
2233
+ },
2234
+ "peerDependencies": {
2235
+ "react": ">=16.9.0",
2236
+ "react-dom": ">=16.9.0"
2237
+ }
2238
+ },
2239
+ "node_modules/rc-rate": {
2240
+ "version": "2.13.1",
2241
+ "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.1.tgz",
2242
+ "integrity": "sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==",
2243
+ "license": "MIT",
2244
+ "dependencies": {
2245
+ "@babel/runtime": "^7.10.1",
2246
+ "classnames": "^2.2.5",
2247
+ "rc-util": "^5.0.1"
2248
+ },
2249
+ "engines": {
2250
+ "node": ">=8.x"
2251
+ },
2252
+ "peerDependencies": {
2253
+ "react": ">=16.9.0",
2254
+ "react-dom": ">=16.9.0"
2255
+ }
2256
+ },
2257
+ "node_modules/rc-resize-observer": {
2258
+ "version": "1.4.3",
2259
+ "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.3.tgz",
2260
+ "integrity": "sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==",
2261
+ "license": "MIT",
2262
+ "dependencies": {
2263
+ "@babel/runtime": "^7.20.7",
2264
+ "classnames": "^2.2.1",
2265
+ "rc-util": "^5.44.1",
2266
+ "resize-observer-polyfill": "^1.5.1"
2267
+ },
2268
+ "peerDependencies": {
2269
+ "react": ">=16.9.0",
2270
+ "react-dom": ">=16.9.0"
2271
+ }
2272
+ },
2273
+ "node_modules/rc-segmented": {
2274
+ "version": "2.7.1",
2275
+ "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.7.1.tgz",
2276
+ "integrity": "sha512-izj1Nw/Dw2Vb7EVr+D/E9lUTkBe+kKC+SAFSU9zqr7WV2W5Ktaa9Gc7cB2jTqgk8GROJayltaec+DBlYKc6d+g==",
2277
+ "license": "MIT",
2278
+ "dependencies": {
2279
+ "@babel/runtime": "^7.11.1",
2280
+ "classnames": "^2.2.1",
2281
+ "rc-motion": "^2.4.4",
2282
+ "rc-util": "^5.17.0"
2283
+ },
2284
+ "peerDependencies": {
2285
+ "react": ">=16.0.0",
2286
+ "react-dom": ">=16.0.0"
2287
+ }
2288
+ },
2289
+ "node_modules/rc-select": {
2290
+ "version": "14.16.8",
2291
+ "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.16.8.tgz",
2292
+ "integrity": "sha512-NOV5BZa1wZrsdkKaiK7LHRuo5ZjZYMDxPP6/1+09+FB4KoNi8jcG1ZqLE3AVCxEsYMBe65OBx71wFoHRTP3LRg==",
2293
+ "license": "MIT",
2294
+ "dependencies": {
2295
+ "@babel/runtime": "^7.10.1",
2296
+ "@rc-component/trigger": "^2.1.1",
2297
+ "classnames": "2.x",
2298
+ "rc-motion": "^2.0.1",
2299
+ "rc-overflow": "^1.3.1",
2300
+ "rc-util": "^5.16.1",
2301
+ "rc-virtual-list": "^3.5.2"
2302
+ },
2303
+ "engines": {
2304
+ "node": ">=8.x"
2305
+ },
2306
+ "peerDependencies": {
2307
+ "react": "*",
2308
+ "react-dom": "*"
2309
+ }
2310
+ },
2311
+ "node_modules/rc-slider": {
2312
+ "version": "11.1.9",
2313
+ "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-11.1.9.tgz",
2314
+ "integrity": "sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==",
2315
+ "license": "MIT",
2316
+ "dependencies": {
2317
+ "@babel/runtime": "^7.10.1",
2318
+ "classnames": "^2.2.5",
2319
+ "rc-util": "^5.36.0"
2320
+ },
2321
+ "engines": {
2322
+ "node": ">=8.x"
2323
+ },
2324
+ "peerDependencies": {
2325
+ "react": ">=16.9.0",
2326
+ "react-dom": ">=16.9.0"
2327
+ }
2328
+ },
2329
+ "node_modules/rc-steps": {
2330
+ "version": "6.0.1",
2331
+ "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-6.0.1.tgz",
2332
+ "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==",
2333
+ "license": "MIT",
2334
+ "dependencies": {
2335
+ "@babel/runtime": "^7.16.7",
2336
+ "classnames": "^2.2.3",
2337
+ "rc-util": "^5.16.1"
2338
+ },
2339
+ "engines": {
2340
+ "node": ">=8.x"
2341
+ },
2342
+ "peerDependencies": {
2343
+ "react": ">=16.9.0",
2344
+ "react-dom": ">=16.9.0"
2345
+ }
2346
+ },
2347
+ "node_modules/rc-switch": {
2348
+ "version": "4.1.0",
2349
+ "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-4.1.0.tgz",
2350
+ "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==",
2351
+ "license": "MIT",
2352
+ "dependencies": {
2353
+ "@babel/runtime": "^7.21.0",
2354
+ "classnames": "^2.2.1",
2355
+ "rc-util": "^5.30.0"
2356
+ },
2357
+ "peerDependencies": {
2358
+ "react": ">=16.9.0",
2359
+ "react-dom": ">=16.9.0"
2360
+ }
2361
+ },
2362
+ "node_modules/rc-table": {
2363
+ "version": "7.54.0",
2364
+ "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.54.0.tgz",
2365
+ "integrity": "sha512-/wDTkki6wBTjwylwAGjpLKYklKo9YgjZwAU77+7ME5mBoS32Q4nAwoqhA2lSge6fobLW3Tap6uc5xfwaL2p0Sw==",
2366
+ "license": "MIT",
2367
+ "dependencies": {
2368
+ "@babel/runtime": "^7.10.1",
2369
+ "@rc-component/context": "^1.4.0",
2370
+ "classnames": "^2.2.5",
2371
+ "rc-resize-observer": "^1.1.0",
2372
+ "rc-util": "^5.44.3",
2373
+ "rc-virtual-list": "^3.14.2"
2374
+ },
2375
+ "engines": {
2376
+ "node": ">=8.x"
2377
+ },
2378
+ "peerDependencies": {
2379
+ "react": ">=16.9.0",
2380
+ "react-dom": ">=16.9.0"
2381
+ }
2382
+ },
2383
+ "node_modules/rc-tabs": {
2384
+ "version": "15.7.0",
2385
+ "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.7.0.tgz",
2386
+ "integrity": "sha512-ZepiE+6fmozYdWf/9gVp7k56PKHB1YYoDsKeQA1CBlJ/POIhjkcYiv0AGP0w2Jhzftd3AVvZP/K+V+Lpi2ankA==",
2387
+ "license": "MIT",
2388
+ "dependencies": {
2389
+ "@babel/runtime": "^7.11.2",
2390
+ "classnames": "2.x",
2391
+ "rc-dropdown": "~4.2.0",
2392
+ "rc-menu": "~9.16.0",
2393
+ "rc-motion": "^2.6.2",
2394
+ "rc-resize-observer": "^1.0.0",
2395
+ "rc-util": "^5.34.1"
2396
+ },
2397
+ "engines": {
2398
+ "node": ">=8.x"
2399
+ },
2400
+ "peerDependencies": {
2401
+ "react": ">=16.9.0",
2402
+ "react-dom": ">=16.9.0"
2403
+ }
2404
+ },
2405
+ "node_modules/rc-textarea": {
2406
+ "version": "1.10.2",
2407
+ "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.10.2.tgz",
2408
+ "integrity": "sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==",
2409
+ "license": "MIT",
2410
+ "dependencies": {
2411
+ "@babel/runtime": "^7.10.1",
2412
+ "classnames": "^2.2.1",
2413
+ "rc-input": "~1.8.0",
2414
+ "rc-resize-observer": "^1.0.0",
2415
+ "rc-util": "^5.27.0"
2416
+ },
2417
+ "peerDependencies": {
2418
+ "react": ">=16.9.0",
2419
+ "react-dom": ">=16.9.0"
2420
+ }
2421
+ },
2422
+ "node_modules/rc-tooltip": {
2423
+ "version": "6.4.0",
2424
+ "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.4.0.tgz",
2425
+ "integrity": "sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==",
2426
+ "license": "MIT",
2427
+ "dependencies": {
2428
+ "@babel/runtime": "^7.11.2",
2429
+ "@rc-component/trigger": "^2.0.0",
2430
+ "classnames": "^2.3.1",
2431
+ "rc-util": "^5.44.3"
2432
+ },
2433
+ "peerDependencies": {
2434
+ "react": ">=16.9.0",
2435
+ "react-dom": ">=16.9.0"
2436
+ }
2437
+ },
2438
+ "node_modules/rc-tree": {
2439
+ "version": "5.13.1",
2440
+ "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.13.1.tgz",
2441
+ "integrity": "sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==",
2442
+ "license": "MIT",
2443
+ "dependencies": {
2444
+ "@babel/runtime": "^7.10.1",
2445
+ "classnames": "2.x",
2446
+ "rc-motion": "^2.0.1",
2447
+ "rc-util": "^5.16.1",
2448
+ "rc-virtual-list": "^3.5.1"
2449
+ },
2450
+ "engines": {
2451
+ "node": ">=10.x"
2452
+ },
2453
+ "peerDependencies": {
2454
+ "react": "*",
2455
+ "react-dom": "*"
2456
+ }
2457
+ },
2458
+ "node_modules/rc-tree-select": {
2459
+ "version": "5.27.0",
2460
+ "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.27.0.tgz",
2461
+ "integrity": "sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==",
2462
+ "license": "MIT",
2463
+ "dependencies": {
2464
+ "@babel/runtime": "^7.25.7",
2465
+ "classnames": "2.x",
2466
+ "rc-select": "~14.16.2",
2467
+ "rc-tree": "~5.13.0",
2468
+ "rc-util": "^5.43.0"
2469
+ },
2470
+ "peerDependencies": {
2471
+ "react": "*",
2472
+ "react-dom": "*"
2473
+ }
2474
+ },
2475
+ "node_modules/rc-upload": {
2476
+ "version": "4.11.0",
2477
+ "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.11.0.tgz",
2478
+ "integrity": "sha512-ZUyT//2JAehfHzjWowqROcwYJKnZkIUGWaTE/VogVrepSl7AFNbQf4+zGfX4zl9Vrj/Jm8scLO0R6UlPDKK4wA==",
2479
+ "license": "MIT",
2480
+ "dependencies": {
2481
+ "@babel/runtime": "^7.18.3",
2482
+ "classnames": "^2.2.5",
2483
+ "rc-util": "^5.2.0"
2484
+ },
2485
+ "peerDependencies": {
2486
+ "react": ">=16.9.0",
2487
+ "react-dom": ">=16.9.0"
2488
+ }
2489
+ },
2490
+ "node_modules/rc-util": {
2491
+ "version": "5.44.4",
2492
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.4.tgz",
2493
+ "integrity": "sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==",
2494
+ "license": "MIT",
2495
+ "dependencies": {
2496
+ "@babel/runtime": "^7.18.3",
2497
+ "react-is": "^18.2.0"
2498
+ },
2499
+ "peerDependencies": {
2500
+ "react": ">=16.9.0",
2501
+ "react-dom": ">=16.9.0"
2502
+ }
2503
+ },
2504
+ "node_modules/rc-virtual-list": {
2505
+ "version": "3.19.2",
2506
+ "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.19.2.tgz",
2507
+ "integrity": "sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==",
2508
+ "license": "MIT",
2509
+ "dependencies": {
2510
+ "@babel/runtime": "^7.20.0",
2511
+ "classnames": "^2.2.6",
2512
+ "rc-resize-observer": "^1.0.0",
2513
+ "rc-util": "^5.36.0"
2514
+ },
2515
+ "engines": {
2516
+ "node": ">=8.x"
2517
+ },
2518
+ "peerDependencies": {
2519
+ "react": ">=16.9.0",
2520
+ "react-dom": ">=16.9.0"
2521
+ }
2522
+ },
2523
+ "node_modules/react": {
2524
+ "version": "19.2.4",
2525
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
2526
+ "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
2527
+ "license": "MIT",
2528
+ "peer": true,
2529
+ "engines": {
2530
+ "node": ">=0.10.0"
2531
+ }
2532
+ },
2533
+ "node_modules/react-dom": {
2534
+ "version": "19.2.4",
2535
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
2536
+ "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
2537
+ "license": "MIT",
2538
+ "peer": true,
2539
+ "dependencies": {
2540
+ "scheduler": "^0.27.0"
2541
+ },
2542
+ "peerDependencies": {
2543
+ "react": "^19.2.4"
2544
+ }
2545
+ },
2546
+ "node_modules/react-is": {
2547
+ "version": "18.3.1",
2548
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
2549
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
2550
+ "license": "MIT"
2551
+ },
2552
+ "node_modules/react-refresh": {
2553
+ "version": "0.18.0",
2554
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
2555
+ "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
2556
+ "dev": true,
2557
+ "license": "MIT",
2558
+ "engines": {
2559
+ "node": ">=0.10.0"
2560
+ }
2561
+ },
2562
+ "node_modules/resize-observer-polyfill": {
2563
+ "version": "1.5.1",
2564
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
2565
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
2566
+ "license": "MIT"
2567
+ },
2568
+ "node_modules/rollup": {
2569
+ "version": "4.57.1",
2570
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz",
2571
+ "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==",
2572
+ "dev": true,
2573
+ "license": "MIT",
2574
+ "dependencies": {
2575
+ "@types/estree": "1.0.8"
2576
+ },
2577
+ "bin": {
2578
+ "rollup": "dist/bin/rollup"
2579
+ },
2580
+ "engines": {
2581
+ "node": ">=18.0.0",
2582
+ "npm": ">=8.0.0"
2583
+ },
2584
+ "optionalDependencies": {
2585
+ "@rollup/rollup-android-arm-eabi": "4.57.1",
2586
+ "@rollup/rollup-android-arm64": "4.57.1",
2587
+ "@rollup/rollup-darwin-arm64": "4.57.1",
2588
+ "@rollup/rollup-darwin-x64": "4.57.1",
2589
+ "@rollup/rollup-freebsd-arm64": "4.57.1",
2590
+ "@rollup/rollup-freebsd-x64": "4.57.1",
2591
+ "@rollup/rollup-linux-arm-gnueabihf": "4.57.1",
2592
+ "@rollup/rollup-linux-arm-musleabihf": "4.57.1",
2593
+ "@rollup/rollup-linux-arm64-gnu": "4.57.1",
2594
+ "@rollup/rollup-linux-arm64-musl": "4.57.1",
2595
+ "@rollup/rollup-linux-loong64-gnu": "4.57.1",
2596
+ "@rollup/rollup-linux-loong64-musl": "4.57.1",
2597
+ "@rollup/rollup-linux-ppc64-gnu": "4.57.1",
2598
+ "@rollup/rollup-linux-ppc64-musl": "4.57.1",
2599
+ "@rollup/rollup-linux-riscv64-gnu": "4.57.1",
2600
+ "@rollup/rollup-linux-riscv64-musl": "4.57.1",
2601
+ "@rollup/rollup-linux-s390x-gnu": "4.57.1",
2602
+ "@rollup/rollup-linux-x64-gnu": "4.57.1",
2603
+ "@rollup/rollup-linux-x64-musl": "4.57.1",
2604
+ "@rollup/rollup-openbsd-x64": "4.57.1",
2605
+ "@rollup/rollup-openharmony-arm64": "4.57.1",
2606
+ "@rollup/rollup-win32-arm64-msvc": "4.57.1",
2607
+ "@rollup/rollup-win32-ia32-msvc": "4.57.1",
2608
+ "@rollup/rollup-win32-x64-gnu": "4.57.1",
2609
+ "@rollup/rollup-win32-x64-msvc": "4.57.1",
2610
+ "fsevents": "~2.3.2"
2611
+ }
2612
+ },
2613
+ "node_modules/scheduler": {
2614
+ "version": "0.27.0",
2615
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
2616
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
2617
+ "license": "MIT"
2618
+ },
2619
+ "node_modules/scroll-into-view-if-needed": {
2620
+ "version": "3.1.0",
2621
+ "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
2622
+ "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==",
2623
+ "license": "MIT",
2624
+ "dependencies": {
2625
+ "compute-scroll-into-view": "^3.0.2"
2626
+ }
2627
+ },
2628
+ "node_modules/semver": {
2629
+ "version": "6.3.1",
2630
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
2631
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
2632
+ "dev": true,
2633
+ "license": "ISC",
2634
+ "bin": {
2635
+ "semver": "bin/semver.js"
2636
+ }
2637
+ },
2638
+ "node_modules/source-map-js": {
2639
+ "version": "1.2.1",
2640
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
2641
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
2642
+ "dev": true,
2643
+ "license": "BSD-3-Clause",
2644
+ "engines": {
2645
+ "node": ">=0.10.0"
2646
+ }
2647
+ },
2648
+ "node_modules/string-convert": {
2649
+ "version": "0.2.1",
2650
+ "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
2651
+ "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==",
2652
+ "license": "MIT"
2653
+ },
2654
+ "node_modules/stylis": {
2655
+ "version": "4.3.6",
2656
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
2657
+ "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==",
2658
+ "license": "MIT"
2659
+ },
2660
+ "node_modules/throttle-debounce": {
2661
+ "version": "5.0.2",
2662
+ "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
2663
+ "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
2664
+ "license": "MIT",
2665
+ "engines": {
2666
+ "node": ">=12.22"
2667
+ }
2668
+ },
2669
+ "node_modules/tinyglobby": {
2670
+ "version": "0.2.15",
2671
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
2672
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
2673
+ "dev": true,
2674
+ "license": "MIT",
2675
+ "dependencies": {
2676
+ "fdir": "^6.5.0",
2677
+ "picomatch": "^4.0.3"
2678
+ },
2679
+ "engines": {
2680
+ "node": ">=12.0.0"
2681
+ },
2682
+ "funding": {
2683
+ "url": "https://github.com/sponsors/SuperchupuDev"
2684
+ }
2685
+ },
2686
+ "node_modules/toggle-selection": {
2687
+ "version": "1.0.6",
2688
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
2689
+ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
2690
+ "license": "MIT"
2691
+ },
2692
+ "node_modules/update-browserslist-db": {
2693
+ "version": "1.2.3",
2694
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
2695
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
2696
+ "dev": true,
2697
+ "funding": [
2698
+ {
2699
+ "type": "opencollective",
2700
+ "url": "https://opencollective.com/browserslist"
2701
+ },
2702
+ {
2703
+ "type": "tidelift",
2704
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
2705
+ },
2706
+ {
2707
+ "type": "github",
2708
+ "url": "https://github.com/sponsors/ai"
2709
+ }
2710
+ ],
2711
+ "license": "MIT",
2712
+ "dependencies": {
2713
+ "escalade": "^3.2.0",
2714
+ "picocolors": "^1.1.1"
2715
+ },
2716
+ "bin": {
2717
+ "update-browserslist-db": "cli.js"
2718
+ },
2719
+ "peerDependencies": {
2720
+ "browserslist": ">= 4.21.0"
2721
+ }
2722
+ },
2723
+ "node_modules/vite": {
2724
+ "version": "7.3.1",
2725
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
2726
+ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
2727
+ "dev": true,
2728
+ "license": "MIT",
2729
+ "peer": true,
2730
+ "dependencies": {
2731
+ "esbuild": "^0.27.0",
2732
+ "fdir": "^6.5.0",
2733
+ "picomatch": "^4.0.3",
2734
+ "postcss": "^8.5.6",
2735
+ "rollup": "^4.43.0",
2736
+ "tinyglobby": "^0.2.15"
2737
+ },
2738
+ "bin": {
2739
+ "vite": "bin/vite.js"
2740
+ },
2741
+ "engines": {
2742
+ "node": "^20.19.0 || >=22.12.0"
2743
+ },
2744
+ "funding": {
2745
+ "url": "https://github.com/vitejs/vite?sponsor=1"
2746
+ },
2747
+ "optionalDependencies": {
2748
+ "fsevents": "~2.3.3"
2749
+ },
2750
+ "peerDependencies": {
2751
+ "@types/node": "^20.19.0 || >=22.12.0",
2752
+ "jiti": ">=1.21.0",
2753
+ "less": "^4.0.0",
2754
+ "lightningcss": "^1.21.0",
2755
+ "sass": "^1.70.0",
2756
+ "sass-embedded": "^1.70.0",
2757
+ "stylus": ">=0.54.8",
2758
+ "sugarss": "^5.0.0",
2759
+ "terser": "^5.16.0",
2760
+ "tsx": "^4.8.1",
2761
+ "yaml": "^2.4.2"
2762
+ },
2763
+ "peerDependenciesMeta": {
2764
+ "@types/node": {
2765
+ "optional": true
2766
+ },
2767
+ "jiti": {
2768
+ "optional": true
2769
+ },
2770
+ "less": {
2771
+ "optional": true
2772
+ },
2773
+ "lightningcss": {
2774
+ "optional": true
2775
+ },
2776
+ "sass": {
2777
+ "optional": true
2778
+ },
2779
+ "sass-embedded": {
2780
+ "optional": true
2781
+ },
2782
+ "stylus": {
2783
+ "optional": true
2784
+ },
2785
+ "sugarss": {
2786
+ "optional": true
2787
+ },
2788
+ "terser": {
2789
+ "optional": true
2790
+ },
2791
+ "tsx": {
2792
+ "optional": true
2793
+ },
2794
+ "yaml": {
2795
+ "optional": true
2796
+ }
2797
+ }
2798
+ },
2799
+ "node_modules/yallist": {
2800
+ "version": "3.1.1",
2801
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
2802
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
2803
+ "dev": true,
2804
+ "license": "ISC"
2805
+ }
2806
+ }
2807
+ }
frontend/package.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "fastfileviewer-frontend",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "antd": "^5.28.0",
13
+ "react": "^19.1.1",
14
+ "react-dom": "^19.1.1"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-react": "^5.0.2",
18
+ "vite": "^7.1.5"
19
+ }
20
+ }
frontend/src/api/client.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const TOKEN_KEY = "ffv_token";
2
+
3
+ export function setToken(token) {
4
+ localStorage.setItem(TOKEN_KEY, token);
5
+ }
6
+
7
+ export function getToken() {
8
+ return localStorage.getItem(TOKEN_KEY) || "";
9
+ }
10
+
11
+ export function clearToken() {
12
+ localStorage.removeItem(TOKEN_KEY);
13
+ }
14
+
15
+ export async function api(path, options = {}) {
16
+ const token = getToken();
17
+ const headers = {
18
+ ...(options.headers || {}),
19
+ };
20
+ if (!(options.body instanceof FormData)) {
21
+ headers["Content-Type"] = "application/json";
22
+ }
23
+ if (token) {
24
+ headers.Authorization = `Bearer ${token}`;
25
+ }
26
+ const res = await fetch(path, { ...options, headers });
27
+ if (!res.ok) {
28
+ const text = await res.text();
29
+ throw new Error(text || `HTTP ${res.status}`);
30
+ }
31
+ return res.json();
32
+ }
frontend/src/main.jsx ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import "antd/dist/reset.css";
4
+ import "./styles.css";
5
+ import { App } from "./pages/App.jsx";
6
+
7
+ createRoot(document.getElementById("root")).render(
8
+ <React.StrictMode>
9
+ <App />
10
+ </React.StrictMode>
11
+ );
frontend/src/pages/App.jsx ADDED
@@ -0,0 +1,355 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import {
3
+ App as AntdApp,
4
+ Button,
5
+ Form,
6
+ Input,
7
+ Layout,
8
+ Modal,
9
+ Progress,
10
+ Space,
11
+ Table,
12
+ Tabs,
13
+ Tag,
14
+ Typography,
15
+ Upload,
16
+ } from "antd";
17
+ import { api, clearToken, getToken, setToken } from "../api/client";
18
+
19
+ const { Header, Content } = Layout;
20
+ const { Text } = Typography;
21
+
22
+ const taskColor = {
23
+ queued: "default",
24
+ running: "processing",
25
+ success: "success",
26
+ failed: "error",
27
+ };
28
+
29
+ export function App() {
30
+ const [token, setTokenState] = useState(getToken());
31
+ const [pwd, setPwd] = useState("");
32
+ const [currentPath, setCurrentPath] = useState(".");
33
+ const [entries, setEntries] = useState([]);
34
+ const [tasks, setTasks] = useState([]);
35
+ const [loading, setLoading] = useState(false);
36
+ const [downloadOpen, setDownloadOpen] = useState(false);
37
+ const [extractOpen, setExtractOpen] = useState(false);
38
+ const [apiMsg, contextHolder] = AntdApp.useApp();
39
+
40
+ async function loadFiles(path = currentPath) {
41
+ setLoading(true);
42
+ try {
43
+ const data = await api(`/api/fs/list?path=${encodeURIComponent(path)}`);
44
+ setEntries(data.entries || []);
45
+ setCurrentPath(path);
46
+ } catch (err) {
47
+ apiMsg.error(String(err.message || err));
48
+ } finally {
49
+ setLoading(false);
50
+ }
51
+ }
52
+
53
+ async function loadTasks() {
54
+ try {
55
+ const data = await api("/api/tasks?limit=100");
56
+ setTasks(data.tasks || []);
57
+ } catch (err) {
58
+ if (String(err.message || "").includes("401")) {
59
+ clearToken();
60
+ setTokenState("");
61
+ }
62
+ }
63
+ }
64
+
65
+ useEffect(() => {
66
+ if (!token) return;
67
+ loadFiles(".");
68
+ loadTasks();
69
+ const timer = setInterval(loadTasks, 2000);
70
+ return () => clearInterval(timer);
71
+ }, [token]);
72
+
73
+ const columns = useMemo(
74
+ () => [
75
+ {
76
+ title: "Name",
77
+ dataIndex: "name",
78
+ render: (_, row) =>
79
+ row.isDir ? (
80
+ <a onClick={() => loadFiles(row.path)}>{row.name}</a>
81
+ ) : (
82
+ <span>{row.name}</span>
83
+ ),
84
+ },
85
+ {
86
+ title: "Type",
87
+ dataIndex: "isDir",
88
+ render: (v) => (v ? "Directory" : "File"),
89
+ },
90
+ {
91
+ title: "Size",
92
+ dataIndex: "size",
93
+ },
94
+ {
95
+ title: "Action",
96
+ render: (_, row) => (
97
+ <Space>
98
+ <Button
99
+ danger
100
+ size="small"
101
+ onClick={async () => {
102
+ await api("/api/fs/delete", {
103
+ method: "POST",
104
+ body: JSON.stringify({ path: row.path }),
105
+ });
106
+ apiMsg.success("Deleted");
107
+ loadFiles(currentPath);
108
+ }}
109
+ >
110
+ Delete
111
+ </Button>
112
+ {!row.isDir && (
113
+ <Button
114
+ size="small"
115
+ onClick={() =>
116
+ window.open(
117
+ `/api/fs/download?path=${encodeURIComponent(row.path)}`,
118
+ "_blank"
119
+ )
120
+ }
121
+ >
122
+ Download
123
+ </Button>
124
+ )}
125
+ </Space>
126
+ ),
127
+ },
128
+ ],
129
+ [currentPath]
130
+ );
131
+
132
+ if (!token) {
133
+ return (
134
+ <AntdApp>
135
+ {contextHolder}
136
+ <div className="center-card">
137
+ <h2>FastFileViewer Login</h2>
138
+ <Space.Compact style={{ width: "100%" }}>
139
+ <Input.Password
140
+ placeholder="Admin password"
141
+ value={pwd}
142
+ onChange={(e) => setPwd(e.target.value)}
143
+ onPressEnter={async () => {
144
+ try {
145
+ const data = await api("/api/login", {
146
+ method: "POST",
147
+ body: JSON.stringify({ password: pwd }),
148
+ });
149
+ setToken(data.token);
150
+ setTokenState(data.token);
151
+ setPwd("");
152
+ } catch (err) {
153
+ apiMsg.error("Login failed");
154
+ }
155
+ }}
156
+ />
157
+ <Button
158
+ type="primary"
159
+ onClick={async () => {
160
+ try {
161
+ const data = await api("/api/login", {
162
+ method: "POST",
163
+ body: JSON.stringify({ password: pwd }),
164
+ });
165
+ setToken(data.token);
166
+ setTokenState(data.token);
167
+ setPwd("");
168
+ } catch (err) {
169
+ apiMsg.error("Login failed");
170
+ }
171
+ }}
172
+ >
173
+ Login
174
+ </Button>
175
+ </Space.Compact>
176
+ </div>
177
+ </AntdApp>
178
+ );
179
+ }
180
+
181
+ return (
182
+ <AntdApp>
183
+ {contextHolder}
184
+ <Layout style={{ minHeight: "100vh" }}>
185
+ <Header className="header">
186
+ <Text strong style={{ color: "#fff" }}>
187
+ FastFileViewer
188
+ </Text>
189
+ <Button
190
+ onClick={() => {
191
+ clearToken();
192
+ setTokenState("");
193
+ }}
194
+ >
195
+ Logout
196
+ </Button>
197
+ </Header>
198
+ <Content className="content">
199
+ <Tabs
200
+ items={[
201
+ {
202
+ key: "files",
203
+ label: "Files",
204
+ children: (
205
+ <>
206
+ <Space style={{ marginBottom: 12 }}>
207
+ <Text>Current: {currentPath}</Text>
208
+ <Button onClick={() => loadFiles(".")}>Root</Button>
209
+ <Button onClick={() => loadFiles(currentPath)}>Refresh</Button>
210
+ <Button onClick={() => setDownloadOpen(true)}>
211
+ URL Download
212
+ </Button>
213
+ <Button onClick={() => setExtractOpen(true)}>Extract</Button>
214
+ <Upload
215
+ showUploadList={false}
216
+ customRequest={async ({ file, onSuccess, onError }) => {
217
+ try {
218
+ const form = new FormData();
219
+ form.append("dir", currentPath);
220
+ form.append("file", file);
221
+ await api("/api/fs/upload", {
222
+ method: "POST",
223
+ body: form,
224
+ });
225
+ onSuccess?.("ok");
226
+ loadFiles(currentPath);
227
+ } catch (err) {
228
+ onError?.(err);
229
+ }
230
+ }}
231
+ >
232
+ <Button>Upload</Button>
233
+ </Upload>
234
+ </Space>
235
+ <Table
236
+ rowKey={(row) => row.path}
237
+ columns={columns}
238
+ dataSource={entries}
239
+ loading={loading}
240
+ pagination={false}
241
+ />
242
+ </>
243
+ ),
244
+ },
245
+ {
246
+ key: "tasks",
247
+ label: "Tasks",
248
+ children: (
249
+ <Table
250
+ rowKey={(row) => row.id}
251
+ dataSource={tasks}
252
+ pagination={false}
253
+ columns={[
254
+ { title: "ID", dataIndex: "id" },
255
+ { title: "Type", dataIndex: "type" },
256
+ {
257
+ title: "Status",
258
+ dataIndex: "status",
259
+ render: (v) => <Tag color={taskColor[v]}>{v}</Tag>,
260
+ },
261
+ {
262
+ title: "Progress",
263
+ dataIndex: "progress",
264
+ render: (v) => <Progress percent={v} size="small" />,
265
+ },
266
+ { title: "Source", dataIndex: "source" },
267
+ { title: "Target", dataIndex: "targetPath" },
268
+ { title: "Error", dataIndex: "error" },
269
+ ]}
270
+ />
271
+ ),
272
+ },
273
+ ]}
274
+ />
275
+ </Content>
276
+ </Layout>
277
+
278
+ <Modal
279
+ open={downloadOpen}
280
+ title="Create Download Task"
281
+ onCancel={() => setDownloadOpen(false)}
282
+ footer={null}
283
+ >
284
+ <Form
285
+ layout="vertical"
286
+ onFinish={async (values) => {
287
+ await api("/api/tasks/download", {
288
+ method: "POST",
289
+ body: JSON.stringify(values),
290
+ });
291
+ setDownloadOpen(false);
292
+ loadTasks();
293
+ }}
294
+ >
295
+ <Form.Item
296
+ label="URL"
297
+ name="url"
298
+ rules={[{ required: true, message: "Please input URL" }]}
299
+ >
300
+ <Input placeholder="https://example.com/file.zip" />
301
+ </Form.Item>
302
+ <Form.Item
303
+ label="Target Path"
304
+ name="targetPath"
305
+ initialValue={`${currentPath}/download.bin`}
306
+ rules={[{ required: true, message: "Please input target path" }]}
307
+ >
308
+ <Input />
309
+ </Form.Item>
310
+ <Button type="primary" htmlType="submit">
311
+ Submit
312
+ </Button>
313
+ </Form>
314
+ </Modal>
315
+
316
+ <Modal
317
+ open={extractOpen}
318
+ title="Create Extract Task"
319
+ onCancel={() => setExtractOpen(false)}
320
+ footer={null}
321
+ >
322
+ <Form
323
+ layout="vertical"
324
+ onFinish={async (values) => {
325
+ await api("/api/tasks/extract", {
326
+ method: "POST",
327
+ body: JSON.stringify(values),
328
+ });
329
+ setExtractOpen(false);
330
+ loadTasks();
331
+ }}
332
+ >
333
+ <Form.Item
334
+ label="Archive Path"
335
+ name="sourcePath"
336
+ rules={[{ required: true, message: "Please input archive path" }]}
337
+ >
338
+ <Input placeholder="path/to/file.zip" />
339
+ </Form.Item>
340
+ <Form.Item
341
+ label="Target Dir"
342
+ name="targetPath"
343
+ initialValue={currentPath}
344
+ rules={[{ required: true, message: "Please input target dir" }]}
345
+ >
346
+ <Input />
347
+ </Form.Item>
348
+ <Button type="primary" htmlType="submit">
349
+ Submit
350
+ </Button>
351
+ </Form>
352
+ </Modal>
353
+ </AntdApp>
354
+ );
355
+ }
frontend/src/styles.css ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ background: linear-gradient(120deg, #f4f8fb 0%, #e9eef5 100%);
4
+ font-family: "Segoe UI", "Noto Sans", sans-serif;
5
+ }
6
+
7
+ .center-card {
8
+ max-width: 420px;
9
+ margin: 12vh auto;
10
+ background: #fff;
11
+ border-radius: 12px;
12
+ padding: 24px;
13
+ box-shadow: 0 10px 30px rgba(19, 36, 61, 0.12);
14
+ }
15
+
16
+ .header {
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ background: #113049;
21
+ }
22
+
23
+ .content {
24
+ max-width: 1200px;
25
+ width: calc(100% - 32px);
26
+ margin: 16px auto;
27
+ padding: 16px;
28
+ background: rgba(255, 255, 255, 0.92);
29
+ border-radius: 12px;
30
+ }
frontend/vite.config.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ proxy: {
8
+ "/api": "http://localhost:7860",
9
+ },
10
+ },
11
+ });