diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..486db5a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,33 @@ +# Git +.git +.gitignore +.codegraph + +# Reference repo +ref/ + +# Docs (not needed in image) +docs/ +*.md +!frontend/README.md + +# Test fixtures +fixture/ +*_test.go + +# Runtime data +data/*.db +data/*.db-shm +data/*.db-wal + +# IDE +.vscode +.idea +*.swp + +# Build artifacts +sub-store +*.exe + +# Node modules (will be installed fresh in Docker) +frontend/node_modules diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..61a9f23 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,63 @@ +name: Build and Publish Docker Image + +on: + push: + branches: [main, master] + tags: ['v*'] + pull_request: + branches: [main, master] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix=sha- + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64,linux/arm64 diff --git a/.gitignore b/.gitignore index ac9e500..8ff01f6 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,11 @@ go.work.sum # === Logs === *.log + +# === Docker === +# Don't commit runtime Docker volumes +docker-data/ + +# === Frontend === +# node_modules already excluded above; keep dist tracked for embed +frontend/node_modules/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5631208 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# ─── Stage 1: Build backend ─── +FROM golang:1.26-alpine AS backend-builder +RUN apk add --no-cache git ca-certificates +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /sub-store . + +# ─── Stage 2: Runtime ─── +FROM alpine:3.21 +RUN apk add --no-cache ca-certificates tzdata +WORKDIR /app +COPY --from=backend-builder /sub-store /app/sub-store +COPY config/config.example.yaml /app/config/config.example.yaml + +RUN mkdir -p /app/data + +ENV TZ=Asia/Shanghai +ENV SUB_STORE_CONFIG=/app/config/config.yaml + +EXPOSE 3000 + +ENTRYPOINT ["/app/sub-store"] +CMD ["serve", "-c", "/app/config/config.yaml"] diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..12c3be8 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,90 @@ +# Sub-Store 前端 + +独立可运行的可视化管理页面,基于 Vue 3 + Vite + Tailwind CSS。 + +## 安全机制 + +页面必须通过 `?token=xxx` 参数打开。Token 会与后端 `/api/env` 接口验证: +- **无 token** → 显示 404 页面(防检测) +- **错误 token** → 显示 404 页面 +- **正确 token** → 进入管理后台,token 自动从 URL 中移除并存储到 localStorage + +## 独立部署 + +### 构建 + +```bash +npm install +npm run build +``` + +构建产物在 `dist/` 目录,包含 4 个文件: +- `index.html` — 入口 HTML +- `config.js` — 运行时配置(可编辑,无需重新构建) +- `assets/index-xxx.js` — 应用 JS +- `assets/index-xxx.css` — 样式 CSS + +### 部署方式 + +**方式一:同源部署(推荐)** + +将 `dist/` 内容放在后端服务器的静态文件目录下,配置后端同时提供 API 和静态文件。 + +**方式二:独立部署 + 反向代理** + +前端部署在 Nginx,通过反向代理转发 `/api` 到后端: + +```nginx +server { + listen 80; + root /path/to/dist; + + location / { + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_pass http://backend:3001; + } + + location /download { + proxy_pass http://backend:3001; + } +} +``` + +**方式三:完全独立部署** + +编辑 `config.js`,设置后端 API 地址: + +```javascript +window.SUB_STORE_CONFIG = { + apiBaseUrl: 'https://api.example.com', + useBearerAuth: true, +} +``` + +然后部署 `dist/` 到任意静态文件服务器。 + +## 开发 + +```bash +npm run dev # 启动开发服务器 (端口 5173) +npm run build # 生产构建 +npm run preview # 预览生产构建 +``` + +开发模式下,Vite 自动代理 `/api` 和 `/download` 到 `http://localhost:3001`。 + +## 功能页面 + +| 页面 | 路径 | 功能 | +|------|------|------| +| 概览 | `/` | 统计卡片 + 环境信息 + 功能特性 | +| 订阅源 | `/sources` | CRUD + 过滤器编辑 + 预览 + 下载链接 | +| 合集 | `/collections` | CRUD + 源多选 + 模板选择 | +| 模板 | `/templates` | CRUD + JSON 配置编辑 + 内置模板查看 | +| 分享 | `/shares` | 创建 + 启用/禁用 + 删除 + 过期时间 | +| 回收站 | `/recycle-bin` | 恢复 + 彻底删除 | +| 工具 | `/tools` | 代理/规则转换 + 节点信息查询 + 数据导入导出 | +| 设置 | `/settings` | UA/超时/缓存/节点API/主题 | diff --git a/frontend/dist/assets/index-CJWAL95F.css b/frontend/dist/assets/index-CJWAL95F.css new file mode 100644 index 0000000..c8b11c9 --- /dev/null +++ b/frontend/dist/assets/index-CJWAL95F.css @@ -0,0 +1 @@ +*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.right-4{right:1rem}.z-30{z-index:30}.z-50{z-index:50}.z-\[60\]{z-index:60}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-60{margin-left:15rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.max-h-32{max-height:8rem}.max-h-96{max-height:24rem}.max-h-\[85vh\]{max-height:85vh}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-24{width:6rem}.w-28{width:7rem}.w-60{width:15rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-primary-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-primary-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-primary-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-7xl{font-size:4.5rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-primary-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#94a3b8}.fade-enter-active,.fade-leave-active{transition:opacity .2s}.fade-enter-from,.fade-leave-to{opacity:0}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-700:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800\/50:hover{background-color:#1f293780}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-primary-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.disabled\:bg-gray-100:disabled{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}@media(min-width:768px){.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} diff --git a/frontend/dist/assets/index-DuuGFjFx.js b/frontend/dist/assets/index-DuuGFjFx.js new file mode 100644 index 0000000..c940c12 --- /dev/null +++ b/frontend/dist/assets/index-DuuGFjFx.js @@ -0,0 +1,37 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** +* @vue/shared v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Kr(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const _e={},gn=[],Et=()=>{},Yi=()=>!1,Fs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Vs=e=>e.startsWith("onUpdate:"),Ie=Object.assign,Wr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},au=Object.prototype.hasOwnProperty,me=(e,t)=>au.call(e,t),Z=Array.isArray,yn=e=>is(e)==="[object Map]",On=e=>is(e)==="[object Set]",To=e=>is(e)==="[object Date]",te=e=>typeof e=="function",Se=e=>typeof e=="string",ct=e=>typeof e=="symbol",ge=e=>e!==null&&typeof e=="object",Zi=e=>(ge(e)||te(e))&&te(e.then)&&te(e.catch),el=Object.prototype.toString,is=e=>el.call(e),uu=e=>is(e).slice(8,-1),tl=e=>is(e)==="[object Object]",Gr=e=>Se(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,jn=Kr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ms=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},cu=/-\w/g,Qe=Ms(e=>e.replace(cu,t=>t.slice(1).toUpperCase())),fu=/\B([A-Z])/g,Gt=Ms(e=>e.replace(fu,"-$1").toLowerCase()),Bs=Ms(e=>e.charAt(0).toUpperCase()+e.slice(1)),nr=Ms(e=>e?`on${Bs(e)}`:""),wt=(e,t)=>!Object.is(e,t),vs=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},js=e=>{const t=parseFloat(e);return isNaN(t)?e:t},du=e=>{const t=Se(e)?Number(e):NaN;return isNaN(t)?e:t};let Oo;const Hs=()=>Oo||(Oo=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function zr(e){if(Z(e)){const t={};for(let n=0;n{if(n){const s=n.split(hu);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Ve(e){let t="";if(Se(e))t=e;else if(Z(e))for(let n=0;nPn(n,t))}const rl=e=>!!(e&&e.__v_isRef===!0),q=e=>Se(e)?e:e==null?"":Z(e)||ge(e)&&(e.toString===el||!te(e.toString))?rl(e)?q(e.value):JSON.stringify(e,ol,2):String(e),ol=(e,t)=>rl(t)?ol(e,t.value):yn(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[sr(s,o)+" =>"]=r,n),{})}:On(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>sr(n))}:ct(t)?sr(t):ge(t)&&!Z(t)&&!tl(t)?String(t):t,sr=(e,t="")=>{var n;return ct(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Le;class il{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&Le&&(Le.active?(this.parent=Le,this.index=(Le.scopes||(Le.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes){const s=this.scopes.slice();for(t=0,n=s.length;t0&&--this._on===0){if(Le===this)Le=this.prevScope;else{let t=Le;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(qn){let t=qn;for(qn=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Hn;){let t=Hn;for(Hn=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function cl(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function fl(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),Yr(s),wu(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function wr(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(dl(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function dl(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===zn)||(e.globalVersion=zn,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!wr(e))))return;e.flags|=2;const t=e.dep,n=Ee,s=ut;Ee=e,ut=!0;try{cl(e);const r=e.fn(e._value);(t.version===0||wt(r,e._value))&&(e.flags|=128,e._value=r,t.version++)}catch(r){throw t.version++,r}finally{Ee=n,ut=s,fl(e),e.flags&=-3}}function Yr(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let o=n.computed.deps;o;o=o.nextDep)Yr(o,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function wu(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let ut=!0;const pl=[];function Lt(){pl.push(ut),ut=!1}function Ut(){const e=pl.pop();ut=e===void 0?!0:e}function Po(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Ee;Ee=void 0;try{t()}finally{Ee=n}}}let zn=0;class Eu{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Zr{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Ee||!ut||Ee===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Ee)n=this.activeLink=new Eu(Ee,this),Ee.deps?(n.prevDep=Ee.depsTail,Ee.depsTail.nextDep=n,Ee.depsTail=n):Ee.deps=Ee.depsTail=n,hl(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=Ee.depsTail,n.nextDep=void 0,Ee.depsTail.nextDep=n,Ee.depsTail=n,Ee.deps===n&&(Ee.deps=s)}return n}trigger(t){this.version++,zn++,this.notify(t)}notify(t){Xr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Qr()}}}function hl(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)hl(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Er=new WeakMap,rn=Symbol(""),Sr=Symbol(""),Jn=Symbol("");function Be(e,t,n){if(ut&&Ee){let s=Er.get(e);s||Er.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new Zr),r.map=s,r.key=n),r.track()}}function Nt(e,t,n,s,r,o){const i=Er.get(e);if(!i){zn++;return}const l=a=>{a&&a.trigger()};if(Xr(),t==="clear")i.forEach(l);else{const a=Z(e),u=a&&Gr(n);if(a&&n==="length"){const c=Number(s);i.forEach((f,d)=>{(d==="length"||d===Jn||!ct(d)&&d>=c)&&l(f)})}else switch((n!==void 0||i.has(void 0))&&l(i.get(n)),u&&l(i.get(Jn)),t){case"add":a?u&&l(i.get("length")):(l(i.get(rn)),yn(e)&&l(i.get(Sr)));break;case"delete":a||(l(i.get(rn)),yn(e)&&l(i.get(Sr)));break;case"set":yn(e)&&l(i.get(rn));break}}Qr()}function dn(e){const t=pe(e);return t===e?t:(Be(t,"iterate",Jn),it(e)?t:t.map(ft))}function qs(e){return Be(e=pe(e),"iterate",Jn),e}function vt(e,t){return Ft(e)?En(on(e)?ft(t):t):ft(t)}const Su={__proto__:null,[Symbol.iterator](){return or(this,Symbol.iterator,e=>vt(this,e))},concat(...e){return dn(this).concat(...e.map(t=>Z(t)?dn(t):t))},entries(){return or(this,"entries",e=>(e[1]=vt(this,e[1]),e))},every(e,t){return Ct(this,"every",e,t,void 0,arguments)},filter(e,t){return Ct(this,"filter",e,t,n=>n.map(s=>vt(this,s)),arguments)},find(e,t){return Ct(this,"find",e,t,n=>vt(this,n),arguments)},findIndex(e,t){return Ct(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ct(this,"findLast",e,t,n=>vt(this,n),arguments)},findLastIndex(e,t){return Ct(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ct(this,"forEach",e,t,void 0,arguments)},includes(...e){return ir(this,"includes",e)},indexOf(...e){return ir(this,"indexOf",e)},join(e){return dn(this).join(e)},lastIndexOf(...e){return ir(this,"lastIndexOf",e)},map(e,t){return Ct(this,"map",e,t,void 0,arguments)},pop(){return Dn(this,"pop")},push(...e){return Dn(this,"push",e)},reduce(e,...t){return No(this,"reduce",e,t)},reduceRight(e,...t){return No(this,"reduceRight",e,t)},shift(){return Dn(this,"shift")},some(e,t){return Ct(this,"some",e,t,void 0,arguments)},splice(...e){return Dn(this,"splice",e)},toReversed(){return dn(this).toReversed()},toSorted(e){return dn(this).toSorted(e)},toSpliced(...e){return dn(this).toSpliced(...e)},unshift(...e){return Dn(this,"unshift",e)},values(){return or(this,"values",e=>vt(this,e))}};function or(e,t,n){const s=qs(e),r=s[t]();return s!==e&&!it(e)&&(r._next=r.next,r.next=()=>{const o=r._next();return o.done||(o.value=n(o.value)),o}),r}const Ru=Array.prototype;function Ct(e,t,n,s,r,o){const i=qs(e),l=i!==e&&!it(e),a=i[t];if(a!==Ru[t]){const f=a.apply(e,o);return l?ft(f):f}let u=n;i!==e&&(l?u=function(f,d){return n.call(this,vt(e,f),d,e)}:n.length>2&&(u=function(f,d){return n.call(this,f,d,e)}));const c=a.call(i,u,s);return l&&r?r(c):c}function No(e,t,n,s){const r=qs(e),o=r!==e&&!it(e);let i=n,l=!1;r!==e&&(o?(l=s.length===0,i=function(u,c,f){return l&&(l=!1,u=vt(e,u)),n.call(this,u,vt(e,c),f,e)}):n.length>3&&(i=function(u,c,f){return n.call(this,u,c,f,e)}));const a=r[t](i,...s);return l?vt(e,a):a}function ir(e,t,n){const s=pe(e);Be(s,"iterate",Jn);const r=s[t](...n);return(r===-1||r===!1)&&no(n[0])?(n[0]=pe(n[0]),s[t](...n)):r}function Dn(e,t,n=[]){Lt(),Xr();const s=pe(e)[t].apply(e,n);return Qr(),Ut(),s}const Cu=Kr("__proto__,__v_isRef,__isVue"),ml=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ct));function Au(e){ct(e)||(e=String(e));const t=pe(this);return Be(t,"has",e),t.hasOwnProperty(e)}class gl{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?Uu:vl:o?xl:bl).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=Z(t);if(!r){let a;if(i&&(a=Su[n]))return a;if(n==="hasOwnProperty")return Au}const l=Reflect.get(t,n,qe(t)?t:s);if((ct(n)?ml.has(n):Cu(n))||(r||Be(t,"get",n),o))return l;if(qe(l)){const a=i&&Gr(n)?l:l.value;return r&&ge(a)?Cr(a):a}return ge(l)?r?Cr(l):zt(l):l}}class yl extends gl{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];const i=Z(t)&&Gr(n);if(!this._isShallow){const u=Ft(o);if(!it(s)&&!Ft(s)&&(o=pe(o),s=pe(s)),!i&&qe(o)&&!qe(s))return u||(o.value=s),!0}const l=i?Number(n)e,hs=e=>Reflect.getPrototypeOf(e);function Iu(e,t,n){return function(...s){const r=this.__v_raw,o=pe(r),i=yn(o),l=e==="entries"||e===Symbol.iterator&&i,a=e==="keys"&&i,u=r[e](...s),c=n?Rr:t?En:ft;return!t&&Be(o,"iterate",a?Sr:rn),Ie(Object.create(u),{next(){const{value:f,done:d}=u.next();return d?{value:f,done:d}:{value:l?[c(f[0]),c(f[1])]:c(f),done:d}}})}}function ms(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function ku(e,t){const n={get(r){const o=this.__v_raw,i=pe(o),l=pe(r);e||(wt(r,l)&&Be(i,"get",r),Be(i,"get",l));const{has:a}=hs(i),u=t?Rr:e?En:ft;if(a.call(i,r))return u(o.get(r));if(a.call(i,l))return u(o.get(l));o!==i&&o.get(r)},get size(){const r=this.__v_raw;return!e&&Be(pe(r),"iterate",rn),r.size},has(r){const o=this.__v_raw,i=pe(o),l=pe(r);return e||(wt(r,l)&&Be(i,"has",r),Be(i,"has",l)),r===l?o.has(r):o.has(r)||o.has(l)},forEach(r,o){const i=this,l=i.__v_raw,a=pe(l),u=t?Rr:e?En:ft;return!e&&Be(a,"iterate",rn),l.forEach((c,f)=>r.call(o,u(c),u(f),i))}};return Ie(n,e?{add:ms("add"),set:ms("set"),delete:ms("delete"),clear:ms("clear")}:{add(r){const o=pe(this),i=hs(o),l=pe(r),a=!t&&!it(r)&&!Ft(r)?l:r;return i.has.call(o,a)||wt(r,a)&&i.has.call(o,r)||wt(l,a)&&i.has.call(o,l)||(o.add(a),Nt(o,"add",a,a)),this},set(r,o){!t&&!it(o)&&!Ft(o)&&(o=pe(o));const i=pe(this),{has:l,get:a}=hs(i);let u=l.call(i,r);u||(r=pe(r),u=l.call(i,r));const c=a.call(i,r);return i.set(r,o),u?wt(o,c)&&Nt(i,"set",r,o):Nt(i,"add",r,o),this},delete(r){const o=pe(this),{has:i,get:l}=hs(o);let a=i.call(o,r);a||(r=pe(r),a=i.call(o,r)),l&&l.call(o,r);const u=o.delete(r);return a&&Nt(o,"delete",r,void 0),u},clear(){const r=pe(this),o=r.size!==0,i=r.clear();return o&&Nt(r,"clear",void 0,void 0),i}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=Iu(r,e,t)}),n}function eo(e,t){const n=ku(e,t);return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(me(n,r)&&r in s?n:s,r,o)}const Du={get:eo(!1,!1)},$u={get:eo(!1,!0)},Lu={get:eo(!0,!1)};const bl=new WeakMap,xl=new WeakMap,vl=new WeakMap,Uu=new WeakMap;function Fu(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function zt(e){return Ft(e)?e:to(e,!1,Ou,Du,bl)}function _l(e){return to(e,!1,Nu,$u,xl)}function Cr(e){return to(e,!0,Pu,Lu,vl)}function to(e,t,n,s,r){if(!ge(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=r.get(e);if(o)return o;const i=Fu(uu(e));if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function on(e){return Ft(e)?on(e.__v_raw):!!(e&&e.__v_isReactive)}function Ft(e){return!!(e&&e.__v_isReadonly)}function it(e){return!!(e&&e.__v_isShallow)}function no(e){return e?!!e.__v_raw:!1}function pe(e){const t=e&&e.__v_raw;return t?pe(t):e}function wl(e){return!me(e,"__v_skip")&&Object.isExtensible(e)&&nl(e,"__v_skip",!0),e}const ft=e=>ge(e)?zt(e):e,En=e=>ge(e)?Cr(e):e;function qe(e){return e?e.__v_isRef===!0:!1}function z(e){return El(e,!1)}function Vu(e){return El(e,!0)}function El(e,t){return qe(e)?e:new Mu(e,t)}class Mu{constructor(t,n){this.dep=new Zr,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:pe(t),this._value=n?t:ft(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||it(t)||Ft(t);t=s?t:pe(t),wt(t,n)&&(this._rawValue=t,this._value=s?t:ft(t),this.dep.trigger())}}function bn(e){return qe(e)?e.value:e}const Bu={get:(e,t,n)=>t==="__v_raw"?e:bn(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return qe(r)&&!qe(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Sl(e){return on(e)?e:new Proxy(e,Bu)}class ju{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Zr(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=zn-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&Ee!==this)return ul(this,!0),!0}get value(){const t=this.dep.track();return dl(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Hu(e,t,n=!1){let s,r;return te(e)?s=e:(s=e.get,r=e.set),new ju(s,r,n)}const gs={},As=new WeakMap;let Zt;function qu(e,t=!1,n=Zt){if(n){let s=As.get(n);s||As.set(n,s=[]),s.push(e)}}function Ku(e,t,n=_e){const{immediate:s,deep:r,once:o,scheduler:i,augmentJob:l,call:a}=n,u=g=>r?g:it(g)||r===!1||r===0?It(g,1):It(g);let c,f,d,m,R=!1,A=!1;if(qe(e)?(f=()=>e.value,R=it(e)):on(e)?(f=()=>u(e),R=!0):Z(e)?(A=!0,R=e.some(g=>on(g)||it(g)),f=()=>e.map(g=>{if(qe(g))return g.value;if(on(g))return u(g);if(te(g))return a?a(g,2):g()})):te(e)?t?f=a?()=>a(e,2):e:f=()=>{if(d){Lt();try{d()}finally{Ut()}}const g=Zt;Zt=c;try{return a?a(e,3,[m]):e(m)}finally{Zt=g}}:f=Et,t&&r){const g=f,x=r===!0?1/0:r;f=()=>It(g(),x)}const O=_u(),E=()=>{c.stop(),O&&O.active&&Wr(O.effects,c)};if(o&&t){const g=t;t=(...x)=>{const I=g(...x);return E(),I}}let w=A?new Array(e.length).fill(gs):gs;const v=g=>{if(!(!(c.flags&1)||!c.dirty&&!g))if(t){const x=c.run();if(g||r||R||(A?x.some((I,C)=>wt(I,w[C])):wt(x,w))){d&&d();const I=Zt;Zt=c;try{const C=[x,w===gs?void 0:A&&w[0]===gs?[]:w,m];w=x,a?a(t,3,C):t(...C)}finally{Zt=I}}}else c.run()};return l&&l(v),c=new ll(f),c.scheduler=i?()=>i(v,!1):v,m=g=>qu(g,!1,c),d=c.onStop=()=>{const g=As.get(c);if(g){if(a)a(g,4);else for(const x of g)x();As.delete(c)}},t?s?v(!0):w=c.run():i?i(v.bind(null,!0),!0):c.run(),E.pause=c.pause.bind(c),E.resume=c.resume.bind(c),E.stop=E,E}function It(e,t=1/0,n){if(t<=0||!ge(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,qe(e))It(e.value,t,n);else if(Z(e))for(let s=0;s{It(s,t,n)});else if(tl(e)){for(const s in e)It(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&It(e[s],t,n)}return e}/** +* @vue/runtime-core v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function ls(e,t,n,s){try{return s?e(...s):e()}catch(r){Ks(r,t,n)}}function at(e,t,n,s){if(te(e)){const r=ls(e,t,n,s);return r&&Zi(r)&&r.catch(o=>{Ks(o,t,n)}),r}if(Z(e)){const r=[];for(let o=0;o>>1,r=Je[s],o=Xn(r);o=Xn(n)?Je.push(e):Je.splice(Gu(t),0,e),e.flags|=1,Cl()}}function Cl(){Ts||(Ts=Rl.then(Tl))}function zu(e){Z(e)?xn.push(...e):Ht&&e.id===-1?Ht.splice(hn+1,0,e):e.flags&1||(xn.push(e),e.flags|=1),Cl()}function Io(e,t,n=xt+1){for(;nXn(n)-Xn(s));if(xn.length=0,Ht){Ht.push(...t);return}for(Ht=t,hn=0;hne.id==null?e.flags&2?-1:1/0:e.id;function Tl(e){try{for(xt=0;xt{s._d&&Is(-1);const o=Os(t),i=Dt.length;let l;try{l=e(...r)}finally{for(let a=Dt.length;a>i;a--)ao();Os(o),s._d&&Is(1)}return l};return s._n=!0,s._c=!0,s._d=!0,s}function se(e,t){if(Fe===null)return e;const n=Xs(Fe),s=e.dirs||(e.dirs=[]);for(let r=0;r1)return n&&te(t)?t.call(s&&s.proxy):t}}const Ju=Symbol.for("v-scx"),Xu=()=>kt(Ju);function ws(e,t,n){return Pl(e,t,n)}function Pl(e,t,n=_e){const{immediate:s,deep:r,flush:o,once:i}=n,l=Ie({},n),a=t&&s||!t&&o!=="post";let u;if(es){if(o==="sync"){const m=Xu();u=m.__watcherHandles||(m.__watcherHandles=[])}else if(!a){const m=()=>{};return m.stop=Et,m.resume=Et,m.pause=Et,m}}const c=He;l.call=(m,R,A)=>at(m,c,R,A);let f=!1;o==="post"?l.scheduler=m=>{Ge(m,c&&c.suspense)}:o!=="sync"&&(f=!0,l.scheduler=(m,R)=>{R?m():ro(m)}),l.augmentJob=m=>{t&&(m.flags|=4),f&&(m.flags|=2,c&&(m.id=c.uid,m.i=c))};const d=Ku(e,t,l);return es&&(u?u.push(d):a&&d()),d}function Qu(e,t,n){const s=this.proxy,r=Se(e)?e.includes(".")?Nl(s,e):()=>s[e]:e.bind(s,s);let o;te(t)?o=t:(o=t.handler,n=t);const i=as(this),l=Pl(r,o.bind(s),n);return i(),l}function Nl(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;re.__isTeleport,en=e=>e&&(e.disabled||e.disabled===""),Yu=e=>e&&(e.defer||e.defer===""),ko=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Do=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Ar=(e,t)=>{const n=e&&e.to;return Se(n)?t?t(n):null:n},Zu={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,o,i,l,a,u){const{mc:c,pc:f,pbc:d,o:{insert:m,querySelector:R,createText:A,createComment:O,parentNode:E}}=u,w=en(t.props);let{dynamicChildren:v}=t;const g=(C,U,k)=>{C.shapeFlag&16&&c(C.children,U,k,r,o,i,l,a)},x=(C=t)=>{const U=en(C.props),k=C.target=Ar(C.props,R),Q=Tr(k,C,A,m);k&&(i!=="svg"&&ko(k)?i="svg":i!=="mathml"&&Do(k)&&(i="mathml"),r&&r.isCE&&(r.ce._teleportTargets||(r.ce._teleportTargets=new Set)).add(k),U||(g(C,k,Q),Vn(C,!1)))},I=C=>{const U=()=>{if(jt.get(C)===U){if(jt.delete(C),en(C.props)){const k=E(C.el)||n;g(C,k,C.anchor),Vn(C,!0)}x(C)}};jt.set(C,U),Ge(U,o)};if(e==null){const C=t.el=A(""),U=t.anchor=A("");if(m(C,n,s),m(U,n,s),Yu(t.props)||o&&o.pendingBranch){I(t);return}w&&(g(t,n,U),Vn(t,!0)),x()}else{t.el=e.el;const C=t.anchor=e.anchor,U=jt.get(e);if(U){U.flags|=8,jt.delete(e),I(t);return}t.targetStart=e.targetStart;const k=t.target=e.target,Q=t.targetAnchor=e.targetAnchor,G=en(e.props),B=G?n:k,oe=G?C:Q;if(i==="svg"||ko(k)?i="svg":(i==="mathml"||Do(k))&&(i="mathml"),v?(d(e.dynamicChildren,v,B,r,o,i,l),lo(e,t,!0)):a||f(e,t,B,oe,r,o,i,l,!1),w)G?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):ys(t,n,C,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const ie=Ar(t.props,R);ie&&(t.target=ie,ys(t,ie,null,u,0))}else G&&ys(t,k,Q,u,1);Vn(t,w)}},remove(e,t,n,{um:s,o:{remove:r}},o){const{shapeFlag:i,children:l,anchor:a,targetStart:u,targetAnchor:c,target:f,props:d}=e,m=en(d),R=o||!m,A=jt.get(e);if(A&&(A.flags|=8,jt.delete(e)),f&&(r(u),r(c)),o&&r(a),!A&&(m||f)&&i&16)for(let O=0;O{e.isMounted=!0}),Hl(()=>{e.isUnmounting=!0}),e}const rt=[Function,Array],$l={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:rt,onEnter:rt,onAfterEnter:rt,onEnterCancelled:rt,onBeforeLeave:rt,onLeave:rt,onAfterLeave:rt,onLeaveCancelled:rt,onBeforeAppear:rt,onAppear:rt,onAfterAppear:rt,onAppearCancelled:rt},Ll=e=>{const t=e.subTree;return t.component?Ll(t.component):t},nc={name:"BaseTransition",props:$l,setup(e,{slots:t}){const n=pa(),s=tc();return()=>{const r=t.default&&Vl(t.default(),!0),o=r&&r.length?Ul(r):n.subTree?ce():void 0;if(!o)return;const i=pe(e),{mode:l}=i;if(s.isLeaving)return lr(o);const a=$o(o);if(!a)return lr(o);let u=Or(a,i,s,n,f=>u=f);a.type!==je&&Qn(a,u);let c=n.subTree&&$o(n.subTree);if(c&&c.type!==je&&!tn(c,a)&&Ll(n).type!==je){let f=Or(c,i,s,n);if(Qn(c,f),l==="out-in"&&a.type!==je)return s.isLeaving=!0,f.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete f.afterLeave,c=void 0},lr(o);l==="in-out"&&a.type!==je?f.delayLeave=(d,m,R)=>{const A=Fl(s,c);A[String(c.key)]=c,d[ot]=()=>{m(),d[ot]=void 0,delete u.delayedLeave,c=void 0},u.delayedLeave=()=>{R(),delete u.delayedLeave,c=void 0}}:c=void 0}else c&&(c=void 0);return o}}};function Ul(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==je){t=n;break}}return t}const sc=nc;function Fl(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Or(e,t,n,s,r){const{appear:o,mode:i,persisted:l=!1,onBeforeEnter:a,onEnter:u,onAfterEnter:c,onEnterCancelled:f,onBeforeLeave:d,onLeave:m,onAfterLeave:R,onLeaveCancelled:A,onBeforeAppear:O,onAppear:E,onAfterAppear:w,onAppearCancelled:v}=t,g=String(e.key),x=Fl(n,e),I=(k,Q)=>{k&&at(k,s,9,Q)},C=(k,Q)=>{const G=Q[1];I(k,Q),Z(k)?k.every(B=>B.length<=1)&&G():k.length<=1&&G()},U={mode:i,persisted:l,beforeEnter(k){let Q=a;if(!n.isMounted)if(o)Q=O||a;else return;k[ot]&&k[ot](!0);const G=x[g];G&&tn(e,G)&&G.el[ot]&&G.el[ot](),I(Q,[k])},enter(k){if(x[g]===e)return;let Q=u,G=c,B=f;if(!n.isMounted)if(o)Q=E||u,G=w||c,B=v||f;else return;let oe=!1;k[$n]=ke=>{oe||(oe=!0,ke?I(B,[k]):I(G,[k]),U.delayedLeave&&U.delayedLeave(),k[$n]=void 0)};const ie=k[$n].bind(null,!1);Q?C(Q,[k,ie]):ie()},leave(k,Q){const G=String(e.key);if(k[$n]&&k[$n](!0),n.isUnmounting)return Q();I(d,[k]);let B=!1;k[ot]=ie=>{B||(B=!0,Q(),ie?I(A,[k]):I(R,[k]),k[ot]=void 0,x[G]===e&&delete x[G])};const oe=k[ot].bind(null,!1);x[G]=e,m?C(m,[k,oe]):oe()},clone(k){const Q=Or(k,t,n,s,r);return r&&r(Q),Q}};return U}function lr(e){if(Ws(e))return e=Wt(e),e.children=null,e}function $o(e){if(!Ws(e))return kl(e.type)&&e.children?Ul(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&te(n.default))return n.default()}}function Qn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Qn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Vl(e,t=!1,n){let s=[],r=0;for(let o=0;o1)for(let o=0;oKn(A,t&&(Z(t)?t[O]:t),n,s,r));return}if(vn(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&Kn(e,t,n,s.component.subTree);return}const o=s.shapeFlag&4?Xs(s.component):s.el,i=r?null:o,{i:l,r:a}=e,u=t&&t.r,c=l.refs===_e?l.refs={}:l.refs,f=l.setupState,d=pe(f),m=f===_e?Yi:A=>Lo(c,A)?!1:me(d,A),R=(A,O)=>!(O&&Lo(c,O));if(u!=null&&u!==a){if(Uo(t),Se(u))c[u]=null,m(u)&&(f[u]=null);else if(qe(u)){const A=t;R(u,A.k)&&(u.value=null),A.k&&(c[A.k]=null)}}if(te(a))ls(a,l,12,[i,c]);else{const A=Se(a),O=qe(a);if(A||O){const E=()=>{if(e.f){const w=A?m(a)?f[a]:c[a]:R()||!e.k?a.value:c[e.k];if(r)Z(w)&&Wr(w,o);else if(Z(w))w.includes(o)||w.push(o);else if(A)c[a]=[o],m(a)&&(f[a]=c[a]);else{const v=[o];R(a,e.k)&&(a.value=v),e.k&&(c[e.k]=v)}}else A?(c[a]=i,m(a)&&(f[a]=i)):O&&(R(a,e.k)&&(a.value=i),e.k&&(c[e.k]=i))};if(i){const w=()=>{E(),Ps.delete(e)};w.id=-1,Ps.set(e,w),Ge(w,n)}else Uo(e),E()}}}function Uo(e){const t=Ps.get(e);t&&(t.flags|=8,Ps.delete(e))}Hs().requestIdleCallback;Hs().cancelIdleCallback;const vn=e=>!!e.type.__asyncLoader,Ws=e=>e.type.__isKeepAlive;function rc(e,t){jl(e,"a",t)}function oc(e,t){jl(e,"da",t)}function jl(e,t,n=He){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Gs(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Ws(r.parent.vnode)&&ic(s,t,n,r),r=r.parent}}function ic(e,t,n,s){const r=Gs(t,e,s,!0);ql(()=>{Wr(s[t],r)},n)}function Gs(e,t,n=He,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{Lt();const l=as(n),a=at(t,n,e,i);return l(),Ut(),a});return s?r.unshift(o):r.push(o),o}}const Vt=e=>(t,n=He)=>{(!es||e==="sp")&&Gs(e,(...s)=>t(...s),n)},lc=Vt("bm"),Rt=Vt("m"),ac=Vt("bu"),uc=Vt("u"),Hl=Vt("bum"),ql=Vt("um"),cc=Vt("sp"),fc=Vt("rtg"),dc=Vt("rtc");function pc(e,t=He){Gs("ec",e,t)}const Kl="components";function Pr(e,t){return Gl(Kl,e,!0,t)||e}const Wl=Symbol.for("v-ndc");function hc(e){return Se(e)?Gl(Kl,e,!1)||e:e||Wl}function Gl(e,t,n=!0,s=!1){const r=Fe||He;if(r){const o=r.type;{const l=Qc(o,!1);if(l&&(l===t||l===Qe(t)||l===Bs(Qe(t))))return o}const i=Fo(r[e]||o[e],t)||Fo(r.appContext[e],t);return!i&&s?o:i}}function Fo(e,t){return e&&(e[t]||e[Qe(t)]||e[Bs(Qe(t))])}function Ne(e,t,n,s){let r;const o=n,i=Z(e);if(i||Se(e)){const l=i&&on(e);let a=!1,u=!1;l&&(a=!it(e),u=Ft(e),e=qs(e)),r=new Array(e.length);for(let c=0,f=e.length;ct(l,a,void 0,o));else{const l=Object.keys(e);r=new Array(l.length);for(let a=0,u=l.length;a0;return t!=="default"&&(u.name=t),D(),an(fe,null,[we("slot",u,s)],c?-2:64)}let i=e[t];i&&i._c&&(i._d=!1);const l=Dt.length;D();let a;try{const u=i&&zl(i(n)),c=n.key||o||u&&u.key;a=an(fe,{key:(c&&!ct(c)?c:`_${t}`)+(!u&&s?"_fb":"")},u||(s?s():[]),u&&e._===1?64:-2)}catch(u){for(let c=Dt.length;c>l;c--)ao();throw u}finally{i&&i._c&&(i._d=!0)}return a.scopeId&&(a.slotScopeIds=[a.scopeId+"-s"]),a}function zl(e){return e.some(t=>Zn(t)?!(t.type===je||t.type===fe&&!zl(t.children)):!0)?e:null}const Nr=e=>e?ha(e)?Xs(e):Nr(e.parent):null,Wn=Ie(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Nr(e.parent),$root:e=>Nr(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Xl(e),$forceUpdate:e=>e.f||(e.f=()=>{ro(e.update)}),$nextTick:e=>e.n||(e.n=so.bind(e.proxy)),$watch:e=>Qu.bind(e)}),ar=(e,t)=>e!==_e&&!e.__isScriptSetup&&me(e,t),mc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:a}=e;if(t[0]!=="$"){const d=i[t];if(d!==void 0)switch(d){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(ar(s,t))return i[t]=1,s[t];if(r!==_e&&me(r,t))return i[t]=2,r[t];if(me(o,t))return i[t]=3,o[t];if(n!==_e&&me(n,t))return i[t]=4,n[t];Ir&&(i[t]=0)}}const u=Wn[t];let c,f;if(u)return t==="$attrs"&&Be(e.attrs,"get",""),u(e);if((c=l.__cssModules)&&(c=c[t]))return c;if(n!==_e&&me(n,t))return i[t]=4,n[t];if(f=a.config.globalProperties,me(f,t))return f[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return ar(r,t)?(r[t]=n,!0):s!==_e&&me(s,t)?(s[t]=n,!0):me(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,props:o,type:i}},l){let a;return!!(n[l]||e!==_e&&l[0]!=="$"&&me(e,l)||ar(t,l)||me(o,l)||me(s,l)||me(Wn,l)||me(r.config.globalProperties,l)||(a=i.__cssModules)&&a[l])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:me(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Mo(e){return Z(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Ir=!0;function gc(e){const t=Xl(e),n=e.proxy,s=e.ctx;Ir=!1,t.beforeCreate&&Bo(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:a,inject:u,created:c,beforeMount:f,mounted:d,beforeUpdate:m,updated:R,activated:A,deactivated:O,beforeDestroy:E,beforeUnmount:w,destroyed:v,unmounted:g,render:x,renderTracked:I,renderTriggered:C,errorCaptured:U,serverPrefetch:k,expose:Q,inheritAttrs:G,components:B,directives:oe,filters:ie}=t;if(u&&yc(u,s,null),i)for(const ae in i){const ue=i[ae];te(ue)&&(s[ae]=ue.bind(n))}if(r){const ae=r.call(n,n);ge(ae)&&(e.data=zt(ae))}if(Ir=!0,o)for(const ae in o){const ue=o[ae],nt=te(ue)?ue.bind(n,n):te(ue.get)?ue.get.bind(n,n):Et,De=!te(ue)&&te(ue.set)?ue.set.bind(n):Et,ye=Xe({get:nt,set:De});Object.defineProperty(s,ae,{enumerable:!0,configurable:!0,get:()=>ye.value,set:Re=>ye.value=Re})}if(l)for(const ae in l)Jl(l[ae],s,n,ae);if(a){const ae=te(a)?a.call(n):a;Reflect.ownKeys(ae).forEach(ue=>{_s(ue,ae[ue])})}c&&Bo(c,e,"c");function xe(ae,ue){Z(ue)?ue.forEach(nt=>ae(nt.bind(n))):ue&&ae(ue.bind(n))}if(xe(lc,f),xe(Rt,d),xe(ac,m),xe(uc,R),xe(rc,A),xe(oc,O),xe(pc,U),xe(dc,I),xe(fc,C),xe(Hl,w),xe(ql,g),xe(cc,k),Z(Q))if(Q.length){const ae=e.exposed||(e.exposed={});Q.forEach(ue=>{Object.defineProperty(ae,ue,{get:()=>n[ue],set:nt=>n[ue]=nt,enumerable:!0})})}else e.exposed||(e.exposed={});x&&e.render===Et&&(e.render=x),G!=null&&(e.inheritAttrs=G),B&&(e.components=B),oe&&(e.directives=oe),k&&Bl(e)}function yc(e,t,n=Et){Z(e)&&(e=kr(e));for(const s in e){const r=e[s];let o;ge(r)?"default"in r?o=kt(r.from||s,r.default,!0):o=kt(r.from||s):o=kt(r),qe(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function Bo(e,t,n){at(Z(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Jl(e,t,n,s){let r=s.includes(".")?Nl(n,s):()=>n[s];if(Se(e)){const o=t[e];te(o)&&ws(r,o)}else if(te(e))ws(r,e.bind(n));else if(ge(e))if(Z(e))e.forEach(o=>Jl(o,t,n,s));else{const o=te(e.handler)?e.handler.bind(n):t[e.handler];te(o)&&ws(r,o,e)}}function Xl(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let a;return l?a=l:!r.length&&!n&&!s?a=t:(a={},r.length&&r.forEach(u=>Ns(a,u,i,!0)),Ns(a,t,i)),ge(t)&&o.set(t,a),a}function Ns(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Ns(e,o,n,!0),r&&r.forEach(i=>Ns(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=bc[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const bc={data:jo,props:Ho,emits:Ho,methods:Mn,computed:Mn,beforeCreate:We,created:We,beforeMount:We,mounted:We,beforeUpdate:We,updated:We,beforeDestroy:We,beforeUnmount:We,destroyed:We,unmounted:We,activated:We,deactivated:We,errorCaptured:We,serverPrefetch:We,components:Mn,directives:Mn,watch:vc,provide:jo,inject:xc};function jo(e,t){return t?e?function(){return Ie(te(e)?e.call(this,this):e,te(t)?t.call(this,this):t)}:t:e}function xc(e,t){return Mn(kr(e),kr(t))}function kr(e){if(Z(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Qe(t)}Modifiers`]||e[`${Gt(t)}Modifiers`];function Sc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||_e;let r=n;const o=t.startsWith("update:"),i=o&&Ec(s,t.slice(7));i&&(i.trim&&(r=n.map(c=>Se(c)?c.trim():c)),i.number&&(r=n.map(js)));let l,a=s[l=nr(t)]||s[l=nr(Qe(t))];!a&&o&&(a=s[l=nr(Gt(t))]),a&&at(a,e,6,r);const u=s[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,at(u,e,6,r)}}const Rc=new WeakMap;function Yl(e,t,n=!1){const s=n?Rc:t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!te(e)){const a=u=>{const c=Yl(u,t,!0);c&&(l=!0,Ie(i,c))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(ge(e)&&s.set(e,null),null):(Z(o)?o.forEach(a=>i[a]=null):Ie(i,o),ge(e)&&s.set(e,i),i)}function zs(e,t){return!e||!Fs(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),me(e,t[0].toLowerCase()+t.slice(1))||me(e,Gt(t))||me(e,t))}function qo(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[o],slots:i,attrs:l,emit:a,render:u,renderCache:c,props:f,data:d,setupState:m,ctx:R,inheritAttrs:A}=e,O=Os(e);let E,w;try{if(n.shapeFlag&4){const g=r||s,x=g;E=_t(u.call(x,g,c,f,m,d,R)),w=l}else{const g=t;E=_t(g.length>1?g(f,{attrs:l,slots:i,emit:a}):g(f,null)),w=t.props?l:Cc(l)}}catch(g){Dt.length=0,Ks(g,e,1),E=we(je)}let v=E;if(w&&A!==!1){const g=Object.keys(w),{shapeFlag:x}=v;g.length&&x&7&&(o&&g.some(Vs)&&(w=Ac(w,o)),v=Wt(v,w,!1,!0))}return n.dirs&&(v=Wt(v,null,!1,!0),v.dirs=v.dirs?v.dirs.concat(n.dirs):n.dirs),n.transition&&Qn(v,n.transition),E=v,Os(O),E}const Cc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Fs(n))&&((t||(t={}))[n]=e[n]);return t},Ac=(e,t)=>{const n={};for(const s in e)(!Vs(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Tc(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:a}=t,u=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return s?Ko(s,i,u):!!i;if(a&8){const c=t.dynamicProps;for(let f=0;fObject.create(ea),na=e=>Object.getPrototypeOf(e)===ea;function Pc(e,t,n,s=!1){const r={},o=ta();e.propsDefaults=Object.create(null),sa(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:_l(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function Nc(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=pe(r),[a]=e.propsOptions;let u=!1;if((s||i>0)&&!(i&16)){if(i&8){const c=e.vnode.dynamicProps;for(let f=0;f{a=!0;const[d,m]=ra(f,t,!0);Ie(i,d),m&&l.push(...m)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!o&&!a)return ge(e)&&s.set(e,gn),gn;if(Z(o))for(let c=0;ce==="_"||e==="_ctx"||e==="$stable",io=e=>Z(e)?e.map(_t):[_t(e)],kc=(e,t,n)=>{if(t._n)return t;const s=lt((...r)=>io(t(...r)),n);return s._c=!1,s},oa=(e,t,n)=>{const s=e._ctx;for(const r in e){if(oo(r))continue;const o=e[r];if(te(o))t[r]=kc(r,o,s);else if(o!=null){const i=io(o);t[r]=()=>i}}},ia=(e,t)=>{const n=io(t);e.slots.default=()=>n},la=(e,t,n)=>{for(const s in t)(n||!oo(s))&&(e[s]=t[s])},Dc=(e,t,n)=>{const s=e.slots=ta();if(e.vnode.shapeFlag&32){const r=t._;r?(la(s,t,n),n&&nl(s,"_",r,!0)):oa(t,s)}else t&&ia(e,t)},$c=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=_e;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:la(r,t,n):(o=!t.$stable,oa(t,r)),i=t}else t&&(ia(e,t),i={default:1});if(o)for(const l in r)!oo(l)&&i[l]==null&&delete r[l]},Ge=Mc;function Lc(e){return Uc(e)}function Uc(e,t){const n=Hs();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:a,setText:u,setElementText:c,parentNode:f,nextSibling:d,setScopeId:m=Et,insertStaticContent:R}=e,A=(h,y,_,P=null,S=null,T=null,M=void 0,F=null,V=!!y.dynamicChildren)=>{if(h===y)return;h&&!tn(h,y)&&(P=N(h),Re(h,S,T,!0),h=null),y.patchFlag===-2&&(V=!1,y.dynamicChildren=null);const{type:$,ref:J,shapeFlag:W}=y;switch($){case Js:O(h,y,_,P);break;case je:E(h,y,_,P);break;case cr:h==null&&w(y,_,P,M);break;case fe:B(h,y,_,P,S,T,M,F,V);break;default:W&1?x(h,y,_,P,S,T,M,F,V):W&6?oe(h,y,_,P,S,T,M,F,V):(W&64||W&128)&&$.process(h,y,_,P,S,T,M,F,V,X)}J!=null&&S?Kn(J,h&&h.ref,T,y||h,!y):J==null&&h&&h.ref!=null&&Kn(h.ref,null,T,h,!0)},O=(h,y,_,P)=>{if(h==null)s(y.el=l(y.children),_,P);else{const S=y.el=h.el;y.children!==h.children&&u(S,y.children)}},E=(h,y,_,P)=>{h==null?s(y.el=a(y.children||""),_,P):y.el=h.el},w=(h,y,_,P)=>{[h.el,h.anchor]=R(h.children,y,_,P,h.el,h.anchor)},v=({el:h,anchor:y},_,P)=>{let S;for(;h&&h!==y;)S=d(h),s(h,_,P),h=S;s(y,_,P)},g=({el:h,anchor:y})=>{let _;for(;h&&h!==y;)_=d(h),r(h),h=_;r(y)},x=(h,y,_,P,S,T,M,F,V)=>{if(y.type==="svg"?M="svg":y.type==="math"&&(M="mathml"),h==null)I(y,_,P,S,T,M,F,V);else{const $=h.el&&h.el._isVueCE?h.el:null;try{$&&$._beginPatch(),k(h,y,S,T,M,F,V)}finally{$&&$._endPatch()}}},I=(h,y,_,P,S,T,M,F)=>{let V,$;const{props:J,shapeFlag:W,transition:Y,dirs:ee}=h;if(V=h.el=i(h.type,T,J&&J.is,J),W&8?c(V,h.children):W&16&&U(h.children,V,null,P,S,ur(h,T),M,F),ee&&Jt(h,null,P,"created"),C(V,h,h.scopeId,M,P),J){for(const ve in J)ve!=="value"&&!jn(ve)&&o(V,ve,null,J[ve],T,P);"value"in J&&o(V,"value",null,J.value,T),($=J.onVnodeBeforeMount)&&bt($,P,h)}ee&&Jt(h,null,P,"beforeMount");const le=Fc(S,Y);le&&Y.beforeEnter(V),s(V,y,_),(($=J&&J.onVnodeMounted)||le||ee)&&Ge(()=>{try{$&&bt($,P,h),le&&Y.enter(V),ee&&Jt(h,null,P,"mounted")}finally{}},S)},C=(h,y,_,P,S)=>{if(_&&m(h,_),P)for(let T=0;T{for(let $=V;${const F=y.el=h.el;let{patchFlag:V,dynamicChildren:$,dirs:J}=y;V|=h.patchFlag&16;const W=h.props||_e,Y=y.props||_e;let ee;if(_&&Xt(_,!1),(ee=Y.onVnodeBeforeUpdate)&&bt(ee,_,y,h),J&&Jt(y,h,_,"beforeUpdate"),_&&Xt(_,!0),$&&(!h.dynamicChildren||h.dynamicChildren.length!==$.length)&&(V=0,M=!1,$=null),(W.innerHTML&&Y.innerHTML==null||W.textContent&&Y.textContent==null)&&c(F,""),$?Q(h.dynamicChildren,$,F,_,P,ur(y,S),T):M||ue(h,y,F,null,_,P,ur(y,S),T,!1),V>0){if(V&16)G(F,W,Y,_,S);else if(V&2&&W.class!==Y.class&&o(F,"class",null,Y.class,S),V&4&&o(F,"style",W.style,Y.style,S),V&8){const le=y.dynamicProps;for(let ve=0;ve{ee&&bt(ee,_,y,h),J&&Jt(y,h,_,"updated")},P)},Q=(h,y,_,P,S,T,M)=>{for(let F=0;F{if(y!==_){if(y!==_e)for(const T in y)!jn(T)&&!(T in _)&&o(h,T,y[T],null,S,P);for(const T in _){if(jn(T))continue;const M=_[T],F=y[T];M!==F&&T!=="value"&&o(h,T,F,M,S,P)}"value"in _&&o(h,"value",y.value,_.value,S)}},B=(h,y,_,P,S,T,M,F,V)=>{const $=y.el=h?h.el:l(""),J=y.anchor=h?h.anchor:l("");let{patchFlag:W,dynamicChildren:Y,slotScopeIds:ee}=y;ee&&(F=F?F.concat(ee):ee),h==null?(s($,_,P),s(J,_,P),U(y.children||[],_,J,S,T,M,F,V)):W>0&&W&64&&Y&&h.dynamicChildren&&h.dynamicChildren.length===Y.length?(Q(h.dynamicChildren,Y,_,S,T,M,F),(y.key!=null||S&&y===S.subTree)&&lo(h,y,!0)):ue(h,y,_,J,S,T,M,F,V)},oe=(h,y,_,P,S,T,M,F,V)=>{y.slotScopeIds=F,h==null?y.shapeFlag&512?S.ctx.activate(y,_,P,M,V):ie(y,_,P,S,T,M,V):ke(h,y,V)},ie=(h,y,_,P,S,T,M)=>{const F=h.component=Wc(h,P,S);if(Ws(h)&&(F.ctx.renderer=X),Gc(F,!1,M),F.asyncDep){if(S&&S.registerDep(F,xe,M),!h.el){const V=F.subTree=we(je);E(null,V,y,_),h.placeholder=V.el}}else xe(F,h,y,_,S,T,M)},ke=(h,y,_)=>{const P=y.component=h.component;if(Tc(h,y,_))if(P.asyncDep&&!P.asyncResolved){ae(P,y,_);return}else P.next=y,P.update();else y.el=h.el,P.vnode=y},xe=(h,y,_,P,S,T,M)=>{const F=()=>{if(h.isMounted){let{next:W,bu:Y,u:ee,parent:le,vnode:ve}=h;{const gt=aa(h);if(gt){W&&(W.el=ve.el,ae(h,W,M)),gt.asyncDep.then(()=>{Ge(()=>{h.isUnmounted||$()},S)});return}}let be=W,Oe;Xt(h,!1),W?(W.el=ve.el,ae(h,W,M)):W=ve,Y&&vs(Y),(Oe=W.props&&W.props.onVnodeBeforeUpdate)&&bt(Oe,le,W,ve),Xt(h,!0);const $e=qo(h),mt=h.subTree;h.subTree=$e,A(mt,$e,f(mt.el),N(mt),h,S,T),W.el=$e.el,be===null&&Oc(h,$e.el),ee&&Ge(ee,S),(Oe=W.props&&W.props.onVnodeUpdated)&&Ge(()=>bt(Oe,le,W,ve),S)}else{let W;const{el:Y,props:ee}=y,{bm:le,m:ve,parent:be,root:Oe,type:$e}=h,mt=vn(y);Xt(h,!1),le&&vs(le),!mt&&(W=ee&&ee.onVnodeBeforeMount)&&bt(W,be,y),Xt(h,!0);{Oe.ce&&Oe.ce._hasShadowRoot()&&Oe.ce._injectChildStyle($e,h.parent?h.parent.type:void 0);const gt=h.subTree=qo(h);A(null,gt,_,P,h,S,T),y.el=gt.el}if(ve&&Ge(ve,S),!mt&&(W=ee&&ee.onVnodeMounted)){const gt=y;Ge(()=>bt(W,be,gt),S)}(y.shapeFlag&256||be&&vn(be.vnode)&&be.vnode.shapeFlag&256)&&h.a&&Ge(h.a,S),h.isMounted=!0,y=_=P=null}};h.scope.on();const V=h.effect=new ll(F);h.scope.off();const $=h.update=V.run.bind(V),J=h.job=V.runIfDirty.bind(V);J.i=h,J.id=h.uid,V.scheduler=()=>ro(J),Xt(h,!0),$()},ae=(h,y,_)=>{y.component=h;const P=h.vnode.props;h.vnode=y,h.next=null,Nc(h,y.props,P,_),$c(h,y.children,_),Lt(),Io(h),Ut()},ue=(h,y,_,P,S,T,M,F,V=!1)=>{const $=h&&h.children,J=h?h.shapeFlag:0,W=y.children,{patchFlag:Y,shapeFlag:ee}=y;if(Y>0){if(Y&128){De($,W,_,P,S,T,M,F,V);return}else if(Y&256){nt($,W,_,P,S,T,M,F,V);return}}ee&8?(J&16&&ne($,S,T),W!==$&&c(_,W)):J&16?ee&16?De($,W,_,P,S,T,M,F,V):ne($,S,T,!0):(J&8&&c(_,""),ee&16&&U(W,_,P,S,T,M,F,V))},nt=(h,y,_,P,S,T,M,F,V)=>{h=h||gn,y=y||gn;const $=h.length,J=y.length,W=Math.min($,J);let Y;for(Y=0;YJ?ne(h,S,T,!0,!1,W):U(y,_,P,S,T,M,F,V,W)},De=(h,y,_,P,S,T,M,F,V)=>{let $=0;const J=y.length;let W=h.length-1,Y=J-1;for(;$<=W&&$<=Y;){const ee=h[$],le=y[$]=V?Pt(y[$]):_t(y[$]);if(tn(ee,le))A(ee,le,_,null,S,T,M,F,V);else break;$++}for(;$<=W&&$<=Y;){const ee=h[W],le=y[Y]=V?Pt(y[Y]):_t(y[Y]);if(tn(ee,le))A(ee,le,_,null,S,T,M,F,V);else break;W--,Y--}if($>W){if($<=Y){const ee=Y+1,le=eeY)for(;$<=W;)Re(h[$],S,T,!0),$++;else{const ee=$,le=$,ve=new Map;for($=le;$<=Y;$++){const et=y[$]=V?Pt(y[$]):_t(y[$]);et.key!=null&&ve.set(et.key,$)}let be,Oe=0;const $e=Y-le+1;let mt=!1,gt=0;const kn=new Array($e);for($=0;$<$e;$++)kn[$]=0;for($=ee;$<=W;$++){const et=h[$];if(Oe>=$e){Re(et,S,T,!0);continue}let yt;if(et.key!=null)yt=ve.get(et.key);else for(be=le;be<=Y;be++)if(kn[be-le]===0&&tn(et,y[be])){yt=be;break}yt===void 0?Re(et,S,T,!0):(kn[yt-le]=$+1,yt>=gt?gt=yt:mt=!0,A(et,y[yt],_,null,S,T,M,F,V),Oe++)}const Ro=mt?Vc(kn):gn;for(be=Ro.length-1,$=$e-1;$>=0;$--){const et=le+$,yt=y[et],Co=y[et+1],Ao=et+1{const{el:T,type:M,transition:F,children:V,shapeFlag:$}=h;if($&6){ye(h.component.subTree,y,_,P);return}if($&128){h.suspense.move(y,_,P);return}if($&64){M.move(h,y,_,X);return}if(M===fe){s(T,y,_);for(let W=0;WF.enter(T),S));else{const{leave:W,delayLeave:Y,afterLeave:ee}=F,le=()=>{h.ctx.isUnmounted?r(T):s(T,y,_)},ve=()=>{const be=T._isLeaving||!!T[ot];T._isLeaving&&T[ot](!0),F.persisted&&!be?le():W(T,()=>{le(),ee&&ee()})};Y?Y(T,le,ve):ve()}else s(T,y,_)},Re=(h,y,_,P=!1,S=!1)=>{const{type:T,props:M,ref:F,children:V,dynamicChildren:$,shapeFlag:J,patchFlag:W,dirs:Y,cacheIndex:ee,memo:le}=h;if(W===-2&&(S=!1),F!=null&&(Lt(),Kn(F,null,_,h,!0),Ut()),ee!=null&&(y.renderCache[ee]=void 0),J&256){y.ctx.deactivate(h);return}const ve=J&1&&Y,be=!vn(h);let Oe;if(be&&(Oe=M&&M.onVnodeBeforeUnmount)&&bt(Oe,y,h),J&6)ht(h.component,_,P);else{if(J&128){h.suspense.unmount(_,P);return}ve&&Jt(h,null,y,"beforeUnmount"),J&64?h.type.remove(h,y,_,X,P):$&&!$.hasOnce&&(T!==fe||W>0&&W&64)?ne($,y,_,!1,!0):(T===fe&&W&384||!S&&J&16)&&ne(V,y,_),P&&Ze(h)}const $e=le!=null&&ee==null;(be&&(Oe=M&&M.onVnodeUnmounted)||ve||$e)&&Ge(()=>{Oe&&bt(Oe,y,h),ve&&Jt(h,null,y,"unmounted"),$e&&(h.el=null)},_)},Ze=h=>{const{type:y,el:_,anchor:P,transition:S}=h;if(y===fe){st(_,P);return}if(y===cr){g(h);return}const T=()=>{r(_),S&&!S.persisted&&S.afterLeave&&S.afterLeave()};if(h.shapeFlag&1&&S&&!S.persisted){const{leave:M,delayLeave:F}=S,V=()=>M(_,T);F?F(h.el,T,V):V()}else T()},st=(h,y)=>{let _;for(;h!==y;)_=d(h),r(h),h=_;r(y)},ht=(h,y,_)=>{const{bum:P,scope:S,job:T,subTree:M,um:F,m:V,a:$}=h;Go(V),Go($),P&&vs(P),S.stop(),T&&(T.flags|=8,Re(M,h,y,_)),F&&Ge(F,y),Ge(()=>{h.isUnmounted=!0},y)},ne=(h,y,_,P=!1,S=!1,T=0)=>{for(let M=T;M{if(h.shapeFlag&6)return N(h.component.subTree);if(h.shapeFlag&128)return h.suspense.next();const y=d(h.anchor||h.el),_=y&&y[Il];return _?d(_):y};let K=!1;const H=(h,y,_)=>{let P;h==null?y._vnode&&(Re(y._vnode,null,null,!0),P=y._vnode.component):A(y._vnode||null,h,y,null,null,null,_),y._vnode=h,K||(K=!0,Io(P),Al(),K=!1)},X={p:A,um:Re,m:ye,r:Ze,mt:ie,mc:U,pc:ue,pbc:Q,n:N,o:e};return{render:H,hydrate:void 0,createApp:wc(H)}}function ur({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Xt({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Fc(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function lo(e,t,n=!1){const s=e.children,r=t.children;if(Z(s)&&Z(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function aa(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:aa(t)}function Go(e){if(e)for(let t=0;te.__isSuspense;function Mc(e,t){t&&t.pendingBranch?Z(e)?t.effects.push(...e):t.effects.push(e):zu(e)}const fe=Symbol.for("v-fgt"),Js=Symbol.for("v-txt"),je=Symbol.for("v-cmt"),cr=Symbol.for("v-stc"),Dt=[];let tt=null;function D(e=!1){Dt.push(tt=e?null:[])}function ao(){Dt.pop(),tt=Dt[Dt.length-1]||null}let Yn=1;function Is(e,t=!1){Yn+=e,e<0&&tt&&t&&(tt.hasOnce=!0)}function fa(e){return e.dynamicChildren=Yn>0?tt||gn:null,ao(),Yn>0&&tt&&tt.push(e),e}function L(e,t,n,s,r,o){return fa(p(e,t,n,s,r,o,!0))}function an(e,t,n,s,r){return fa(we(e,t,n,s,r,!0))}function Zn(e){return e?e.__v_isVNode===!0:!1}function tn(e,t){return e.type===t.type&&e.key===t.key}const da=({key:e})=>e??null,Es=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Se(e)||qe(e)||te(e)?{i:Fe,r:e,k:t,f:!!n}:e:null);function p(e,t=null,n=null,s=0,r=null,o=e===fe?0:1,i=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&da(t),ref:t&&Es(t),scopeId:Ol,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:Fe};return l?(ks(a,n),o&128&&e.normalize(a)):n&&(a.shapeFlag|=Se(n)?8:16),Yn>0&&!i&&tt&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&tt.push(a),a}const we=Bc;function Bc(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===Wl)&&(e=je),Zn(e)){const l=Wt(e,t,!0);return n&&ks(l,n),Yn>0&&!o&&tt&&(l.shapeFlag&6?tt[tt.indexOf(e)]=l:tt.push(l)),l.patchFlag=-2,l}if(Yc(e)&&(e=e.__vccOpts),t){t=jc(t);let{class:l,style:a}=t;l&&!Se(l)&&(t.class=Ve(l)),ge(a)&&(no(a)&&!Z(a)&&(a=Ie({},a)),t.style=zr(a))}const i=Se(e)?1:ca(e)?128:kl(e)?64:ge(e)?4:te(e)?2:0;return p(e,t,n,s,r,i,o,!0)}function jc(e){return e?no(e)||na(e)?Ie({},e):e:null}function Wt(e,t,n=!1,s=!1){const{props:r,ref:o,patchFlag:i,children:l,transition:a}=e,u=t?Hc(r||{},t):r,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&da(u),ref:t&&t.ref?n&&o?Z(o)?o.concat(Es(t)):[o,Es(t)]:Es(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==fe?i===-1?16:i|16:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Wt(e.ssContent),ssFallback:e.ssFallback&&Wt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&s&&Qn(c,a.clone(c)),c}function un(e=" ",t=0){return we(Js,null,e,t)}function ce(e="",t=!1){return t?(D(),an(je,null,e)):we(je,null,e)}function _t(e){return e==null||typeof e=="boolean"?we(je):Z(e)?we(fe,null,e.slice()):Zn(e)?Pt(e):we(Js,null,String(e))}function Pt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Wt(e)}function ks(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(Z(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),ks(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!na(t)?t._ctx=Fe:r===3&&Fe&&(Fe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(te(t)){if(s&65){ks(e,{default:t});return}t={default:t,_ctx:Fe},n=32}else t=String(t),s&64?(n=16,t=[un(t)]):n=8;e.children=t,e.shapeFlag|=n}function Hc(...e){const t={};for(let n=0;nHe||Fe;let Ds,$r;{const e=Hs(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};Ds=t("__VUE_INSTANCE_SETTERS__",n=>He=n),$r=t("__VUE_SSR_SETTERS__",n=>es=n)}const as=e=>{const t=He;return Ds(e),e.scope.on(),()=>{e.scope.off(),Ds(t)}},zo=()=>{He&&He.scope.off(),Ds(null)};function ha(e){return e.vnode.shapeFlag&4}let es=!1;function Gc(e,t=!1,n=!1){t&&$r(t);const{props:s,children:r}=e.vnode,o=ha(e);Pc(e,s,o,t),Dc(e,r,n||t);const i=o?zc(e,t):void 0;return t&&$r(!1),i}function zc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,mc);const{setup:s}=n;if(s){Lt();const r=e.setupContext=s.length>1?Xc(e):null,o=as(e),i=ls(s,e,0,[e.props,r]),l=Zi(i);if(Ut(),o(),(l||e.sp)&&!vn(e)&&Bl(e),l){if(i.then(zo,zo),t)return i.then(a=>{Jo(e,a)}).catch(a=>{Ks(a,e,0)});e.asyncDep=i}else Jo(e,i)}else ma(e)}function Jo(e,t,n){te(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ge(t)&&(e.setupState=Sl(t)),ma(e)}function ma(e,t,n){const s=e.type;e.render||(e.render=s.render||Et);{const r=as(e);Lt();try{gc(e)}finally{Ut(),r()}}}const Jc={get(e,t){return Be(e,"get",""),e[t]}};function Xc(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Jc),slots:e.slots,emit:e.emit,expose:t}}function Xs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Sl(wl(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Wn)return Wn[n](e)},has(t,n){return n in t||n in Wn}})):e.proxy}function Qc(e,t=!0){return te(e)?e.displayName||e.name:e.name||t&&e.__name}function Yc(e){return te(e)&&"__vccOpts"in e}const Xe=(e,t)=>Hu(e,t,es);function uo(e,t,n){try{Is(-1);const s=arguments.length;return s===2?ge(t)&&!Z(t)?Zn(t)?we(e,null,[t]):we(e,t):we(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Zn(n)&&(n=[n]),we(e,t,n))}finally{Is(1)}}const Zc="3.5.40";/** +* @vue/runtime-dom v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Lr;const Xo=typeof window<"u"&&window.trustedTypes;if(Xo)try{Lr=Xo.createPolicy("vue",{createHTML:e=>e})}catch{}const ga=Lr?e=>Lr.createHTML(e):e=>e,ef="http://www.w3.org/2000/svg",tf="http://www.w3.org/1998/Math/MathML",Ot=typeof document<"u"?document:null,Qo=Ot&&Ot.createElement("template"),nf={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Ot.createElementNS(ef,e):t==="mathml"?Ot.createElementNS(tf,e):n?Ot.createElement(e,{is:n}):Ot.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Ot.createTextNode(e),createComment:e=>Ot.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ot.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{Qo.innerHTML=ga(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=Qo.content;if(s==="svg"||s==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Mt="transition",Ln="animation",ts=Symbol("_vtc"),ya={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},sf=Ie({},$l,ya),rf=e=>(e.displayName="Transition",e.props=sf,e),of=rf((e,{slots:t})=>uo(sc,lf(e),t)),Qt=(e,t=[])=>{Z(e)?e.forEach(n=>n(...t)):e&&e(...t)},Yo=e=>e?Z(e)?e.some(t=>t.length>1):e.length>1:!1;function lf(e){const t={};for(const B in e)B in ya||(t[B]=e[B]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=o,appearActiveClass:u=i,appearToClass:c=l,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:d=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,R=af(r),A=R&&R[0],O=R&&R[1],{onBeforeEnter:E,onEnter:w,onEnterCancelled:v,onLeave:g,onLeaveCancelled:x,onBeforeAppear:I=E,onAppear:C=w,onAppearCancelled:U=v}=t,k=(B,oe,ie,ke)=>{B._enterCancelled=ke,Yt(B,oe?c:l),Yt(B,oe?u:i),ie&&ie()},Q=(B,oe)=>{B._isLeaving=!1,Yt(B,f),Yt(B,m),Yt(B,d),oe&&oe()},G=B=>(oe,ie)=>{const ke=B?C:w,xe=()=>k(oe,B,ie);Qt(ke,[oe,xe]),Zo(()=>{Yt(oe,B?a:o),At(oe,B?c:l),Yo(ke)||ei(oe,s,A,xe)})};return Ie(t,{onBeforeEnter(B){Qt(E,[B]),At(B,o),At(B,i)},onBeforeAppear(B){Qt(I,[B]),At(B,a),At(B,u)},onEnter:G(!1),onAppear:G(!0),onLeave(B,oe){B._isLeaving=!0;const ie=()=>Q(B,oe);At(B,f),B._enterCancelled?(At(B,d),si(B)):(si(B),At(B,d)),Zo(()=>{B._isLeaving&&(Yt(B,f),At(B,m),Yo(g)||ei(B,s,O,ie))}),Qt(g,[B,ie])},onEnterCancelled(B){k(B,!1,void 0,!0),Qt(v,[B])},onAppearCancelled(B){k(B,!0,void 0,!0),Qt(U,[B])},onLeaveCancelled(B){Q(B),Qt(x,[B])}})}function af(e){if(e==null)return null;if(ge(e))return[fr(e.enter),fr(e.leave)];{const t=fr(e);return[t,t]}}function fr(e){return du(e)}function At(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[ts]||(e[ts]=new Set)).add(t)}function Yt(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[ts];n&&(n.delete(t),n.size||(e[ts]=void 0))}function Zo(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let uf=0;function ei(e,t,n,s){const r=e._endId=++uf,o=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(o,n);const{type:i,timeout:l,propCount:a}=cf(e,t);if(!i)return s();const u=i+"end";let c=0;const f=()=>{e.removeEventListener(u,d),o()},d=m=>{m.target===e&&++c>=a&&f()};setTimeout(()=>{c(n[R]||"").split(", "),r=s(`${Mt}Delay`),o=s(`${Mt}Duration`),i=ti(r,o),l=s(`${Ln}Delay`),a=s(`${Ln}Duration`),u=ti(l,a);let c=null,f=0,d=0;t===Mt?i>0&&(c=Mt,f=i,d=o.length):t===Ln?u>0&&(c=Ln,f=u,d=a.length):(f=Math.max(i,u),c=f>0?i>u?Mt:Ln:null,d=c?c===Mt?o.length:a.length:0);const m=c===Mt&&/\b(?:transform|all)(?:,|$)/.test(s(`${Mt}Property`).toString());return{type:c,timeout:f,propCount:d,hasTransform:m}}function ti(e,t){for(;e.lengthni(n)+ni(e[s])))}function ni(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function si(e){return(e?e.ownerDocument:document).body.offsetHeight}function ff(e,t,n){const s=e[ts];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const ri=Symbol("_vod"),df=Symbol("_vsh"),pf=Symbol(""),hf=/(?:^|;)\s*display\s*:/;function mf(e,t,n){const s=e.style,r=Se(n);let o=!1;if(n&&!r){if(t)if(Se(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&Bn(s,l,"")}else for(const i in t)n[i]==null&&Bn(s,i,"");for(const i in n){i==="display"&&(o=!0);const l=n[i];l!=null?yf(e,i,!Se(t)&&t?t[i]:void 0,l)||Bn(s,i,l):Bn(s,i,"")}}else if(r){if(t!==n){const i=s[pf];i&&(n+=";"+i),s.cssText=n,o=hf.test(n)}}else t&&e.removeAttribute("style");ri in e&&(e[ri]=o?s.display:"",e[df]&&(s.display="none"))}const oi=/\s*!important$/;function Bn(e,t,n){if(Z(n))n.forEach(s=>Bn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=gf(e,t);oi.test(n)?e.setProperty(Gt(s),n.replace(oi,""),"important"):e[s]=n}}const ii=["Webkit","Moz","ms"],dr={};function gf(e,t){const n=dr[t];if(n)return n;let s=Qe(t);if(s!=="filter"&&s in e)return dr[t]=s;s=Bs(s);for(let r=0;rpr||(Ef.then(()=>pr=0),pr=Date.now());function Rf(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;const r=n.value;if(Z(r)){const o=s.stopImmediatePropagation;s.stopImmediatePropagation=()=>{o.call(s),s._stopped=!0};const i=r.slice(),l=[s];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Cf=(e,t,n,s,r,o)=>{const i=r==="svg";t==="class"?ff(e,s,i):t==="style"?mf(e,n,s):Fs(t)?Vs(t)||xf(e,t,n,s,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Af(e,t,s,i))?(ui(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&ai(e,t,s,i,o,t!=="value")):e._isVueCE&&(Tf(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!Se(s)))?ui(e,Qe(t),s,o,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),ai(e,t,s,i))};function Af(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&fi(t)&&te(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return fi(t)&&Se(n)?!1:t in e}function Tf(e,t){const n=e._def.props;if(!n)return!1;const s=Qe(t);return Array.isArray(n)?n.some(r=>Qe(r)===s):Object.keys(n).some(r=>Qe(r)===s)}const Sn=e=>{const t=e.props["onUpdate:modelValue"]||!1;return Z(t)?n=>vs(t,n):t};function Of(e){e.target.composing=!0}function di(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const $t=Symbol("_assign");function pi(e,t,n){return t&&(e=e.trim()),n&&(e=js(e)),e}const Ae={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[$t]=Sn(r);const o=s||r.props&&r.props.type==="number";Kt(e,t?"change":"input",i=>{i.target.composing||e[$t](pi(e.value,n,o))}),(n||o)&&Kt(e,"change",()=>{e.value=pi(e.value,n,o)}),t||(Kt(e,"compositionstart",Of),Kt(e,"compositionend",di),Kt(e,"change",di))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:o}},i){if(e[$t]=Sn(i),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?js(e.value):e.value,a=t??"";if(l===a)return;const u=e.getRootNode();(u instanceof Document||u instanceof ShadowRoot)&&u.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===a)||(e.value=a)}},wn={deep:!0,created(e,t,n){e[$t]=Sn(n),Kt(e,"change",()=>{const s=e._modelValue,r=ns(e),o=e.checked,i=e[$t];if(Z(s)){const l=Jr(s,r),a=l!==-1;if(o&&!a)i(s.concat(r));else if(!o&&a){const u=[...s];u.splice(l,1),i(u)}}else if(On(s)){const l=new Set(s);o?l.add(r):l.delete(r),i(l)}else i(ba(e,o))})},mounted:hi,beforeUpdate(e,t,n){e[$t]=Sn(n),hi(e,t,n)}};function hi(e,{value:t,oldValue:n},s){e._modelValue=t;let r;if(Z(t))r=Jr(t,s.props.value)>-1;else if(On(t))r=t.has(s.props.value);else{if(t===n)return;r=Pn(t,ba(e,!0))}e.checked!==r&&(e.checked=r)}const St={deep:!0,created(e,{value:t,modifiers:{number:n}},s){e._modelValue=t,Kt(e,"change",()=>{const r=Array.prototype.filter.call(e.options,o=>o.selected).map(o=>n?js(ns(o)):ns(o));e[$t](e.multiple?On(e._modelValue)?new Set(r):r:r[0]),e._assigning=!0,so(()=>{e._assigning=!1})}),e[$t]=Sn(s)},mounted(e,{value:t}){mi(e,t)},beforeUpdate(e,{value:t},n){e._modelValue=t,e[$t]=Sn(n)},updated(e,{value:t}){e._assigning||mi(e,t)}};function mi(e,t){const n=e.multiple,s=Z(t);if(!(n&&!s&&!On(t))){for(let r=0,o=e.options.length;rString(u)===String(l)):i.selected=Jr(t,l)>-1}else i.selected=t.has(l);else if(Pn(ns(i),t)){e.selectedIndex!==r&&(e.selectedIndex=r);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function ns(e){return"_value"in e?e._value:e.value}function ba(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Pf={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},Nf=(e,t)=>{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=(r=>{if(!("key"in r))return;const o=Gt(r.key);if(t.some(i=>i===o||Pf[i]===o))return e(r)}))},If=Ie({patchProp:Cf},nf);let gi;function kf(){return gi||(gi=Lc(If))}const Df=((...e)=>{const t=kf().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Lf(s);if(!r)return;const o=t._component;!te(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.nodeType===1&&(r.textContent="");const i=n(r,!1,$f(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t});function $f(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Lf(e){return Se(e)?document.querySelector(e):e}/*! + * pinia v2.3.1 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */const Uf=Symbol();var yi;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(yi||(yi={}));function Ff(){const e=vu(!0),t=e.run(()=>z({}));let n=[],s=[];const r=wl({install(o){r._a=o,o.provide(Uf,r),o.config.globalProperties.$pinia=r,s.forEach(i=>n.push(i)),s=[]},use(o){return this._a?n.push(o):s.push(o),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return r}const Vf={__name:"App",setup(e){return(t,n)=>{const s=Pr("router-view");return D(),an(s,null,{default:lt(({Component:r})=>[we(of,{name:"fade",mode:"out-in"},{default:lt(()=>[(D(),an(hc(r)))]),_:2},1024)]),_:1})}}};/*! + * vue-router v4.6.4 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */const mn=typeof document<"u";function xa(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Mf(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&xa(e.default)}const he=Object.assign;function hr(e,t){const n={};for(const s in t){const r=t[s];n[s]=dt(r)?r.map(e):e(r)}return n}const Gn=()=>{},dt=Array.isArray;function bi(e,t){const n={};for(const s in e)n[s]=s in t?t[s]:e[s];return n}const va=/#/g,Bf=/&/g,jf=/\//g,Hf=/=/g,qf=/\?/g,_a=/\+/g,Kf=/%5B/g,Wf=/%5D/g,wa=/%5E/g,Gf=/%60/g,Ea=/%7B/g,zf=/%7C/g,Sa=/%7D/g,Jf=/%20/g;function co(e){return e==null?"":encodeURI(""+e).replace(zf,"|").replace(Kf,"[").replace(Wf,"]")}function Xf(e){return co(e).replace(Ea,"{").replace(Sa,"}").replace(wa,"^")}function Ur(e){return co(e).replace(_a,"%2B").replace(Jf,"+").replace(va,"%23").replace(Bf,"%26").replace(Gf,"`").replace(Ea,"{").replace(Sa,"}").replace(wa,"^")}function Qf(e){return Ur(e).replace(Hf,"%3D")}function Yf(e){return co(e).replace(va,"%23").replace(qf,"%3F")}function Zf(e){return Yf(e).replace(jf,"%2F")}function ss(e){if(e==null)return null;try{return decodeURIComponent(""+e)}catch{}return""+e}const ed=/\/$/,td=e=>e.replace(ed,"");function mr(e,t,n="/"){let s,r={},o="",i="";const l=t.indexOf("#");let a=t.indexOf("?");return a=l>=0&&a>l?-1:a,a>=0&&(s=t.slice(0,a),o=t.slice(a,l>0?l:t.length),r=e(o.slice(1))),l>=0&&(s=s||t.slice(0,l),i=t.slice(l,t.length)),s=od(s??t,n),{fullPath:s+o+i,path:s,query:r,hash:ss(i)}}function nd(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function xi(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function sd(e,t,n){const s=t.matched.length-1,r=n.matched.length-1;return s>-1&&s===r&&Rn(t.matched[s],n.matched[r])&&Ra(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function Rn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Ra(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!rd(e[n],t[n]))return!1;return!0}function rd(e,t){return dt(e)?vi(e,t):dt(t)?vi(t,e):(e==null?void 0:e.valueOf())===(t==null?void 0:t.valueOf())}function vi(e,t){return dt(t)?e.length===t.length&&e.every((n,s)=>n===t[s]):e.length===1&&e[0]===t}function od(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),s=e.split("/"),r=s[s.length-1];(r===".."||r===".")&&s.push("");let o=n.length-1,i,l;for(i=0;i1&&o--;else break;return n.slice(0,o).join("/")+"/"+s.slice(i).join("/")}const Bt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};let Fr=(function(e){return e.pop="pop",e.push="push",e})({}),gr=(function(e){return e.back="back",e.forward="forward",e.unknown="",e})({});function id(e){if(!e)if(mn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),td(e)}const ld=/^[^#]+#/;function ad(e,t){return e.replace(ld,"#")+t}function ud(e,t){const n=document.documentElement.getBoundingClientRect(),s=e.getBoundingClientRect();return{behavior:t.behavior,left:s.left-n.left-(t.left||0),top:s.top-n.top-(t.top||0)}}const Qs=()=>({left:window.scrollX,top:window.scrollY});function cd(e){let t;if("el"in e){const n=e.el,s=typeof n=="string"&&n.startsWith("#"),r=typeof n=="string"?s?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!r)return;t=ud(r,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function _i(e,t){return(history.state?history.state.position-t:-1)+e}const Vr=new Map;function fd(e,t){Vr.set(e,t)}function dd(e){const t=Vr.get(e);return Vr.delete(e),t}function pd(e){return typeof e=="string"||e&&typeof e=="object"}function Ca(e){return typeof e=="string"||typeof e=="symbol"}let Ce=(function(e){return e[e.MATCHER_NOT_FOUND=1]="MATCHER_NOT_FOUND",e[e.NAVIGATION_GUARD_REDIRECT=2]="NAVIGATION_GUARD_REDIRECT",e[e.NAVIGATION_ABORTED=4]="NAVIGATION_ABORTED",e[e.NAVIGATION_CANCELLED=8]="NAVIGATION_CANCELLED",e[e.NAVIGATION_DUPLICATED=16]="NAVIGATION_DUPLICATED",e})({});const Aa=Symbol("");Ce.MATCHER_NOT_FOUND+"",Ce.NAVIGATION_GUARD_REDIRECT+"",Ce.NAVIGATION_ABORTED+"",Ce.NAVIGATION_CANCELLED+"",Ce.NAVIGATION_DUPLICATED+"";function Cn(e,t){return he(new Error,{type:e,[Aa]:!0},t)}function Tt(e,t){return e instanceof Error&&Aa in e&&(t==null||!!(e.type&t))}const hd=["params","query","hash"];function md(e){if(typeof e=="string")return e;if(e.path!=null)return e.path;const t={};for(const n of hd)n in e&&(t[n]=e[n]);return JSON.stringify(t,null,2)}function gd(e){const t={};if(e===""||e==="?")return t;const n=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;sr&&Ur(r)):[s&&Ur(s)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function yd(e){const t={};for(const n in e){const s=e[n];s!==void 0&&(t[n]=dt(s)?s.map(r=>r==null?null:""+r):s==null?s:""+s)}return t}const bd=Symbol(""),Ei=Symbol(""),fo=Symbol(""),Ta=Symbol(""),Mr=Symbol("");function Un(){let e=[];function t(s){return e.push(s),()=>{const r=e.indexOf(s);r>-1&&e.splice(r,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function qt(e,t,n,s,r,o=i=>i()){const i=s&&(s.enterCallbacks[r]=s.enterCallbacks[r]||[]);return()=>new Promise((l,a)=>{const u=d=>{d===!1?a(Cn(Ce.NAVIGATION_ABORTED,{from:n,to:t})):d instanceof Error?a(d):pd(d)?a(Cn(Ce.NAVIGATION_GUARD_REDIRECT,{from:t,to:d})):(i&&s.enterCallbacks[r]===i&&typeof d=="function"&&i.push(d),l())},c=o(()=>e.call(s&&s.instances[r],t,n,u));let f=Promise.resolve(c);e.length<3&&(f=f.then(u)),f.catch(d=>a(d))})}function yr(e,t,n,s,r=o=>o()){const o=[];for(const i of e)for(const l in i.components){let a=i.components[l];if(!(t!=="beforeRouteEnter"&&!i.instances[l]))if(xa(a)){const u=(a.__vccOpts||a)[t];u&&o.push(qt(u,n,s,i,l,r))}else{let u=a();o.push(()=>u.then(c=>{if(!c)throw new Error(`Couldn't resolve component "${l}" at "${i.path}"`);const f=Mf(c)?c.default:c;i.mods[l]=c,i.components[l]=f;const d=(f.__vccOpts||f)[t];return d&&qt(d,n,s,i,l,r)()}))}}return o}function xd(e,t){const n=[],s=[],r=[],o=Math.max(t.matched.length,e.matched.length);for(let i=0;iRn(u,l))?s.push(l):n.push(l));const a=e.matched[i];a&&(t.matched.find(u=>Rn(u,a))||r.push(a))}return[n,s,r]}/*! + * vue-router v4.6.4 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */let vd=()=>location.protocol+"//"+location.host;function Oa(e,t){const{pathname:n,search:s,hash:r}=t,o=e.indexOf("#");if(o>-1){let i=r.includes(e.slice(o))?e.slice(o).length:1,l=r.slice(i);return l[0]!=="/"&&(l="/"+l),xi(l,"")}return xi(n,e)+s+r}function _d(e,t,n,s){let r=[],o=[],i=null;const l=({state:d})=>{const m=Oa(e,location),R=n.value,A=t.value;let O=0;if(d){if(n.value=m,t.value=d,i&&i===R){i=null;return}O=A?d.position-A.position:0}else s(m);r.forEach(E=>{E(n.value,R,{delta:O,type:Fr.pop,direction:O?O>0?gr.forward:gr.back:gr.unknown})})};function a(){i=n.value}function u(d){r.push(d);const m=()=>{const R=r.indexOf(d);R>-1&&r.splice(R,1)};return o.push(m),m}function c(){if(document.visibilityState==="hidden"){const{history:d}=window;if(!d.state)return;d.replaceState(he({},d.state,{scroll:Qs()}),"")}}function f(){for(const d of o)d();o=[],window.removeEventListener("popstate",l),window.removeEventListener("pagehide",c),document.removeEventListener("visibilitychange",c)}return window.addEventListener("popstate",l),window.addEventListener("pagehide",c),document.addEventListener("visibilitychange",c),{pauseListeners:a,listen:u,destroy:f}}function Si(e,t,n,s=!1,r=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:r?Qs():null}}function wd(e){const{history:t,location:n}=window,s={value:Oa(e,n)},r={value:t.state};r.value||o(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(a,u,c){const f=e.indexOf("#"),d=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+a:vd()+e+a;try{t[c?"replaceState":"pushState"](u,"",d),r.value=u}catch(m){console.error(m),n[c?"replace":"assign"](d)}}function i(a,u){o(a,he({},t.state,Si(r.value.back,a,r.value.forward,!0),u,{position:r.value.position}),!0),s.value=a}function l(a,u){const c=he({},r.value,t.state,{forward:a,scroll:Qs()});o(c.current,c,!0),o(a,he({},Si(s.value,a,null),{position:c.position+1},u),!1),s.value=a}return{location:s,state:r,push:l,replace:i}}function Ed(e){e=id(e);const t=wd(e),n=_d(e,t.state,t.location,t.replace);function s(o,i=!0){i||n.pauseListeners(),history.go(o)}const r=he({location:"",base:e,go:s,createHref:ad.bind(null,e)},t,n);return Object.defineProperty(r,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(r,"state",{enumerable:!0,get:()=>t.state.value}),r}let nn=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e})({});var Pe=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e})(Pe||{});const Sd={type:nn.Static,value:""},Rd=/[a-zA-Z0-9_]/;function Cd(e){if(!e)return[[]];if(e==="/")return[[Sd]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${u}": ${m}`)}let n=Pe.Static,s=n;const r=[];let o;function i(){o&&r.push(o),o=[]}let l=0,a,u="",c="";function f(){u&&(n===Pe.Static?o.push({type:nn.Static,value:u}):n===Pe.Param||n===Pe.ParamRegExp||n===Pe.ParamRegExpEnd?(o.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),o.push({type:nn.Param,value:u,regexp:c,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),u="")}function d(){u+=a}for(;lt.length?t.length===1&&t[0]===ze.Static+ze.Segment?1:-1:0}function Pa(e,t){let n=0;const s=e.score,r=t.score;for(;n0&&t[t.length-1]<0}const Nd={strict:!1,end:!0,sensitive:!1};function Id(e,t,n){const s=Od(Cd(e.path),n),r=he(s,{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function kd(e,t){const n=[],s=new Map;t=bi(Nd,t);function r(f){return s.get(f)}function o(f,d,m){const R=!m,A=Ti(f);A.aliasOf=m&&m.record;const O=bi(t,f),E=[A];if("alias"in f){const g=typeof f.alias=="string"?[f.alias]:f.alias;for(const x of g)E.push(Ti(he({},A,{components:m?m.record.components:A.components,path:x,aliasOf:m?m.record:A})))}let w,v;for(const g of E){const{path:x}=g;if(d&&x[0]!=="/"){const I=d.record.path,C=I[I.length-1]==="/"?"":"/";g.path=d.record.path+(x&&C+x)}if(w=Id(g,d,O),m?m.alias.push(w):(v=v||w,v!==w&&v.alias.push(w),R&&f.name&&!Oi(w)&&i(f.name)),Na(w)&&a(w),A.children){const I=A.children;for(let C=0;C{i(v)}:Gn}function i(f){if(Ca(f)){const d=s.get(f);d&&(s.delete(f),n.splice(n.indexOf(d),1),d.children.forEach(i),d.alias.forEach(i))}else{const d=n.indexOf(f);d>-1&&(n.splice(d,1),f.record.name&&s.delete(f.record.name),f.children.forEach(i),f.alias.forEach(i))}}function l(){return n}function a(f){const d=Ld(f,n);n.splice(d,0,f),f.record.name&&!Oi(f)&&s.set(f.record.name,f)}function u(f,d){let m,R={},A,O;if("name"in f&&f.name){if(m=s.get(f.name),!m)throw Cn(Ce.MATCHER_NOT_FOUND,{location:f});O=m.record.name,R=he(Ai(d.params,m.keys.filter(v=>!v.optional).concat(m.parent?m.parent.keys.filter(v=>v.optional):[]).map(v=>v.name)),f.params&&Ai(f.params,m.keys.map(v=>v.name))),A=m.stringify(R)}else if(f.path!=null)A=f.path,m=n.find(v=>v.re.test(A)),m&&(R=m.parse(A),O=m.record.name);else{if(m=d.name?s.get(d.name):n.find(v=>v.re.test(d.path)),!m)throw Cn(Ce.MATCHER_NOT_FOUND,{location:f,currentLocation:d});O=m.record.name,R=he({},d.params,f.params),A=m.stringify(R)}const E=[];let w=m;for(;w;)E.unshift(w.record),w=w.parent;return{name:O,path:A,params:R,matched:E,meta:$d(E)}}e.forEach(f=>o(f));function c(){n.length=0,s.clear()}return{addRoute:o,resolve:u,removeRoute:i,clearRoutes:c,getRoutes:l,getRecordMatcher:r}}function Ai(e,t){const n={};for(const s of t)s in e&&(n[s]=e[s]);return n}function Ti(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Dd(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Dd(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const s in e.components)t[s]=typeof n=="object"?n[s]:n;return t}function Oi(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function $d(e){return e.reduce((t,n)=>he(t,n.meta),{})}function Ld(e,t){let n=0,s=t.length;for(;n!==s;){const o=n+s>>1;Pa(e,t[o])<0?s=o:n=o+1}const r=Ud(e);return r&&(s=t.lastIndexOf(r,s-1)),s}function Ud(e){let t=e;for(;t=t.parent;)if(Na(t)&&Pa(e,t)===0)return t}function Na({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Pi(e){const t=kt(fo),n=kt(Ta),s=Xe(()=>{const a=bn(e.to);return t.resolve(a)}),r=Xe(()=>{const{matched:a}=s.value,{length:u}=a,c=a[u-1],f=n.matched;if(!c||!f.length)return-1;const d=f.findIndex(Rn.bind(null,c));if(d>-1)return d;const m=Ni(a[u-2]);return u>1&&Ni(c)===m&&f[f.length-1].path!==m?f.findIndex(Rn.bind(null,a[u-2])):d}),o=Xe(()=>r.value>-1&&jd(n.params,s.value.params)),i=Xe(()=>r.value>-1&&r.value===n.matched.length-1&&Ra(n.params,s.value.params));function l(a={}){if(Bd(a)){const u=t[bn(e.replace)?"replace":"push"](bn(e.to)).catch(Gn);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>u),u}return Promise.resolve()}return{route:s,href:Xe(()=>s.value.href),isActive:o,isExactActive:i,navigate:l}}function Fd(e){return e.length===1?e[0]:e}const Vd=Ml({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:Pi,setup(e,{slots:t}){const n=zt(Pi(e)),{options:s}=kt(fo),r=Xe(()=>({[Ii(e.activeClass,s.linkActiveClass,"router-link-active")]:n.isActive,[Ii(e.exactActiveClass,s.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&Fd(t.default(n));return e.custom?o:uo("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:r.value},o)}}}),Md=Vd;function Bd(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function jd(e,t){for(const n in t){const s=t[n],r=e[n];if(typeof s=="string"){if(s!==r)return!1}else if(!dt(r)||r.length!==s.length||s.some((o,i)=>o.valueOf()!==r[i].valueOf()))return!1}return!0}function Ni(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Ii=(e,t,n)=>e??t??n,Hd=Ml({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const s=kt(Mr),r=Xe(()=>e.route||s.value),o=kt(Ei,0),i=Xe(()=>{let u=bn(o);const{matched:c}=r.value;let f;for(;(f=c[u])&&!f.components;)u++;return u}),l=Xe(()=>r.value.matched[i.value]);_s(Ei,Xe(()=>i.value+1)),_s(bd,l),_s(Mr,r);const a=z();return ws(()=>[a.value,l.value,e.name],([u,c,f],[d,m,R])=>{c&&(c.instances[f]=u,m&&m!==c&&u&&u===d&&(c.leaveGuards.size||(c.leaveGuards=m.leaveGuards),c.updateGuards.size||(c.updateGuards=m.updateGuards))),u&&c&&(!m||!Rn(c,m)||!d)&&(c.enterCallbacks[f]||[]).forEach(A=>A(u))},{flush:"post"}),()=>{const u=r.value,c=e.name,f=l.value,d=f&&f.components[c];if(!d)return ki(n.default,{Component:d,route:u});const m=f.props[c],R=m?m===!0?u.params:typeof m=="function"?m(u):m:null,O=uo(d,he({},R,t,{onVnodeUnmounted:E=>{E.component.isUnmounted&&(f.instances[c]=null)},ref:a}));return ki(n.default,{Component:O,route:u})||O}}});function ki(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const qd=Hd;function Kd(e){const t=kd(e.routes,e),n=e.parseQuery||gd,s=e.stringifyQuery||wi,r=e.history,o=Un(),i=Un(),l=Un(),a=Vu(Bt);let u=Bt;mn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=hr.bind(null,N=>""+N),f=hr.bind(null,Zf),d=hr.bind(null,ss);function m(N,K){let H,X;return Ca(N)?(H=t.getRecordMatcher(N),X=K):X=N,t.addRoute(X,H)}function R(N){const K=t.getRecordMatcher(N);K&&t.removeRoute(K)}function A(){return t.getRoutes().map(N=>N.record)}function O(N){return!!t.getRecordMatcher(N)}function E(N,K){if(K=he({},K||a.value),typeof N=="string"){const _=mr(n,N,K.path),P=t.resolve({path:_.path},K),S=r.createHref(_.fullPath);return he(_,P,{params:d(P.params),hash:ss(_.hash),redirectedFrom:void 0,href:S})}let H;if(N.path!=null)H=he({},N,{path:mr(n,N.path,K.path).path});else{const _=he({},N.params);for(const P in _)_[P]==null&&delete _[P];H=he({},N,{params:f(_)}),K.params=f(K.params)}const X=t.resolve(H,K),re=N.hash||"";X.params=c(d(X.params));const h=nd(s,he({},N,{hash:Xf(re),path:X.path})),y=r.createHref(h);return he({fullPath:h,hash:re,query:s===wi?yd(N.query):N.query||{}},X,{redirectedFrom:void 0,href:y})}function w(N){return typeof N=="string"?mr(n,N,a.value.path):he({},N)}function v(N,K){if(u!==N)return Cn(Ce.NAVIGATION_CANCELLED,{from:K,to:N})}function g(N){return C(N)}function x(N){return g(he(w(N),{replace:!0}))}function I(N,K){const H=N.matched[N.matched.length-1];if(H&&H.redirect){const{redirect:X}=H;let re=typeof X=="function"?X(N,K):X;return typeof re=="string"&&(re=re.includes("?")||re.includes("#")?re=w(re):{path:re},re.params={}),he({query:N.query,hash:N.hash,params:re.path!=null?{}:N.params},re)}}function C(N,K){const H=u=E(N),X=a.value,re=N.state,h=N.force,y=N.replace===!0,_=I(H,X);if(_)return C(he(w(_),{state:typeof _=="object"?he({},re,_.state):re,force:h,replace:y}),K||H);const P=H;P.redirectedFrom=K;let S;return!h&&sd(s,X,H)&&(S=Cn(Ce.NAVIGATION_DUPLICATED,{to:P,from:X}),ye(X,X,!0,!1)),(S?Promise.resolve(S):Q(P,X)).catch(T=>Tt(T)?Tt(T,Ce.NAVIGATION_GUARD_REDIRECT)?T:De(T):ue(T,P,X)).then(T=>{if(T){if(Tt(T,Ce.NAVIGATION_GUARD_REDIRECT))return C(he({replace:y},w(T.to),{state:typeof T.to=="object"?he({},re,T.to.state):re,force:h}),K||P)}else T=B(P,X,!0,y,re);return G(P,X,T),T})}function U(N,K){const H=v(N,K);return H?Promise.reject(H):Promise.resolve()}function k(N){const K=st.values().next().value;return K&&typeof K.runWithContext=="function"?K.runWithContext(N):N()}function Q(N,K){let H;const[X,re,h]=xd(N,K);H=yr(X.reverse(),"beforeRouteLeave",N,K);for(const _ of X)_.leaveGuards.forEach(P=>{H.push(qt(P,N,K))});const y=U.bind(null,N,K);return H.push(y),ne(H).then(()=>{H=[];for(const _ of o.list())H.push(qt(_,N,K));return H.push(y),ne(H)}).then(()=>{H=yr(re,"beforeRouteUpdate",N,K);for(const _ of re)_.updateGuards.forEach(P=>{H.push(qt(P,N,K))});return H.push(y),ne(H)}).then(()=>{H=[];for(const _ of h)if(_.beforeEnter)if(dt(_.beforeEnter))for(const P of _.beforeEnter)H.push(qt(P,N,K));else H.push(qt(_.beforeEnter,N,K));return H.push(y),ne(H)}).then(()=>(N.matched.forEach(_=>_.enterCallbacks={}),H=yr(h,"beforeRouteEnter",N,K,k),H.push(y),ne(H))).then(()=>{H=[];for(const _ of i.list())H.push(qt(_,N,K));return H.push(y),ne(H)}).catch(_=>Tt(_,Ce.NAVIGATION_CANCELLED)?_:Promise.reject(_))}function G(N,K,H){l.list().forEach(X=>k(()=>X(N,K,H)))}function B(N,K,H,X,re){const h=v(N,K);if(h)return h;const y=K===Bt,_=mn?history.state:{};H&&(X||y?r.replace(N.fullPath,he({scroll:y&&_&&_.scroll},re)):r.push(N.fullPath,re)),a.value=N,ye(N,K,H,y),De()}let oe;function ie(){oe||(oe=r.listen((N,K,H)=>{if(!ht.listening)return;const X=E(N),re=I(X,ht.currentRoute.value);if(re){C(he(re,{replace:!0,force:!0}),X).catch(Gn);return}u=X;const h=a.value;mn&&fd(_i(h.fullPath,H.delta),Qs()),Q(X,h).catch(y=>Tt(y,Ce.NAVIGATION_ABORTED|Ce.NAVIGATION_CANCELLED)?y:Tt(y,Ce.NAVIGATION_GUARD_REDIRECT)?(C(he(w(y.to),{force:!0}),X).then(_=>{Tt(_,Ce.NAVIGATION_ABORTED|Ce.NAVIGATION_DUPLICATED)&&!H.delta&&H.type===Fr.pop&&r.go(-1,!1)}).catch(Gn),Promise.reject()):(H.delta&&r.go(-H.delta,!1),ue(y,X,h))).then(y=>{y=y||B(X,h,!1),y&&(H.delta&&!Tt(y,Ce.NAVIGATION_CANCELLED)?r.go(-H.delta,!1):H.type===Fr.pop&&Tt(y,Ce.NAVIGATION_ABORTED|Ce.NAVIGATION_DUPLICATED)&&r.go(-1,!1)),G(X,h,y)}).catch(Gn)}))}let ke=Un(),xe=Un(),ae;function ue(N,K,H){De(N);const X=xe.list();return X.length?X.forEach(re=>re(N,K,H)):console.error(N),Promise.reject(N)}function nt(){return ae&&a.value!==Bt?Promise.resolve():new Promise((N,K)=>{ke.add([N,K])})}function De(N){return ae||(ae=!N,ie(),ke.list().forEach(([K,H])=>N?H(N):K()),ke.reset()),N}function ye(N,K,H,X){const{scrollBehavior:re}=e;if(!mn||!re)return Promise.resolve();const h=!H&&dd(_i(N.fullPath,0))||(X||!H)&&history.state&&history.state.scroll||null;return so().then(()=>re(N,K,h)).then(y=>y&&cd(y)).catch(y=>ue(y,N,K))}const Re=N=>r.go(N);let Ze;const st=new Set,ht={currentRoute:a,listening:!0,addRoute:m,removeRoute:R,clearRoutes:t.clearRoutes,hasRoute:O,getRoutes:A,resolve:E,options:e,push:g,replace:x,go:Re,back:()=>Re(-1),forward:()=>Re(1),beforeEach:o.add,beforeResolve:i.add,afterEach:l.add,onError:xe.add,isReady:nt,install(N){N.component("RouterLink",Md),N.component("RouterView",qd),N.config.globalProperties.$router=ht,Object.defineProperty(N.config.globalProperties,"$route",{enumerable:!0,get:()=>bn(a)}),mn&&!Ze&&a.value===Bt&&(Ze=!0,g(r.location).catch(X=>{}));const K={};for(const X in Bt)Object.defineProperty(K,X,{get:()=>a.value[X],enumerable:!0});N.provide(fo,ht),N.provide(Ta,_l(K)),N.provide(Mr,a);const H=N.unmount;st.add(N),N.unmount=function(){st.delete(N),st.size<1&&(u=Bt,oe&&oe(),oe=null,a.value=Bt,Ze=!1,ae=!1),H()}}};function ne(N){return N.reduce((K,H)=>K.then(()=>k(H)),Promise.resolve())}return ht}const po="sub_store_admin_token",ho="sub_store_token_validated";function Wd(){return new URLSearchParams(window.location.search).get("token")||""}function Gd(e){e&&(localStorage.setItem(po,e),localStorage.setItem(ho,"true"))}function Ia(){return localStorage.getItem(po)||""}function zd(){return localStorage.getItem(ho)==="true"}function ka(){localStorage.removeItem(po),localStorage.removeItem(ho)}async function Jd(e){var t;if(!e)return!1;try{const n=((t=window.SUB_STORE_CONFIG)==null?void 0:t.apiBaseUrl)||"",s=await fetch(`${n}/api/env?token=${encodeURIComponent(e)}`);return s.ok?(await s.json()).status==="success":!1}catch{return!1}}function Xd(){const e=Wd();return e||Ia()}function Da(e,t){return function(){return e.apply(t,arguments)}}const{toString:Qd}=Object.prototype,{getPrototypeOf:An}=Object,{iterator:us,toStringTag:$a}=Symbol,$s=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),rs=(e,t)=>{let n=e;const s=[];for(;n!=null&&n!==Object.prototype;){if(s.indexOf(n)!==-1)return!1;if(s.push(n),$s(n,t))return!0;n=An(n)}return!1},Yd=(e,t)=>e!=null&&rs(e,t)?e[t]:void 0,mo=(e=>t=>{const n=Qd.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),pt=e=>(e=e.toLowerCase(),t=>mo(t)===e),Ys=e=>t=>typeof t===e,{isArray:cn}=Array,Tn=Ys("undefined");function Nn(e){return e!==null&&!Tn(e)&&e.constructor!==null&&!Tn(e.constructor)&&Ye(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const La=pt("ArrayBuffer");function Zd(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&La(e.buffer),t}const ep=Ys("string"),Ye=Ys("function"),Ua=Ys("number"),In=e=>e!==null&&typeof e=="object",tp=e=>e===!0||e===!1,Ss=e=>{if(!In(e))return!1;const t=An(e);return(t===null||t===Object.prototype||An(t)===null)&&!rs(e,$a)&&!rs(e,us)},np=e=>{if(!In(e)||Nn(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},sp=pt("Date"),rp=pt("File"),op=e=>!!(e&&typeof e.uri<"u"),ip=e=>e&&typeof e.getParts<"u",lp=pt("Blob"),ap=pt("FileList"),up=e=>In(e)&&Ye(e.pipe);function cp(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}}const Di=cp(),$i=typeof Di.FormData<"u"?Di.FormData:void 0,fp=e=>{if(!e)return!1;if($i&&e instanceof $i)return!0;const t=An(e);if(!t||t===Object.prototype||!Ye(e.append))return!1;const n=mo(e);return n==="formdata"||n==="object"&&Ye(e.toString)&&e.toString()==="[object FormData]"},dp=pt("URLSearchParams"),[pp,hp,mp,gp]=["ReadableStream","Request","Response","Headers"].map(pt),yp=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function cs(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),cn(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const sn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Va=e=>!Tn(e)&&e!==sn;function Br(...e){const{caseless:t,skipUndefined:n}=Va(this)&&this||{},s={},r=(o,i)=>{if(i==="__proto__"||i==="constructor"||i==="prototype")return;const l=t&&typeof i=="string"&&Fa(s,i)||i,a=$s(s,l)?s[l]:void 0;Ss(a)&&Ss(o)?s[l]=Br(a,o):Ss(o)?s[l]=Br({},o):cn(o)?s[l]=o.slice():(!n||!Tn(o))&&(s[l]=o)};for(let o=0,i=e.length;o(cs(t,(r,o)=>{n&&Ye(r)?Object.defineProperty(e,o,{__proto__:null,value:Da(r,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,o,{__proto__:null,value:r,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:s}),e),xp=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),vp=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),Object.defineProperty(e.prototype,"constructor",{__proto__:null,value:e,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e,"super",{__proto__:null,value:t.prototype}),n&&Object.assign(e.prototype,n)},_p=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&An(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},wp=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},Ep=e=>{if(!e)return null;if(cn(e))return e;let t=e.length;if(!Ua(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},Sp=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&An(Uint8Array)),Rp=(e,t)=>{const s=(e&&e[us]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},Cp=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},Ap=pt("HTMLFormElement"),Tp=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),{propertyIsEnumerable:Op}=Object.prototype,Pp=pt("RegExp"),Ma=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};cs(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},Np=e=>{Ma(e,(t,n)=>{if(Ye(e)&&["arguments","caller","callee"].includes(n))return!1;const s=e[n];if(Ye(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},Ip=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return cn(e)?s(e):s(String(e).split(t)),n},kp=()=>{},Dp=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function $p(e){return!!(e&&Ye(e.append)&&e[$a]==="FormData"&&e[us])}const Lp=e=>{const t=new WeakSet,n=s=>{if(In(s)){if(t.has(s))return;if(Nn(s))return s;if(!("toJSON"in s)){t.add(s);const r=cn(s)?[]:{};return cs(s,(o,i)=>{const l=n(o);!Tn(l)&&(r[i]=l)}),t.delete(s),r}}return s};return n(e)},Up=pt("AsyncFunction"),Fp=e=>e&&(In(e)||Ye(e))&&Ye(e.then)&&Ye(e.catch),Ba=((e,t)=>e?setImmediate:t?((n,s)=>(sn.addEventListener("message",({source:r,data:o})=>{r===sn&&o===n&&s.length&&s.shift()()},!1),r=>{s.push(r),sn.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",Ye(sn.postMessage)),Vp=typeof queueMicrotask<"u"?queueMicrotask.bind(sn):typeof process<"u"&&process.nextTick||Ba,ja=e=>e!=null&&Ye(e[us]),Mp=e=>e!=null&&rs(e,us)&&ja(e),b={isArray:cn,isArrayBuffer:La,isBuffer:Nn,isFormData:fp,isArrayBufferView:Zd,isString:ep,isNumber:Ua,isBoolean:tp,isObject:In,isPlainObject:Ss,isEmptyObject:np,isReadableStream:pp,isRequest:hp,isResponse:mp,isHeaders:gp,isUndefined:Tn,isDate:sp,isFile:rp,isReactNativeBlob:op,isReactNative:ip,isBlob:lp,isRegExp:Pp,isFunction:Ye,isStream:up,isURLSearchParams:dp,isTypedArray:Sp,isFileList:ap,forEach:cs,merge:Br,extend:bp,trim:yp,stripBOM:xp,inherits:vp,toFlatObject:_p,kindOf:mo,kindOfTest:pt,endsWith:wp,toArray:Ep,forEachEntry:Rp,matchAll:Cp,isHTMLForm:Ap,hasOwnProperty:$s,hasOwnProp:$s,hasOwnInPrototypeChain:rs,getSafeProp:Yd,reduceDescriptors:Ma,freezeMethods:Np,toObjectSet:Ip,toCamelCase:Tp,noop:kp,toFiniteNumber:Dp,findKey:Fa,global:sn,isContextDefined:Va,isSpecCompliantForm:$p,toJSONObject:Lp,isAsyncFn:Up,isThenable:Fp,setImmediate:Ba,asap:Vp,isIterable:ja,isSafeIterable:Mp},Bp=b.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),jp=e=>{const t={};let n,s,r;return e&&e.split(` +`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&Bp[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t};function Hp(e){let t=0,n=e.length;for(;tt;){const s=e.charCodeAt(n-1);if(s!==9&&s!==32)break;n-=1}return t===0&&n===e.length?e:e.slice(t,n)}const qp=new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+","g"),Kp=new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+","g");function go(e,t){return b.isArray(e)?e.map(n=>go(n,t)):Hp(String(e).replace(t,""))}const Wp=e=>go(e,qp),Gp=e=>go(e,Kp);function Ha(e){const t=Object.create(null);return b.forEach(e.toJSON(),(n,s)=>{t[s]=Gp(n)}),t}const Li=Symbol("internals");function Fn(e){return e&&String(e).trim().toLowerCase()}function Rs(e){return e===!1||e==null?e:b.isArray(e)?e.map(Rs):Wp(String(e))}function zp(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const Jp=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function br(e,t,n,s,r){if(b.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!b.isString(t)){if(b.isString(s))return t.indexOf(s)!==-1;if(b.isRegExp(s))return s.test(t)}}function Xp(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function Qp(e,t){const n=b.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{__proto__:null,value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}let Ke=class{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,a,u){const c=Fn(a);if(!c)return;const f=b.findKey(r,c);(!f||r[f]===void 0||u===!0||u===void 0&&r[f]!==!1)&&(r[f||a]=Rs(l))}const i=(l,a)=>b.forEach(l,(u,c)=>o(u,c,a));if(b.isPlainObject(t)||t instanceof this.constructor)i(t,n);else if(b.isString(t)&&(t=t.trim())&&!Jp(t))i(jp(t),n);else if(b.isObject(t)&&b.isSafeIterable(t)){let l=Object.create(null),a,u;for(const c of t){if(!b.isArray(c))throw new TypeError("Object iterator must return a key-value pair");u=c[0],b.hasOwnProp(l,u)?(a=l[u],l[u]=b.isArray(a)?[...a,c[1]]:[a,c[1]]):l[u]=c[1]}i(l,n)}else t!=null&&o(n,t,s);return this}get(t,n){if(t=Fn(t),t){const s=b.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return zp(r);if(b.isFunction(n))return n.call(this,r,s);if(b.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Fn(t),t){const s=b.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||br(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=Fn(i),i){const l=b.findKey(s,i);l&&(!n||br(s,s[l],l,n))&&(delete s[l],r=!0)}}return b.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||br(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return b.forEach(this,(r,o)=>{const i=b.findKey(s,o);if(i){n[i]=Rs(r),delete n[o];return}const l=t?Xp(o):String(o).trim();l!==o&&delete n[o],n[l]=Rs(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return b.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&b.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[Li]=this[Li]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=Fn(i);s[l]||(Qp(r,i),s[l]=!0)}return b.isArray(t)?t.forEach(o):o(t),this}};Ke.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);b.reduceDescriptors(Ke.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});b.freezeMethods(Ke);const Yp="[REDACTED ****]";function Zp(e){if(b.hasOwnProp(e,"toJSON"))return!0;let t=Object.getPrototypeOf(e);for(;t&&t!==Object.prototype;){if(b.hasOwnProp(t,"toJSON"))return!0;t=Object.getPrototypeOf(t)}return!1}function eh(e,t){const n=new Set(t.map(o=>String(o).toLowerCase())),s=[],r=o=>{if(o===null||typeof o!="object"||b.isBuffer(o))return o;if(s.indexOf(o)!==-1)return;o instanceof Ke&&(o=o.toJSON()),s.push(o);let i;if(b.isArray(o))i=[],o.forEach((l,a)=>{const u=r(l);b.isUndefined(u)||(i[a]=u)});else{if(!b.isPlainObject(o)&&Zp(o))return s.pop(),o;i=Object.create(null);for(const[l,a]of Object.entries(o)){const u=n.has(l.toLowerCase())?Yp:r(a);b.isUndefined(u)||(i[l]=u)}}return s.pop(),i};return r(e)}let j=class qa extends Error{static from(t,n,s,r,o,i){const l=new qa(t.message,n||t.code,s,r,o);return Object.defineProperty(l,"cause",{__proto__:null,value:t,writable:!0,enumerable:!1,configurable:!0}),l.name=t.name,t.status!=null&&l.status==null&&(l.status=t.status),i&&Object.assign(l,i),l}constructor(t,n,s,r,o){super(t),Object.defineProperty(this,"message",{__proto__:null,value:t,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,n&&(this.code=n),s&&(this.config=s),r&&(this.request=r),o&&(this.response=o,this.status=o.status)}toJSON(){const t=this.config,n=t&&b.hasOwnProp(t,"redact")?t.redact:void 0,s=b.isArray(n)&&n.length>0?eh(t,n):b.toJSONObject(t);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:s,code:this.code,status:this.status}}};j.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE";j.ERR_BAD_OPTION="ERR_BAD_OPTION";j.ECONNABORTED="ECONNABORTED";j.ETIMEDOUT="ETIMEDOUT";j.ECONNREFUSED="ECONNREFUSED";j.ERR_NETWORK="ERR_NETWORK";j.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS";j.ERR_DEPRECATED="ERR_DEPRECATED";j.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE";j.ERR_BAD_REQUEST="ERR_BAD_REQUEST";j.ERR_CANCELED="ERR_CANCELED";j.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT";j.ERR_INVALID_URL="ERR_INVALID_URL";j.ERR_FORM_DATA_DEPTH_EXCEEDED="ERR_FORM_DATA_DEPTH_EXCEEDED";const th=null,Ka=100;function jr(e){return b.isPlainObject(e)||b.isArray(e)}function Wa(e){return b.endsWith(e,"[]")?e.slice(0,-2):e}function xr(e,t,n){return e?e.concat(t).map(function(r,o){return r=Wa(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function nh(e){return b.isArray(e)&&!e.some(jr)}const sh=b.toFlatObject(b,{},null,function(t){return/^is[A-Z]/.test(t)});function Zs(e,t,n){if(!b.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=b.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(w,v){return!b.isUndefined(v[w])});const s=n.metaTokens,r=n.visitor||R,o=n.dots,i=n.indexes,l=n.Blob||typeof Blob<"u"&&Blob,a=n.maxDepth===void 0?Ka:n.maxDepth,u=l&&b.isSpecCompliantForm(t),c=[];if(!b.isFunction(r))throw new TypeError("visitor must be a function");function f(E){if(E===null)return"";if(b.isDate(E))return E.toISOString();if(b.isBoolean(E))return E.toString();if(!u&&b.isBlob(E))throw new j("Blob is not supported. Use a Buffer instead.");if(b.isArrayBuffer(E)||b.isTypedArray(E)){if(u&&typeof l=="function")return new l([E]);if(typeof Buffer<"u")return Buffer.from(E);throw new j("Blob is not supported. Use a Buffer instead.",j.ERR_NOT_SUPPORT)}return E}function d(E){if(E>a)throw new j("Object is too deeply nested ("+E+" levels). Max depth: "+a,j.ERR_FORM_DATA_DEPTH_EXCEEDED)}function m(E,w){if(a===1/0)return JSON.stringify(E);const v=[];return JSON.stringify(E,function(x,I){if(!b.isObject(I))return I;for(;v.length&&v[v.length-1]!==this;)v.pop();return v.push(I),d(w+v.length-1),I})}function R(E,w,v){let g=E;if(b.isReactNative(t)&&b.isReactNativeBlob(E))return t.append(xr(v,w,o),f(E)),!1;if(E&&!v&&typeof E=="object"){if(b.endsWith(w,"{}"))w=s?w:w.slice(0,-2),E=m(E,1);else if(b.isArray(E)&&nh(E)||(b.isFileList(E)||b.endsWith(w,"[]"))&&(g=b.toArray(E)))return w=Wa(w),g.forEach(function(I,C){!(b.isUndefined(I)||I===null)&&t.append(i===!0?xr([w],C,o):i===null?w:w+"[]",f(I))}),!1}return jr(E)?!0:(t.append(xr(v,w,o),f(E)),!1)}const A=Object.assign(sh,{defaultVisitor:R,convertValue:f,isVisitable:jr});function O(E,w,v=0){if(!b.isUndefined(E)){if(d(v),c.indexOf(E)!==-1)throw new Error("Circular reference detected in "+w.join("."));c.push(E),b.forEach(E,function(x,I){(!(b.isUndefined(x)||x===null)&&r.call(t,x,b.isString(I)?I.trim():I,w,A))===!0&&O(x,w?w.concat(I):[I],v+1)}),c.pop()}}if(!b.isObject(e))throw new TypeError("data must be an object");return O(e),t}function Ui(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"};return encodeURIComponent(e).replace(/[!'()~]|%20/g,function(s){return t[s]})}function yo(e,t){this._pairs=[],e&&Zs(e,this,t)}const Ga=yo.prototype;Ga.append=function(t,n){this._pairs.push([t,n])};Ga.toString=function(t){const n=t?s=>t.call(this,s,Ui):Ui;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function rh(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function za(e,t,n){if(!t)return e;e=e||"";const s=b.isFunction(n)?{serialize:n}:n,r=b.getSafeProp(s,"encode")||rh,o=b.getSafeProp(s,"serialize");let i;if(o?i=o(t,s):i=b.isURLSearchParams(t)?t.toString():new yo(t,s).toString(r),i){const l=e.indexOf("#");l!==-1&&(e=e.slice(0,l)),e+=(e.indexOf("?")===-1?"?":"&")+i}return e}class Fi{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){b.forEach(this.handlers,function(s){s!==null&&t(s)})}}const bo={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0,advertiseZstdAcceptEncoding:!1,validateStatusUndefinedResolves:!0},oh=typeof URLSearchParams<"u"?URLSearchParams:yo,ih=typeof FormData<"u"?FormData:null,lh=typeof Blob<"u"?Blob:null,ah={isBrowser:!0,classes:{URLSearchParams:oh,FormData:ih,Blob:lh},protocols:["http","https","file","blob","url","data"]},xo=typeof window<"u"&&typeof document<"u",Hr=typeof navigator=="object"&&navigator||void 0,uh=xo&&(!Hr||["ReactNative","NativeScript","NS"].indexOf(Hr.product)<0),ch=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",fh=xo&&window.location.href||"http://localhost",dh=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:xo,hasStandardBrowserEnv:uh,hasStandardBrowserWebWorkerEnv:ch,navigator:Hr,origin:fh},Symbol.toStringTag,{value:"Module"})),Ue={...dh,...ah};function ph(e,t){return Zs(e,new Ue.classes.URLSearchParams,{visitor:function(n,s,r,o){return Ue.isNode&&b.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...t})}const Vi=Ka;function Ja(e){if(e>Vi)throw new j("FormData field is too deeply nested ("+e+" levels). Max depth: "+Vi,j.ERR_FORM_DATA_DEPTH_EXCEEDED)}function hh(e){const t=[],n=/\w+|\[(\w*)]/g;let s;for(;(s=n.exec(e))!==null;)Ja(t.length),t.push(s[0]==="[]"?"":s[1]||s[0]);return t}function mh(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&b.isArray(r)?r.length:i,a?(b.hasOwnProp(r,i)?r[i]=b.isArray(r[i])?r[i].concat(s):[r[i],s]:r[i]=s,!l):((!b.hasOwnProp(r,i)||!b.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&b.isArray(r[i])&&(r[i]=mh(r[i])),!l)}if(b.isFormData(e)&&b.isFunction(e.entries)){const n={};return b.forEachEntry(e,(s,r)=>{t(hh(s),r,n,0)}),n}return null}const pn=(e,t)=>e!=null&&b.hasOwnProp(e,t)?e[t]:void 0;function gh(e,t,n){if(b.isString(e))try{return(t||JSON.parse)(e),b.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const fs={transitional:bo,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=b.isObject(t);if(o&&b.isHTMLForm(t)&&(t=new FormData(t)),b.isFormData(t))return r?JSON.stringify(Xa(t)):t;if(b.isArrayBuffer(t)||b.isBuffer(t)||b.isStream(t)||b.isFile(t)||b.isBlob(t)||b.isReadableStream(t))return t;if(b.isArrayBufferView(t))return t.buffer;if(b.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){const a=pn(this,"formSerializer");if(s.indexOf("application/x-www-form-urlencoded")>-1)return ph(t,a).toString();if((l=b.isFileList(t))||s.indexOf("multipart/form-data")>-1){const u=pn(this,"env"),c=u&&u.FormData;return Zs(l?{"files[]":t}:t,c&&new c,a)}}return o||r?(n.setContentType("application/json",!1),gh(t)):t}],transformResponse:[function(t){const n=pn(this,"transitional")||fs.transitional,s=n&&n.forcedJSONParsing,r=pn(this,"responseType"),o=r==="json";if(b.isResponse(t)||b.isReadableStream(t))return t;if(t&&b.isString(t)&&(s&&!r||o)){const l=!(n&&n.silentJSONParsing)&&o;try{return JSON.parse(t,pn(this,"parseReviver"))}catch(a){if(l)throw a.name==="SyntaxError"?j.from(a,j.ERR_BAD_RESPONSE,this,null,pn(this,"response")):a}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:Ue.classes.FormData,Blob:Ue.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};b.forEach(["delete","get","head","post","put","patch","query"],e=>{fs.headers[e]={}});function vr(e,t){const n=this||fs,s=t||n,r=Ke.from(s.headers);let o=s.data;return b.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function Qa(e){return!!(e&&e.__CANCEL__)}let ds=class extends j{constructor(t,n,s){super(t??"canceled",j.ERR_CANCELED,n,s),this.name="CanceledError",this.__CANCEL__=!0}};function Ya(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new j("Request failed with status code "+n.status,n.status>=400&&n.status<500?j.ERR_BAD_REQUEST:j.ERR_BAD_RESPONSE,n.config,n.request,n))}function yh(e){const t=/^([-+\w]{1,25}):(?:\/\/)?/.exec(e);return t&&t[1]||""}function bh(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(a){const u=Date.now(),c=s[o];i||(i=u),n[r]=a,s[r]=u;let f=o,d=0;for(;f!==r;)d+=n[f++],f=f%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),u-i{n=c,r=null,o&&(clearTimeout(o),o=null),e(...u)};return[(...u)=>{const c=Date.now(),f=c-n;f>=s?i(u,c):(r=u,o||(o=setTimeout(()=>{o=null,i(r)},s-f)))},()=>r&&i(r)]}const Ls=(e,t,n=3)=>{let s=0;const r=bh(50,250);return xh(o=>{if(!o||typeof o.loaded!="number")return;const i=o.loaded,l=o.lengthComputable?o.total:void 0,a=l!=null?Math.min(i,l):i,u=Math.max(0,a-s),c=r(u);s=Math.max(s,a);const f={loaded:a,total:l,progress:l?a/l:void 0,bytes:u,rate:c||void 0,estimated:c&&l?(l-a)/c:void 0,event:o,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(f)},n)},Mi=(e,t)=>{const n=e!=null;return[s=>t[0]({lengthComputable:n,total:e,loaded:s}),t[1]]},Bi=e=>(...t)=>b.asap(()=>e(...t)),vh=Ue.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,Ue.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(Ue.origin),Ue.navigator&&/(msie|trident)/i.test(Ue.navigator.userAgent)):()=>!0,_h=Ue.hasStandardBrowserEnv?{write(e,t,n,s,r,o,i){if(typeof document>"u")return;const l=[`${e}=${encodeURIComponent(t)}`];b.isNumber(n)&&l.push(`expires=${new Date(n).toUTCString()}`),b.isString(s)&&l.push(`path=${s}`),b.isString(r)&&l.push(`domain=${r}`),o===!0&&l.push("secure"),b.isString(i)&&l.push(`SameSite=${i}`),document.cookie=l.join("; ")},read(e){if(typeof document>"u")return null;const t=document.cookie.split(";");for(let n=0;ne instanceof Ke?{...e}:e;function fn(e,t){e=e||{},t=t||{};const n=Object.create(null);Object.defineProperty(n,"hasOwnProperty",{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function s(c,f,d,m){return b.isPlainObject(c)&&b.isPlainObject(f)?b.merge.call({caseless:m},c,f):b.isPlainObject(f)?b.merge({},f):b.isArray(f)?f.slice():f}function r(c,f,d,m){if(b.isUndefined(f)){if(!b.isUndefined(c))return s(void 0,c,d,m)}else return s(c,f,d,m)}function o(c,f){if(!b.isUndefined(f))return s(void 0,f)}function i(c,f){if(b.isUndefined(f)){if(!b.isUndefined(c))return s(void 0,c)}else return s(void 0,f)}function l(c){const f=b.hasOwnProp(t,"transitional")?t.transitional:void 0;if(!b.isUndefined(f))if(b.isPlainObject(f)){if(b.hasOwnProp(f,c))return f[c]}else return;const d=b.hasOwnProp(e,"transitional")?e.transitional:void 0;if(b.isPlainObject(d)&&b.hasOwnProp(d,c))return d[c]}function a(c,f,d){if(b.hasOwnProp(t,d))return s(c,f);if(b.hasOwnProp(e,d))return s(void 0,c)}const u={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,allowedSocketPaths:i,responseEncoding:i,validateStatus:a,headers:(c,f,d)=>r(Hi(c),Hi(f),d,!0)};return b.forEach(Object.keys({...e,...t}),function(f){if(f==="__proto__"||f==="constructor"||f==="prototype")return;const d=b.hasOwnProp(u,f)?u[f]:r,m=b.hasOwnProp(e,f)?e[f]:void 0,R=b.hasOwnProp(t,f)?t[f]:void 0,A=d(m,R,f);b.isUndefined(A)&&d!==a||(n[f]=A)}),b.hasOwnProp(t,"validateStatus")&&b.isUndefined(t.validateStatus)&&l("validateStatusUndefinedResolves")===!1&&(b.hasOwnProp(e,"validateStatus")?n.validateStatus=s(void 0,e.validateStatus):delete n.validateStatus),n}const Th=["content-type","content-length"];function Oh(e,t,n){if(n!=="content-only"){e.set(t);return}Object.entries(t||{}).forEach(([s,r])=>{Th.includes(s.toLowerCase())&&e.set(s,r)})}const Ph=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(t,n)=>String.fromCharCode(parseInt(n,16)));function eu(e){const t=fn({},e),n=d=>b.hasOwnProp(t,d)?t[d]:void 0,s=n("data");let r=n("withXSRFToken");const o=n("xsrfHeaderName"),i=n("xsrfCookieName");let l=n("headers");const a=n("auth"),u=n("baseURL"),c=n("allowAbsoluteUrls"),f=n("url");if(t.headers=l=Ke.from(l),t.url=za(Za(u,f,c,t),n("params"),n("paramsSerializer")),a){const d=b.getSafeProp(a,"username")||"",m=b.getSafeProp(a,"password")||"";try{l.set("Authorization","Basic "+btoa(d+":"+(m?Ph(m):"")))}catch(R){throw j.from(R,j.ERR_BAD_OPTION_VALUE,e)}}if(b.isFormData(s)&&(Ue.hasStandardBrowserEnv||Ue.hasStandardBrowserWebWorkerEnv||b.isReactNative(s)?l.setContentType(void 0):b.isFunction(s.getHeaders)&&Oh(l,s.getHeaders(),n("formDataHeaderPolicy"))),Ue.hasStandardBrowserEnv&&(b.isFunction(r)&&(r=r(t)),r===!0||r==null&&vh(t.url))){const m=o&&i&&_h.read(i);m&&l.set(o,m)}return t}const Nh=typeof XMLHttpRequest<"u",Ih=Nh&&function(e){return new Promise(function(n,s){const r=eu(e);let o=r.data;const i=Ke.from(r.headers).normalize();let{responseType:l,onUploadProgress:a,onDownloadProgress:u}=r,c,f,d,m,R;function A(){m&&m(),R&&R(),r.cancelToken&&r.cancelToken.unsubscribe(c),r.signal&&r.signal.removeEventListener("abort",c)}let O=new XMLHttpRequest;O.open(r.method.toUpperCase(),r.url,!0),O.timeout=r.timeout;function E(){if(!O)return;const v=Ke.from("getAllResponseHeaders"in O&&O.getAllResponseHeaders()),x={data:!l||l==="text"||l==="json"?O.responseText:O.response,status:O.status,statusText:O.statusText,headers:v,config:e,request:O};Ya(function(C){n(C),A()},function(C){s(C),A()},x),O=null}"onloadend"in O?O.onloadend=E:O.onreadystatechange=function(){!O||O.readyState!==4||O.status===0&&!(O.responseURL&&O.responseURL.startsWith("file:"))||setTimeout(E)},O.onabort=function(){O&&(s(new j("Request aborted",j.ECONNABORTED,e,O)),A(),O=null)},O.onerror=function(g){const x=g&&g.message?g.message:"Network Error",I=new j(x,j.ERR_NETWORK,e,O);I.event=g||null,s(I),A(),O=null},O.ontimeout=function(){let g=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const x=r.transitional||bo;r.timeoutErrorMessage&&(g=r.timeoutErrorMessage),s(new j(g,x.clarifyTimeoutError?j.ETIMEDOUT:j.ECONNABORTED,e,O)),A(),O=null},o===void 0&&i.setContentType(null),"setRequestHeader"in O&&b.forEach(Ha(i),function(g,x){O.setRequestHeader(x,g)}),b.isUndefined(r.withCredentials)||(O.withCredentials=!!r.withCredentials),l&&l!=="json"&&(O.responseType=r.responseType),u&&([d,R]=Ls(u,!0),O.addEventListener("progress",d)),a&&O.upload&&([f,m]=Ls(a),O.upload.addEventListener("progress",f),O.upload.addEventListener("loadend",m)),(r.cancelToken||r.signal)&&(c=v=>{O&&(s(!v||v.type?new ds(null,e,O):v),O.abort(),A(),O=null)},r.cancelToken&&r.cancelToken.subscribe(c),r.signal&&(r.signal.aborted?c():r.signal.addEventListener("abort",c)));const w=yh(r.url);if(w&&!Ue.protocols.includes(w)){s(new j("Unsupported protocol "+w+":",j.ERR_BAD_REQUEST,e)),A();return}O.send(o||null)})},kh=(e,t)=>{if(e=e?e.filter(Boolean):[],!t&&!e.length)return;const n=new AbortController;let s=!1;const r=function(a){if(!s){s=!0,i();const u=a instanceof Error?a:this.reason;n.abort(u instanceof j?u:new ds(u instanceof Error?u.message:u))}};let o=t&&setTimeout(()=>{o=null,r(new j(`timeout of ${t}ms exceeded`,j.ETIMEDOUT))},t);const i=()=>{e&&(o&&clearTimeout(o),o=null,e.forEach(a=>{a.unsubscribe?a.unsubscribe(r):a.removeEventListener("abort",r)}),e=null)};e.forEach(a=>a.addEventListener("abort",r,{once:!0}));const{signal:l}=n;return l.unsubscribe=()=>b.asap(i),l},Dh=function*(e,t){let n=e.byteLength;if(n{const r=$h(e,t);let o=0,i,l=a=>{i||(i=!0,s&&s(a))};return new ReadableStream({async pull(a){try{const{done:u,value:c}=await r.next();if(u){l(),a.close();return}let f=c.byteLength;if(n){let d=o+=f;n(d)}a.enqueue(new Uint8Array(c))}catch(u){throw l(u),u}},cancel(a){return l(a),r.return()}},{highWaterMark:2})},Us=e=>e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102,Uh=(e,t,n)=>t+2m>=2&&s.charCodeAt(m-2)===37&&s.charCodeAt(m-1)===51&&(s.charCodeAt(m)===68||s.charCodeAt(m)===100);u>=0&&(s.charCodeAt(u)===61?(a++,u--):c(u)&&(a++,u-=3)),a===1&&u>=0&&(s.charCodeAt(u)===61||c(u))&&a++;const d=Math.floor(i/4)*3-(a||0);return d>0?d:0}let o=0;for(let i=0,l=s.length;i=55296&&a<=56319&&i+1=56320&&u<=57343?(o+=4,i++):o+=3}else o+=3}return o}const vo="1.18.1",Ki=64*1024,{isFunction:bs}=b,Vh=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(t,n)=>String.fromCharCode(parseInt(n,16))),Wi=e=>{if(!b.isString(e))return e;try{return decodeURIComponent(e)}catch{return e}},Gi=(e,...t)=>{try{return!!e(...t)}catch{return!1}},Mh=e=>{const t=e.indexOf("://");let n=e;return t!==-1&&(n=n.slice(t+3)),n.includes("@")||n.includes(":")},Bh=e=>{const t=b.global!==void 0&&b.global!==null?b.global:globalThis,{ReadableStream:n,TextEncoder:s}=t;e=b.merge.call({skipUndefined:!0},{Request:t.Request,Response:t.Response},e);const{fetch:r,Request:o,Response:i}=e,l=r?bs(r):typeof fetch=="function",a=bs(o),u=bs(i);if(!l)return!1;const c=l&&bs(n),f=l&&(typeof s=="function"?(E=>w=>E.encode(w))(new s):async E=>new Uint8Array(await new o(E).arrayBuffer())),d=a&&c&&Gi(()=>{let E=!1;const w=new o(Ue.origin,{body:new n,method:"POST",get duplex(){return E=!0,"half"}}),v=w.headers.has("Content-Type");return w.body!=null&&w.body.cancel(),E&&!v}),m=u&&c&&Gi(()=>b.isReadableStream(new i("").body)),R={stream:m&&(E=>E.body)};l&&["text","arrayBuffer","blob","formData","stream"].forEach(E=>{!R[E]&&(R[E]=(w,v)=>{let g=w&&w[E];if(g)return g.call(w);throw new j(`Response type '${E}' is not supported`,j.ERR_NOT_SUPPORT,v)})});const A=async E=>{if(E==null)return 0;if(b.isBlob(E))return E.size;if(b.isSpecCompliantForm(E))return(await new o(Ue.origin,{method:"POST",body:E}).arrayBuffer()).byteLength;if(b.isArrayBufferView(E)||b.isArrayBuffer(E))return E.byteLength;if(b.isURLSearchParams(E)&&(E=E+""),b.isString(E))return(await f(E)).byteLength},O=async(E,w)=>{const v=b.toFiniteNumber(E.getContentLength());return v??A(w)};return async E=>{let{url:w,method:v,data:g,signal:x,cancelToken:I,timeout:C,onDownloadProgress:U,onUploadProgress:k,responseType:Q,headers:G,withCredentials:B="same-origin",fetchOptions:oe,maxContentLength:ie,maxBodyLength:ke}=eu(E);const xe=b.isNumber(ie)&&ie>-1,ae=b.isNumber(ke)&&ke>-1,ue=ne=>b.hasOwnProp(E,ne)?E[ne]:void 0;let nt=r||fetch;Q=Q?(Q+"").toLowerCase():"text";let De=kh([x,I&&I.toAbortSignal()],C),ye=null;const Re=De&&De.unsubscribe&&(()=>{De.unsubscribe()});let Ze,st=null;const ht=()=>new j("Request body larger than maxBodyLength limit",j.ERR_BAD_REQUEST,E,ye);try{let ne;const N=ue("auth");if(N){const S=b.getSafeProp(N,"username")||"",T=b.getSafeProp(N,"password")||"";ne={username:S,password:T}}if(Mh(w)){const S=new URL(w,Ue.origin);if(!ne&&(S.username||S.password)){const T=Wi(S.username),M=Wi(S.password);ne={username:T,password:M}}(S.username||S.password)&&(S.username="",S.password="",w=S.href)}if(ne&&(G.delete("authorization"),G.set("Authorization","Basic "+btoa(Vh((ne.username||"")+":"+(ne.password||""))))),xe&&typeof w=="string"&&w.startsWith("data:")&&Fh(w)>ie)throw new j("maxContentLength size of "+ie+" exceeded",j.ERR_BAD_RESPONSE,E,ye);if(ae&&v!=="get"&&v!=="head"){const S=await A(g);if(typeof S=="number"&&isFinite(S)&&(Ze=S,S>ke))throw ht()}const K=ae&&(b.isReadableStream(g)||b.isStream(g)),H=(S,T,M)=>qi(S,Ki,F=>{if(ae&&F>ke)throw st=ht();T&&T(F)},M);if(d&&v!=="get"&&v!=="head"&&(k||K)){if(Ze=Ze??await O(G,g),Ze!==0||K){let S=new o(w,{method:"POST",body:g,duplex:"half"}),T;if(b.isFormData(g)&&(T=S.headers.get("content-type"))&&G.setContentType(T),S.body){const[M,F]=k&&Mi(Ze,Ls(Bi(k)))||[];g=H(S.body,M,F)}}}else if(K&&!a&&c&&v!=="get"&&v!=="head")g=H(g);else if(K&&a&&!d&&v!=="get"&&v!=="head")throw new j("Stream request bodies are not supported by the current fetch implementation",j.ERR_NOT_SUPPORT,E,ye);b.isString(B)||(B=B?"include":"omit");const X=a&&"credentials"in o.prototype;if(b.isFormData(g)){const S=G.getContentType();S&&/^multipart\/form-data/i.test(S)&&!/boundary=/i.test(S)&&G.delete("content-type")}G.set("User-Agent","axios/"+vo,!1);const re={...oe,signal:De,method:v.toUpperCase(),headers:Ha(G.normalize()),body:g,duplex:"half",credentials:X?B:void 0};ye=a&&new o(w,re);let h=await(a?nt(ye,oe):nt(w,re));const y=Ke.from(h.headers);if(xe){const S=b.toFiniteNumber(y.getContentLength());if(S!=null&&S>ie)throw new j("maxContentLength size of "+ie+" exceeded",j.ERR_BAD_RESPONSE,E,ye)}const _=m&&(Q==="stream"||Q==="response");if(m&&h.body&&(U||xe||_&&Re)){const S={};["status","statusText","headers"].forEach(J=>{S[J]=h[J]});const T=b.toFiniteNumber(y.getContentLength()),[M,F]=U&&Mi(T,Ls(Bi(U),!0))||[];let V=0;const $=J=>{if(xe&&(V=J,V>ie))throw new j("maxContentLength size of "+ie+" exceeded",j.ERR_BAD_RESPONSE,E,ye);M&&M(J)};h=new i(qi(h.body,Ki,$,()=>{F&&F(),Re&&Re()}),S)}Q=Q||"text";let P=await R[b.findKey(R,Q)||"text"](h,E);if(xe&&!m&&!_){let S;if(P!=null&&(typeof P.byteLength=="number"?S=P.byteLength:typeof P.size=="number"?S=P.size:typeof P=="string"&&(S=typeof s=="function"?new s().encode(P).byteLength:P.length)),typeof S=="number"&&S>ie)throw new j("maxContentLength size of "+ie+" exceeded",j.ERR_BAD_RESPONSE,E,ye)}return!_&&Re&&Re(),await new Promise((S,T)=>{Ya(S,T,{data:P,headers:Ke.from(h.headers),status:h.status,statusText:h.statusText,config:E,request:ye})})}catch(ne){if(Re&&Re(),De&&De.aborted&&De.reason instanceof j){const N=De.reason;throw N.config=E,ye&&(N.request=ye),ne!==N&&Object.defineProperty(N,"cause",{__proto__:null,value:ne,writable:!0,enumerable:!1,configurable:!0}),N}if(st)throw ye&&!st.request&&(st.request=ye),st;if(ne instanceof j)throw ye&&!ne.request&&(ne.request=ye),ne;if(ne&&ne.name==="TypeError"&&/Load failed|fetch/i.test(ne.message)){const N=new j("Network Error",j.ERR_NETWORK,E,ye,ne&&ne.response);throw Object.defineProperty(N,"cause",{__proto__:null,value:ne.cause||ne,writable:!0,enumerable:!1,configurable:!0}),N}throw j.from(ne,ne&&ne.code,E,ye,ne&&ne.response)}}},jh=new Map,tu=e=>{let t=e&&e.env||{};const{fetch:n,Request:s,Response:r}=t,o=[s,r,n];let i=o.length,l=i,a,u,c=jh;for(;l--;)a=o[l],u=c.get(a),u===void 0&&c.set(a,u=l?new Map:Bh(t)),c=u;return u};tu();const _o={http:th,xhr:Ih,fetch:{get:tu}};b.forEach(_o,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{__proto__:null,value:t})}catch{}Object.defineProperty(e,"adapterName",{__proto__:null,value:t})}});const zi=e=>`- ${e}`,Hh=e=>b.isFunction(e)||e===null||e===!1;function qh(e,t){e=b.isArray(e)?e:[e];const{length:n}=e;let s,r;const o={};for(let i=0;i`adapter ${a} `+(u===!1?"is not supported by the environment":"is not available in the build"));let l=n?i.length>1?`since : +`+i.map(zi).join(` +`):" "+zi(i[0]):"as no adapter specified";throw new j("There is no suitable adapter to dispatch the request "+l,j.ERR_NOT_SUPPORT)}return r}const nu={getAdapter:qh,adapters:_o};function _r(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new ds(null,e)}function Ji(e){return _r(e),e.headers=Ke.from(e.headers),e.data=vr.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),nu.getAdapter(e.adapter||fs.adapter,e)(e).then(function(s){_r(e),e.response=s;try{s.data=vr.call(e,e.transformResponse,s)}finally{delete e.response}return s.headers=Ke.from(s.headers),s},function(s){if(!Qa(s)&&(_r(e),s&&s.response)){e.response=s.response;try{s.response.data=vr.call(e,e.transformResponse,s.response)}finally{delete e.response}s.response.headers=Ke.from(s.response.headers)}return Promise.reject(s)})}const er={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{er[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const Xi={};er.transitional=function(t,n,s){function r(o,i){return"[Axios v"+vo+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new j(r(i," has been removed"+(n?" in "+n:"")),j.ERR_DEPRECATED);return n&&!Xi[i]&&(Xi[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};er.spelling=function(t){return(n,s)=>(console.warn(`${s} is likely a misspelling of ${t}`),!0)};function Kh(e,t,n){if(typeof e!="object"||e===null)throw new j("options must be an object",j.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=Object.prototype.hasOwnProperty.call(t,o)?t[o]:void 0;if(i){const l=e[o],a=l===void 0||i(l,o,e);if(a!==!0)throw new j("option "+o+" must be "+a,j.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new j("Unknown option "+o,j.ERR_BAD_OPTION)}}const Cs={assertOptions:Kh,validators:er},Me=Cs.validators;let ln=class{constructor(t){this.defaults=t||{},this.interceptors={request:new Fi,response:new Fi}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r={};Error.captureStackTrace?Error.captureStackTrace(r):r=new Error;const o=(()=>{if(!r.stack)return"";const i=r.stack.indexOf(` +`);return i===-1?"":r.stack.slice(i+1)})();try{if(!s.stack)s.stack=o;else if(o){const i=o.indexOf(` +`),l=i===-1?-1:o.indexOf(` +`,i+1),a=l===-1?"":o.slice(l+1);String(s.stack).endsWith(a)||(s.stack+=` +`+o)}}catch{}}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=fn(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Cs.assertOptions(s,{silentJSONParsing:Me.transitional(Me.boolean),forcedJSONParsing:Me.transitional(Me.boolean),clarifyTimeoutError:Me.transitional(Me.boolean),legacyInterceptorReqResOrdering:Me.transitional(Me.boolean),advertiseZstdAcceptEncoding:Me.transitional(Me.boolean),validateStatusUndefinedResolves:Me.transitional(Me.boolean)},!1),r!=null&&(b.isFunction(r)?n.paramsSerializer={serialize:r}:Cs.assertOptions(r,{encode:Me.function,serialize:Me.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Cs.assertOptions(n,{baseUrl:Me.spelling("baseURL"),withXsrfToken:Me.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&b.merge(o.common,o[n.method]);o&&b.forEach(["delete","get","head","post","put","patch","query","common"],R=>{delete o[R]}),n.headers=Ke.concat(i,o);const l=[];let a=!0;this.interceptors.request.forEach(function(A){if(typeof A.runWhen=="function"&&A.runWhen(n)===!1)return;a=a&&A.synchronous;const O=n.transitional||bo;O&&O.legacyInterceptorReqResOrdering?l.unshift(A.fulfilled,A.rejected):l.push(A.fulfilled,A.rejected)});const u=[];this.interceptors.response.forEach(function(A){u.push(A.fulfilled,A.rejected)});let c,f=0,d;if(!a){const R=[Ji.bind(this),void 0];for(R.unshift(...l),R.push(...u),d=R.length,c=Promise.resolve(n);f{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new ds(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=s=>{t.abort(s)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new su(function(r){t=r}),cancel:t}}};function Gh(e){return function(n){return e.apply(null,n)}}function zh(e){return b.isObject(e)&&e.isAxiosError===!0}const qr={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(qr).forEach(([e,t])=>{qr[t]=e});function ru(e){const t=new ln(e),n=Da(ln.prototype.request,t);return b.extend(n,ln.prototype,t,{allOwnKeys:!0}),b.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return ru(fn(e,r))},n}const Te=ru(fs);Te.Axios=ln;Te.CanceledError=ds;Te.CancelToken=Wh;Te.isCancel=Qa;Te.VERSION=vo;Te.toFormData=Zs;Te.AxiosError=j;Te.Cancel=Te.CanceledError;Te.all=function(t){return Promise.all(t)};Te.spread=Gh;Te.isAxiosError=zh;Te.mergeConfig=fn;Te.AxiosHeaders=Ke;Te.formToJSON=e=>Xa(b.isHTMLForm(e)?new FormData(e):e);Te.getAdapter=nu.getAdapter;Te.HttpStatusCode=qr;Te.default=Te;const{Axios:Hb,AxiosError:qb,CanceledError:Kb,isCancel:Wb,CancelToken:Gb,VERSION:zb,all:Jb,Cancel:Xb,isAxiosError:Qb,spread:Yb,toFormData:Zb,AxiosHeaders:e0,HttpStatusCode:t0,formToJSON:n0,getAdapter:s0,mergeConfig:r0,create:o0}=Te;var Qi;const Jh=((Qi=window.SUB_STORE_CONFIG)==null?void 0:Qi.apiBaseUrl)||"",de=Te.create({baseURL:Jh+"/api",timeout:3e4});de.interceptors.request.use(e=>{const t=Xd();return t&&(e.headers.Authorization=`Bearer ${t}`),e});de.interceptors.response.use(e=>e.data,e=>{var n,s,r,o;((n=e.response)==null?void 0:n.status)===401&&ka();const t=((o=(r=(s=e.response)==null?void 0:s.data)==null?void 0:r.error)==null?void 0:o.message)||e.message||"Request failed";return Promise.reject(new Error(t))});const ou=()=>de.get("/env"),Xh=()=>de.get("/settings"),Qh=e=>de.patch("/settings",e),Yh=()=>de.get("/storage"),Zh=e=>de.post("/storage",e),tr=()=>de.get("/sources"),em=e=>de.post("/sources",e),tm=(e,t)=>de.patch(`/sources/${e}`,t),nm=e=>de.delete(`/sources/${e}`),wo=()=>de.get("/collections"),sm=e=>de.post("/collections",e),rm=(e,t)=>de.patch(`/collections/${e}`,t),om=e=>de.delete(`/collections/${e}`),Eo=()=>de.get("/templates"),im=e=>de.post("/templates",e),lm=(e,t)=>de.patch(`/templates/${e}`,t),am=e=>de.delete(`/templates/${e}`),iu=()=>de.get("/shares"),um=e=>de.post("/shares",e),cm=(e,t)=>de.patch(`/shares/${e}`,t),fm=e=>de.delete(`/shares/${e}`),dm=()=>de.get("/recycle-bin"),pm=e=>de.delete(`/recycle-bin/${e}`),hm=e=>de.post(`/recycle-bin/${e}/restore`),mm=e=>de.post("/preview/source",e),gm=(e,t)=>de.get(`/link/source/${e}`,{params:{}}),ym=(e,t)=>de.get(`/link/collection/${e}`,{params:{}}),bm=e=>de.post("/proxy/parse",e),xm=e=>de.post("/rule/parse",e),vm=e=>de.post("/utils/node-info",{server:e}),_m={class:"min-h-screen flex bg-gray-50"},wm={class:"w-60 bg-gray-900 text-gray-300 flex flex-col fixed inset-y-0 left-0 z-30"},Em={class:"px-5 py-4 border-b border-gray-700"},Sm={key:0,class:"text-xs text-gray-500 mt-0.5"},Rm={class:"flex-1 py-3 overflow-y-auto"},Cm={class:"text-base"},Am={class:"flex-1 ml-60 min-h-screen"},Tm={class:"px-6 py-5"},Om={__name:"AdminLayout",setup(e){const t=z(null),n=[{to:"/",icon:"📊",label:"概览"},{to:"/sources",icon:"📡",label:"订阅源"},{to:"/collections",icon:"📁",label:"合集"},{to:"/templates",icon:"📋",label:"模板"},{to:"/shares",icon:"🔗",label:"分享"},{to:"/recycle-bin",icon:"♻️",label:"回收站"},{to:"/tools",icon:"🔧",label:"工具"},{to:"/settings",icon:"⚙️",label:"设置"}];return Rt(async()=>{try{const s=await ou();t.value=s.data}catch{}}),(s,r)=>{const o=Pr("router-link"),i=Pr("router-view");return D(),L("div",_m,[p("aside",wm,[p("div",Em,[r[0]||(r[0]=p("h1",{class:"text-lg font-bold text-white flex items-center gap-2"},[p("span",{class:"inline-block w-2 h-2 bg-primary-500 rounded-full"}),un(" Sub-Store ")],-1)),t.value?(D(),L("p",Sm,q(t.value.backend)+" · "+q(t.value.version),1)):ce("",!0)]),p("nav",Rm,[(D(),L(fe,null,Ne(n,l=>we(o,{key:l.to,to:l.to,class:Ve(["flex items-center gap-3 px-5 py-2.5 text-sm transition-colors",s.$route.path===l.to||l.to!=="/"&&s.$route.path.startsWith(l.to)?"bg-gray-800 text-white border-l-2 border-primary-500":"hover:bg-gray-800/50 border-l-2 border-transparent"])},{default:lt(()=>[p("span",Cm,q(l.icon),1),p("span",null,q(l.label),1)]),_:2},1032,["to","class"])),64))]),r[1]||(r[1]=p("div",{class:"px-5 py-3 border-t border-gray-700 text-xs text-gray-500"},[p("p",null,"SQLite · Go")],-1))]),p("main",Am,[p("div",Tm,[we(i)])])])}}},Pm={class:"min-h-screen flex items-center justify-center bg-gray-50"},Nm={__name:"NotFound",setup(e){return(t,n)=>(D(),L("div",Pm,[...n[0]||(n[0]=[p("div",{class:"text-center"},[p("p",{class:"text-7xl font-bold text-gray-300"},"404"),p("p",{class:"mt-4 text-gray-400"},"Page Not Found")],-1)])]))}},Im={class:"grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6"},km={class:"text-sm text-gray-500"},Dm={class:"grid grid-cols-1 lg:grid-cols-2 gap-4"},$m={class:"bg-white rounded-lg p-4 shadow-sm border"},Lm={key:0,class:"space-y-1.5 text-sm"},Um={class:"flex justify-between"},Fm={class:"flex justify-between"},Vm={class:"flex justify-between"},Mm={class:"flex justify-between"},Bm={class:"flex justify-between"},jm={key:1,class:"text-gray-400 text-sm"},Hm={class:"bg-white rounded-lg p-4 shadow-sm border"},qm={key:0,class:"flex flex-wrap gap-2"},Km={__name:"Dashboard",setup(e){const t=z(null),n=z([]),s=z([]),r=z([]),o=z([]),i=Xe(()=>[{label:"订阅源",value:n.value.length,color:"text-blue-600"},{label:"合集",value:s.value.length,color:"text-purple-600"},{label:"模板",value:r.value.length,color:"text-green-600"},{label:"分享链接",value:o.value.length,color:"text-orange-600"}]),l={buildTimeScripts:"脚本引擎",proxyConversion:"代理转换",ruleConversion:"规则转换",scopedShares:"作用域分享",recycleBin:"回收站",nodeInfo:"节点信息",surgeMac:"Surge Mac"};return Rt(async()=>{try{const[a,u,c,f,d]=await Promise.all([ou(),tr(),wo(),Eo(),iu()]);t.value=a.data,n.value=u.data||[],s.value=c.data||[],r.value=f.data||[],o.value=d.data||[]}catch(a){console.error("Failed to load dashboard",a)}}),(a,u)=>{var c;return D(),L("div",null,[u[7]||(u[7]=p("h2",{class:"text-xl font-bold mb-5"},"概览",-1)),p("div",Im,[(D(!0),L(fe,null,Ne(i.value,f=>(D(),L("div",{key:f.label,class:"bg-white rounded-lg p-4 shadow-sm border"},[p("p",km,q(f.label),1),p("p",{class:Ve(["text-2xl font-bold mt-1",f.color])},q(f.value),3)]))),128))]),p("div",Dm,[p("div",$m,[u[5]||(u[5]=p("h3",{class:"font-semibold mb-3"},"环境信息",-1)),t.value?(D(),L("div",Lm,[p("div",Um,[u[0]||(u[0]=p("span",{class:"text-gray-500"},"应用",-1)),p("span",null,q(t.value.app),1)]),p("div",Fm,[u[1]||(u[1]=p("span",{class:"text-gray-500"},"后端",-1)),p("span",null,q(t.value.backend),1)]),p("div",Vm,[u[2]||(u[2]=p("span",{class:"text-gray-500"},"版本",-1)),p("span",null,q(t.value.version),1)]),p("div",Mm,[u[3]||(u[3]=p("span",{class:"text-gray-500"},"运行时",-1)),p("span",null,q(t.value.runtime),1)]),p("div",Bm,[u[4]||(u[4]=p("span",{class:"text-gray-500"},"存储",-1)),p("span",null,q(t.value.storage),1)])])):(D(),L("div",jm,"加载中..."))]),p("div",Hm,[u[6]||(u[6]=p("h3",{class:"font-semibold mb-3"},"功能特性",-1)),(c=t.value)!=null&&c.feature?(D(),L("div",qm,[(D(!0),L(fe,null,Ne(t.value.feature,(f,d)=>(D(),L("span",{key:d,class:Ve(["px-2 py-1 rounded text-xs",f?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"])},q(l[d]||d)+": "+q(f?"✓":"✗"),3))),128))])):ce("",!0)])])])}}},Wm={key:0,class:"fixed inset-0 z-50 flex items-center justify-center p-4"},Gm={class:"relative bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[85vh] flex flex-col"},zm={class:"flex items-center justify-between px-6 py-3 border-b"},Jm={class:"text-base font-semibold text-gray-900"},Xm={class:"flex-1 overflow-y-auto px-6 py-4"},Qm={key:0,class:"px-6 py-3 border-t flex justify-end gap-2"},os={__name:"Modal",props:{modelValue:Boolean,title:{type:String,default:""}},emits:["update:modelValue"],setup(e){return(t,n)=>(D(),an(Dl,{to:"body"},[e.modelValue?(D(),L("div",Wm,[p("div",{class:"absolute inset-0 bg-black/40",onClick:n[0]||(n[0]=s=>t.$emit("update:modelValue",!1))}),p("div",Gm,[p("div",zm,[p("h3",Jm,q(e.title),1),p("button",{class:"text-gray-400 hover:text-gray-600 text-xl",onClick:n[1]||(n[1]=s=>t.$emit("update:modelValue",!1))},"×")]),p("div",Xm,[Vo(t.$slots,"default")]),t.$slots.footer?(D(),L("div",Qm,[Vo(t.$slots,"footer")])):ce("",!0)])])):ce("",!0)]))}},Ym={key:0,class:"fixed inset-0 z-[60] flex items-center justify-center p-4"},Zm={class:"relative bg-white rounded-lg shadow-xl w-full max-w-sm p-5"},eg={class:"text-base font-semibold text-gray-900 mb-2"},tg={class:"text-sm text-gray-600 mb-4"},ng={class:"flex justify-end gap-2"},ps={__name:"ConfirmDialog",props:{modelValue:Boolean,title:{type:String,default:"确认"},message:{type:String,default:"确定执行此操作?"},confirmText:{type:String,default:"确定"},danger:{type:Boolean,default:!1}},emits:["update:modelValue","confirm"],setup(e){return(t,n)=>(D(),an(Dl,{to:"body"},[e.modelValue?(D(),L("div",Ym,[p("div",{class:"absolute inset-0 bg-black/40",onClick:n[0]||(n[0]=s=>t.$emit("update:modelValue",!1))}),p("div",Zm,[p("h3",eg,q(e.title),1),p("p",tg,q(e.message),1),p("div",ng,[p("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:n[1]||(n[1]=s=>t.$emit("update:modelValue",!1))},"取消"),p("button",{class:Ve(["px-4 py-2 text-sm rounded-lg text-white",e.danger?"bg-red-600 hover:bg-red-700":"bg-primary-600 hover:bg-primary-700"]),onClick:n[2]||(n[2]=s=>t.$emit("confirm"))},q(e.confirmText),3)])])])):ce("",!0)]))}},sg={key:0,class:"text-gray-400 text-sm"},rg={key:1,class:"text-gray-400 text-sm py-8 text-center"},og={key:2,class:"space-y-2"},ig={class:"flex-1 min-w-0"},lg={class:"flex items-center gap-2"},ag={class:"font-medium text-gray-900"},ug={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},cg={class:"text-xs text-gray-500 mt-1 truncate"},fg={class:"flex gap-2 mt-1 text-xs text-gray-400"},dg={key:0},pg={class:"flex gap-1 ml-3"},hg=["onClick"],mg=["onClick"],gg=["onClick"],yg=["onClick"],bg={class:"space-y-4"},xg=["disabled"],vg={key:0},_g={key:1},wg={class:"flex items-center gap-2"},Eg=["onUpdate:modelValue"],Sg=["value"],Rg=["onUpdate:modelValue"],Cg=["onUpdate:modelValue"],Ag=["onClick"],Tg={key:0,class:"text-gray-400 text-sm py-4 text-center"},Og={key:1},Pg={class:"text-xs text-gray-500 mb-2"},Ng={class:"max-h-96 overflow-y-auto text-xs font-mono bg-gray-50 p-3 rounded"},Ig={class:"text-gray-400"},kg={class:"text-blue-600"},Dg={class:"text-gray-400 ml-2"},$g={key:0,class:"text-gray-400 ml-2"},Lg={__name:"Sources",setup(e){const t=z([]),n=z(!0),s=z(!1),r=z(!1),o=z(!1),i=z(!1),l=z(null),a=z(null),u=z({show:!1,title:"",message:"",danger:!1,action:null}),c=["include","exclude","rename","dedupe","sort","delete-field","flag","quick","resolve","custom"],f=()=>({name:"",type:"remote",url:"",content:"",enabled:!0,filters:[]}),d=zt(f());function m(C,U="success"){a.value={msg:C,type:U},setTimeout(()=>a.value=null,2500)}function R(C){return C?new Date(C).toLocaleString("zh-CN"):""}function A(){Object.assign(d,f()),r.value=!1,s.value=!0}function O(C){Object.assign(d,{name:C.id,type:C.type||"remote",url:C.url||"",content:C.content||"",enabled:C.enabled!==!1,filters:JSON.parse(JSON.stringify(C.filters||[]))}),r.value=!0,s.value=!0}function E(){d.filters.push({type:"include",pattern:"",field:""})}async function w(){try{const C={name:d.name,type:d.type,url:d.url,content:d.content,enabled:d.enabled,filters:d.filters.filter(U=>U.type)};r.value?await tm(d.name,C):await em(C),s.value=!1,await I(),m(r.value?"已更新":"已创建")}catch(C){m(C.message,"error")}}async function v(C){u.value={show:!0,title:"删除订阅源",message:`确定删除 "${C.name}"?`,danger:!0,action:async()=>{try{await nm(C.id),await I(),m("已删除")}catch(U){m(U.message,"error")}}}}async function g(C){o.value=!0,i.value=!0,l.value=null;try{const U=await mm({id:C.id,name:C.name,type:C.type,url:C.url,content:C.content,filters:C.filters});l.value=U.data}catch(U){m(U.message,"error"),o.value=!1}finally{i.value=!1}}async function x(C){try{const U=await gm(C.id);await navigator.clipboard.writeText(U.data.url),m("链接已复制")}catch(U){m(U.message,"error")}}async function I(){n.value=!0;try{const C=await tr();t.value=C.data||[]}catch(C){m(C.message,"error")}finally{n.value=!1}}return Rt(I),(C,U)=>(D(),L("div",null,[p("div",{class:"flex items-center justify-between mb-5"},[U[10]||(U[10]=p("h2",{class:"text-xl font-bold"},"订阅源",-1)),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:A},"+ 新建")]),n.value?(D(),L("div",sg,"加载中...")):t.value.length===0?(D(),L("div",rg,"暂无订阅源")):(D(),L("div",og,[(D(!0),L(fe,null,Ne(t.value,k=>{var Q;return D(),L("div",{key:k.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between hover:shadow-md transition-shadow"},[p("div",ig,[p("div",lg,[p("span",ag,q(k.name),1),p("span",{class:Ve(["px-1.5 py-0.5 rounded text-xs",k.type==="remote"?"bg-blue-100 text-blue-700":"bg-gray-100 text-gray-600"])},q(k.type),3),k.enabled?ce("",!0):(D(),L("span",ug,"已禁用"))]),p("p",cg,q(k.type==="local"?"(本地内容)":k.url),1),p("div",fg,[p("span",null,"过滤器: "+q(((Q=k.filters)==null?void 0:Q.length)||0),1),k.createdAt?(D(),L("span",dg,"创建: "+q(R(k.createdAt)),1)):ce("",!0)])]),p("div",pg,[p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:G=>x(k)},"链接",8,hg),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:G=>g(k)},"预览",8,mg),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:G=>O(k)},"编辑",8,gg),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:G=>v(k)},"删除",8,yg)])])}),128))])),we(os,{modelValue:s.value,"onUpdate:modelValue":U[6]||(U[6]=k=>s.value=k),title:r.value?"编辑订阅源":"新建订阅源"},{footer:lt(()=>[p("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:U[5]||(U[5]=k=>s.value=!1)},"取消"),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:w},"保存")]),default:lt(()=>[p("div",bg,[p("div",null,[U[11]||(U[11]=p("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),se(p("input",{"onUpdate:modelValue":U[0]||(U[0]=k=>d.name=k),disabled:r.value,placeholder:"my-sub",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,xg),[[Ae,d.name]]),U[12]||(U[12]=p("p",{class:"text-xs text-gray-400 mt-0.5"},"仅支持小写字母、数字、下划线、连字符",-1))]),p("div",null,[U[14]||(U[14]=p("label",{class:"block text-sm font-medium mb-1"},"类型",-1)),se(p("select",{"onUpdate:modelValue":U[1]||(U[1]=k=>d.type=k),class:"w-full px-3 py-2 border rounded-lg text-sm"},[...U[13]||(U[13]=[p("option",{value:"remote"},"远程 (URL)",-1),p("option",{value:"local"},"本地 (内容)",-1)])],512),[[St,d.type]])]),d.type==="remote"?(D(),L("div",vg,[U[15]||(U[15]=p("label",{class:"block text-sm font-medium mb-1"},"URL",-1)),se(p("textarea",{"onUpdate:modelValue":U[2]||(U[2]=k=>d.url=k),rows:"3",placeholder:"https://example.com/sub (多个URL换行)",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[Ae,d.url]])])):ce("",!0),d.type==="local"?(D(),L("div",_g,[U[16]||(U[16]=p("label",{class:"block text-sm font-medium mb-1"},"内容",-1)),se(p("textarea",{"onUpdate:modelValue":U[3]||(U[3]=k=>d.content=k),rows:"6",placeholder:"ss://... 或 base64 内容",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[Ae,d.content]])])):ce("",!0),p("div",wg,[se(p("input",{type:"checkbox",id:"src-enabled","onUpdate:modelValue":U[4]||(U[4]=k=>d.enabled=k),class:"rounded"},null,512),[[wn,d.enabled]]),U[17]||(U[17]=p("label",{for:"src-enabled",class:"text-sm"},"启用",-1))]),p("div",null,[p("div",{class:"flex items-center justify-between mb-1"},[U[18]||(U[18]=p("label",{class:"text-sm font-medium"},"过滤器",-1)),p("button",{class:"text-xs text-primary-600 hover:underline",onClick:E},"+ 添加")]),(D(!0),L(fe,null,Ne(d.filters,(k,Q)=>(D(),L("div",{key:Q,class:"flex gap-1 mb-1.5"},[se(p("select",{"onUpdate:modelValue":G=>k.type=G,class:"px-2 py-1 border rounded text-xs w-28"},[(D(),L(fe,null,Ne(c,G=>p("option",{key:G,value:G},q(G),9,Sg)),64))],8,Eg),[[St,k.type]]),se(p("input",{"onUpdate:modelValue":G=>k.pattern=G,placeholder:"pattern",class:"flex-1 px-2 py-1 border rounded text-xs"},null,8,Rg),[[Ae,k.pattern]]),se(p("input",{"onUpdate:modelValue":G=>k.field=G,placeholder:"field",class:"w-24 px-2 py-1 border rounded text-xs"},null,8,Cg),[[Ae,k.field]]),p("button",{class:"px-2 py-1 text-xs text-red-500 hover:bg-red-50 rounded",onClick:G=>d.filters.splice(Q,1)},"×",8,Ag)]))),128))])])]),_:1},8,["modelValue","title"]),we(os,{modelValue:o.value,"onUpdate:modelValue":U[7]||(U[7]=k=>o.value=k),title:"预览结果"},{default:lt(()=>{var k,Q;return[i.value?(D(),L("div",Tg,"解析中...")):l.value?(D(),L("div",Og,[p("p",Pg,"原始节点: "+q(((k=l.value.original)==null?void 0:k.length)||0)+" · 处理后: "+q(((Q=l.value.processed)==null?void 0:Q.length)||0),1),p("div",Ng,[(D(!0),L(fe,null,Ne(l.value.processed||l.value.original||[],(G,B)=>(D(),L("div",{key:B,class:"py-0.5"},[p("span",Ig,q(B+1)+".",1),p("span",kg,q(G.name||G.remarks||"unnamed"),1),p("span",Dg,q(G.type),1),G.server?(D(),L("span",$g,q(G.server)+":"+q(G.port),1)):ce("",!0)]))),128))])])):ce("",!0)]}),_:1},8,["modelValue"]),we(ps,{modelValue:u.value.show,"onUpdate:modelValue":U[8]||(U[8]=k=>u.value.show=k),title:u.value.title,message:u.value.message,danger:u.value.danger,onConfirm:U[9]||(U[9]=k=>{u.value.action(),u.value.show=!1})},null,8,["modelValue","title","message","danger"]),a.value?(D(),L("div",{key:3,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",a.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(a.value.msg),3)):ce("",!0)]))}},Ug={key:0,class:"text-gray-400 text-sm"},Fg={key:1,class:"text-gray-400 text-sm py-8 text-center"},Vg={key:2,class:"space-y-2"},Mg={class:"flex-1 min-w-0"},Bg={class:"flex items-center gap-2"},jg={class:"font-medium text-gray-900"},Hg={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},qg={class:"flex gap-3 mt-1 text-xs text-gray-400"},Kg={key:0},Wg={class:"flex gap-1 ml-3"},Gg=["onClick"],zg=["onClick"],Jg=["onClick"],Xg={class:"space-y-4"},Qg=["disabled"],Yg={class:"max-h-32 overflow-y-auto border rounded-lg p-2 space-y-1"},Zg=["value"],ey={class:"text-xs text-gray-400"},ty={key:0,class:"text-xs text-gray-400 py-1"},ny=["value"],sy={class:"flex items-center gap-4"},ry={class:"flex items-center gap-2 text-sm"},oy={class:"flex items-center gap-2 text-sm"},iy={class:"flex items-center justify-between mb-1"},ly=["onUpdate:modelValue"],ay=["value"],uy=["onUpdate:modelValue"],cy=["onClick"],fy={__name:"Collections",setup(e){const t=z([]),n=z([]),s=z([]),r=z(!0),o=z(!1),i=z(!1),l=z(null),a=z({show:!1,title:"",message:"",danger:!1,action:null}),u=["include","exclude","rename","dedupe","sort","delete-field","flag","quick","resolve","custom"],c=()=>({name:"",sourceIds:[],filters:[],templateId:"",ignoreFailed:!0,enabled:!0}),f=zt(c());function d(v,g="success"){l.value={msg:v,type:g},setTimeout(()=>l.value=null,2500)}function m(){Object.assign(f,c()),i.value=!1,o.value=!0}function R(v){Object.assign(f,{name:v.id,sourceIds:[...v.sourceIds||[]],filters:JSON.parse(JSON.stringify(v.filters||[])),templateId:v.templateId||"",ignoreFailed:v.ignoreFailed!==!1,enabled:v.enabled!==!1}),i.value=!0,o.value=!0}async function A(){try{const v={...f};i.value?await rm(f.name,v):await sm(v),o.value=!1,await w(),d(i.value?"已更新":"已创建")}catch(v){d(v.message,"error")}}async function O(v){a.value={show:!0,title:"删除合集",message:`确定删除 "${v.name}"?`,danger:!0,action:async()=>{try{await om(v.id),await w(),d("已删除")}catch(g){d(g.message,"error")}}}}async function E(v){try{const g=await ym(v.id);await navigator.clipboard.writeText(g.data.url),d("链接已复制")}catch(g){d(g.message,"error")}}async function w(){r.value=!0;try{const[v,g,x]=await Promise.all([wo(),tr(),Eo()]);t.value=v.data||[],n.value=g.data||[],s.value=x.data||[]}catch(v){d(v.message,"error")}finally{r.value=!1}}return Rt(w),(v,g)=>(D(),L("div",null,[p("div",{class:"flex items-center justify-between mb-5"},[g[10]||(g[10]=p("h2",{class:"text-xl font-bold"},"合集",-1)),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:m},"+ 新建")]),r.value?(D(),L("div",Ug,"加载中...")):t.value.length===0?(D(),L("div",Fg,"暂无合集")):(D(),L("div",Vg,[(D(!0),L(fe,null,Ne(t.value,x=>{var I,C;return D(),L("div",{key:x.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between hover:shadow-md transition-shadow"},[p("div",Mg,[p("div",Bg,[p("span",jg,q(x.name),1),x.enabled?ce("",!0):(D(),L("span",Hg,"已禁用"))]),p("div",qg,[p("span",null,"订阅源: "+q(((I=x.sourceIds)==null?void 0:I.length)||0),1),p("span",null,"过滤器: "+q(((C=x.filters)==null?void 0:C.length)||0),1),p("span",null,"模板: "+q(x.templateId||"default"),1),x.ignoreFailed?(D(),L("span",Kg,"忽略失败")):ce("",!0)])]),p("div",Wg,[p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:U=>E(x)},"链接",8,Gg),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:U=>R(x)},"编辑",8,zg),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:U=>O(x)},"删除",8,Jg)])])}),128))])),we(os,{modelValue:o.value,"onUpdate:modelValue":g[7]||(g[7]=x=>o.value=x),title:i.value?"编辑合集":"新建合集"},{footer:lt(()=>[p("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:g[6]||(g[6]=x=>o.value=!1)},"取消"),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:A},"保存")]),default:lt(()=>[p("div",Xg,[p("div",null,[g[11]||(g[11]=p("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),se(p("input",{"onUpdate:modelValue":g[0]||(g[0]=x=>f.name=x),disabled:i.value,placeholder:"my-collection",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Qg),[[Ae,f.name]])]),p("div",null,[g[12]||(g[12]=p("label",{class:"block text-sm font-medium mb-1"},"订阅源 (多选)",-1)),p("div",Yg,[(D(!0),L(fe,null,Ne(n.value,x=>(D(),L("label",{key:x.id,class:"flex items-center gap-2 text-sm cursor-pointer hover:bg-gray-50 px-1 py-0.5 rounded"},[se(p("input",{type:"checkbox",value:x.id,"onUpdate:modelValue":g[1]||(g[1]=I=>f.sourceIds=I),class:"rounded"},null,8,Zg),[[wn,f.sourceIds]]),p("span",null,q(x.name),1),p("span",ey,"("+q(x.type)+")",1)]))),128)),n.value.length===0?(D(),L("p",ty,"无可用订阅源")):ce("",!0)])]),p("div",null,[g[14]||(g[14]=p("label",{class:"block text-sm font-medium mb-1"},"模板",-1)),se(p("select",{"onUpdate:modelValue":g[2]||(g[2]=x=>f.templateId=x),class:"w-full px-3 py-2 border rounded-lg text-sm"},[g[13]||(g[13]=p("option",{value:""},"默认",-1)),(D(!0),L(fe,null,Ne(s.value,x=>(D(),L("option",{key:x.id,value:x.id},q(x.name)+" ("+q(x.target)+")",9,ny))),128))],512),[[St,f.templateId]])]),p("div",sy,[p("label",ry,[se(p("input",{type:"checkbox","onUpdate:modelValue":g[3]||(g[3]=x=>f.enabled=x),class:"rounded"},null,512),[[wn,f.enabled]]),g[15]||(g[15]=un(" 启用 ",-1))]),p("label",oy,[se(p("input",{type:"checkbox","onUpdate:modelValue":g[4]||(g[4]=x=>f.ignoreFailed=x),class:"rounded"},null,512),[[wn,f.ignoreFailed]]),g[16]||(g[16]=un(" 忽略失败源 ",-1))])]),p("div",null,[p("div",iy,[g[17]||(g[17]=p("label",{class:"text-sm font-medium"},"过滤器",-1)),p("button",{class:"text-xs text-primary-600 hover:underline",onClick:g[5]||(g[5]=x=>f.filters.push({type:"include",pattern:""}))},"+ 添加")]),(D(!0),L(fe,null,Ne(f.filters,(x,I)=>(D(),L("div",{key:I,class:"flex gap-1 mb-1.5"},[se(p("select",{"onUpdate:modelValue":C=>x.type=C,class:"px-2 py-1 border rounded text-xs w-28"},[(D(),L(fe,null,Ne(u,C=>p("option",{key:C,value:C},q(C),9,ay)),64))],8,ly),[[St,x.type]]),se(p("input",{"onUpdate:modelValue":C=>x.pattern=C,placeholder:"pattern",class:"flex-1 px-2 py-1 border rounded text-xs"},null,8,uy),[[Ae,x.pattern]]),p("button",{class:"px-2 py-1 text-xs text-red-500 hover:bg-red-50 rounded",onClick:C=>f.filters.splice(I,1)},"×",8,cy)]))),128))])])]),_:1},8,["modelValue","title"]),we(ps,{modelValue:a.value.show,"onUpdate:modelValue":g[8]||(g[8]=x=>a.value.show=x),title:a.value.title,message:a.value.message,danger:a.value.danger,onConfirm:g[9]||(g[9]=x=>{a.value.action(),a.value.show=!1})},null,8,["modelValue","title","message","danger"]),l.value?(D(),L("div",{key:3,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",l.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(l.value.msg),3)):ce("",!0)]))}},dy={key:0,class:"text-gray-400 text-sm"},py={key:1,class:"text-gray-400 text-sm py-8 text-center"},hy={key:2,class:"space-y-2"},my={class:"flex-1 min-w-0"},gy={class:"flex items-center gap-2"},yy={class:"font-medium text-gray-900"},by={class:"px-1.5 py-0.5 rounded text-xs bg-purple-100 text-purple-700"},xy={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-gray-100 text-gray-500"},vy={class:"text-xs text-gray-500 mt-1"},_y={key:0,class:"flex gap-1 ml-3"},wy=["onClick"],Ey=["onClick"],Sy={key:1,class:"flex gap-1 ml-3"},Ry=["onClick"],Cy={class:"space-y-4"},Ay=["disabled"],Ty=["value"],Oy={key:0,class:"text-xs text-red-500 mt-1"},Py={class:"text-xs font-mono bg-gray-50 p-3 rounded max-h-96 overflow-auto"},Ny={__name:"Templates",setup(e){const t=z([]),n=z(!0),s=z(!1),r=z(!1),o=z(!1),i=z(null),l=z(null),a=z({show:!1,title:"",message:"",danger:!1,action:null}),u=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],c=()=>({name:"",target:"mihomo",configStr:"{}"}),f=zt(c()),d=Xe(()=>{try{return JSON.parse(f.configStr),""}catch{return"JSON 格式错误"}});function m(g,x="success"){l.value={msg:g,type:x},setTimeout(()=>l.value=null,2500)}function R(){Object.assign(f,c()),r.value=!1,s.value=!0}function A(g){Object.assign(f,{name:g.id,target:g.target,configStr:JSON.stringify(g.config||{},null,2)}),r.value=!0,s.value=!0}function O(g){i.value=g.config,o.value=!0}async function E(){if(d.value){m(d.value,"error");return}try{const g={name:f.name,target:f.target,config:JSON.parse(f.configStr)};r.value?await lm(f.name,g):await im(g),s.value=!1,await v(),m(r.value?"已更新":"已创建")}catch(g){m(g.message,"error")}}async function w(g){a.value={show:!0,title:"删除模板",message:`确定删除 "${g.name}"?`,danger:!0,action:async()=>{try{await am(g.id),await v(),m("已删除")}catch(x){m(x.message,"error")}}}}async function v(){n.value=!0;try{const g=await Eo();t.value=g.data||[]}catch(g){m(g.message,"error")}finally{n.value=!1}}return Rt(v),(g,x)=>(D(),L("div",null,[p("div",{class:"flex items-center justify-between mb-5"},[x[8]||(x[8]=p("h2",{class:"text-xl font-bold"},"模板",-1)),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:R},"+ 新建")]),n.value?(D(),L("div",dy,"加载中...")):t.value.length===0?(D(),L("div",py,"暂无模板")):(D(),L("div",hy,[(D(!0),L(fe,null,Ne(t.value,I=>(D(),L("div",{key:I.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between hover:shadow-md transition-shadow"},[p("div",my,[p("div",gy,[p("span",yy,q(I.name),1),p("span",by,q(I.target),1),I.readonly?(D(),L("span",xy,"内置")):ce("",!0)]),p("p",vy,q(Object.keys(I.config||{}).length)+" 个配置项",1)]),I.readonly?(D(),L("div",Sy,[p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:C=>O(I)},"查看",8,Ry)])):(D(),L("div",_y,[p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:C=>A(I)},"编辑",8,wy),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:C=>w(I)},"删除",8,Ey)]))]))),128))])),we(os,{modelValue:s.value,"onUpdate:modelValue":x[4]||(x[4]=I=>s.value=I),title:r.value?"编辑模板":"新建模板"},{footer:lt(()=>[p("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:x[3]||(x[3]=I=>s.value=!1)},"取消"),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:E},"保存")]),default:lt(()=>[p("div",Cy,[p("div",null,[x[9]||(x[9]=p("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),se(p("input",{"onUpdate:modelValue":x[0]||(x[0]=I=>f.name=I),disabled:r.value,placeholder:"my-template",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Ay),[[Ae,f.name]])]),p("div",null,[x[10]||(x[10]=p("label",{class:"block text-sm font-medium mb-1"},"目标平台",-1)),se(p("select",{"onUpdate:modelValue":x[1]||(x[1]=I=>f.target=I),class:"w-full px-3 py-2 border rounded-lg text-sm"},[(D(),L(fe,null,Ne(u,I=>p("option",{key:I,value:I},q(I),9,Ty)),64))],512),[[St,f.target]])]),p("div",null,[x[11]||(x[11]=p("label",{class:"block text-sm font-medium mb-1"},"配置 (JSON)",-1)),se(p("textarea",{"onUpdate:modelValue":x[2]||(x[2]=I=>f.configStr=I),rows:"12",placeholder:'{"proxy-groups": [], "rules": []}',class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[Ae,f.configStr]]),d.value?(D(),L("p",Oy,q(d.value),1)):ce("",!0)])])]),_:1},8,["modelValue","title"]),we(os,{modelValue:o.value,"onUpdate:modelValue":x[5]||(x[5]=I=>o.value=I),title:"查看模板配置"},{default:lt(()=>[p("pre",Py,q(JSON.stringify(i.value,null,2)),1)]),_:1},8,["modelValue"]),we(ps,{modelValue:a.value.show,"onUpdate:modelValue":x[6]||(x[6]=I=>a.value.show=I),title:a.value.title,message:a.value.message,danger:a.value.danger,onConfirm:x[7]||(x[7]=I=>{a.value.action(),a.value.show=!1})},null,8,["modelValue","title","message","danger"]),l.value?(D(),L("div",{key:3,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",l.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(l.value.msg),3)):ce("",!0)]))}},Iy={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},ky={class:"grid grid-cols-1 md:grid-cols-4 gap-2 mb-3"},Dy=["value"],$y=["value"],Ly=["disabled"],Uy={key:0,class:"text-gray-400 text-sm"},Fy={key:1,class:"text-gray-400 text-sm py-4 text-center"},Vy={key:2,class:"space-y-2"},My={class:"flex-1 min-w-0"},By={class:"flex items-center gap-2"},jy={class:"font-medium text-gray-900"},Hy={key:0,class:"text-xs text-gray-400"},qy={key:1,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},Ky={class:"text-xs text-gray-400 mt-1"},Wy={key:0},Gy={key:1},zy={class:"flex gap-1 ml-3"},Jy=["onClick"],Xy=["onClick"],Qy={__name:"Shares",setup(e){const t=z([]),n=z([]),s=z([]),r=z(!0),o=z(""),i=z(null),l=z({show:!1,title:"",message:"",danger:!1,action:null}),a=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],u=zt({resourceType:"source",resourceId:"",target:"",expiresHours:"0"}),c=Xe(()=>u.resourceType==="source"?n.value:s.value);function f(w,v="success"){i.value={msg:w,type:v},setTimeout(()=>i.value=null,2500)}function d(w){return w?new Date(w).toLocaleString("zh-CN"):""}async function m(w){await navigator.clipboard.writeText(w),f("已复制")}async function R(){try{const w={resourceType:u.resourceType,resourceId:u.resourceId,target:u.target||void 0,expiresIn:Math.max(0,Number(u.expiresHours)||0)*3600},v=await um(w);o.value=v.data.url,await E(),f("分享已创建")}catch(w){f(w.message,"error")}}async function A(w){try{await cm(w.id,{enabled:!w.enabled}),await E()}catch(v){f(v.message,"error")}}async function O(w){l.value={show:!0,title:"删除分享",message:"确定删除此分享?",danger:!0,action:async()=>{try{await fm(w.id),await E(),f("已删除")}catch(v){f(v.message,"error")}}}}async function E(){r.value=!0;try{const[w,v,g]=await Promise.all([iu(),tr(),wo()]);t.value=w.data||[],n.value=v.data||[],s.value=g.data||[]}catch(w){f(w.message,"error")}finally{r.value=!1}}return Rt(E),(w,v)=>(D(),L("div",null,[v[12]||(v[12]=p("h2",{class:"text-xl font-bold mb-5"},"分享链接",-1)),p("div",Iy,[v[11]||(v[11]=p("h3",{class:"font-semibold mb-3 text-sm"},"创建分享",-1)),p("div",ky,[se(p("select",{"onUpdate:modelValue":v[0]||(v[0]=g=>u.resourceType=g),class:"px-3 py-2 border rounded-lg text-sm"},[...v[7]||(v[7]=[p("option",{value:"source"},"订阅源",-1),p("option",{value:"collection"},"合集",-1)])],512),[[St,u.resourceType]]),se(p("select",{"onUpdate:modelValue":v[1]||(v[1]=g=>u.resourceId=g),class:"px-3 py-2 border rounded-lg text-sm"},[v[8]||(v[8]=p("option",{value:""},"选择资源",-1)),(D(!0),L(fe,null,Ne(c.value,g=>(D(),L("option",{key:g.id,value:g.id},q(g.name),9,Dy))),128))],512),[[St,u.resourceId]]),se(p("select",{"onUpdate:modelValue":v[2]||(v[2]=g=>u.target=g),class:"px-3 py-2 border rounded-lg text-sm"},[v[9]||(v[9]=p("option",{value:""},"自动",-1)),(D(),L(fe,null,Ne(a,g=>p("option",{key:g,value:g},q(g),9,$y)),64))],512),[[St,u.target]]),se(p("input",{"onUpdate:modelValue":v[3]||(v[3]=g=>u.expiresHours=g),type:"number",min:"0",placeholder:"有效小时(0=永久)",class:"px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,u.expiresHours]])]),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:!u.resourceId,onClick:R},"创建分享",8,Ly),o.value?(D(),L("div",{key:0,class:"mt-3 p-3 bg-gray-50 rounded-lg break-all text-xs font-mono cursor-pointer hover:bg-gray-100",onClick:v[4]||(v[4]=g=>m(o.value))},[un(q(o.value)+" ",1),v[10]||(v[10]=p("span",{class:"text-primary-600"},"[点击复制]",-1))])):ce("",!0)]),r.value?(D(),L("div",Uy,"加载中...")):t.value.length===0?(D(),L("div",Fy,"暂无分享")):(D(),L("div",Vy,[(D(!0),L(fe,null,Ne(t.value,g=>(D(),L("div",{key:g.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between"},[p("div",My,[p("div",By,[p("span",{class:Ve(["px-1.5 py-0.5 rounded text-xs",g.resourceType==="source"?"bg-blue-100 text-blue-700":"bg-purple-100 text-purple-700"])},q(g.resourceType),3),p("span",jy,q(g.resourceId),1),g.target?(D(),L("span",Hy,"→ "+q(g.target),1)):ce("",!0),g.enabled?ce("",!0):(D(),L("span",qy,"已禁用"))]),p("p",Ky,[un(" 创建: "+q(d(g.createdAt))+" ",1),g.expiresAt?(D(),L("span",Wy," · 过期: "+q(d(g.expiresAt)),1)):(D(),L("span",Gy," · 永久有效"))])]),p("div",zy,[p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:x=>A(g)},q(g.enabled?"禁用":"启用"),9,Jy),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:x=>O(g)},"删除",8,Xy)])]))),128))])),we(ps,{modelValue:l.value.show,"onUpdate:modelValue":v[5]||(v[5]=g=>l.value.show=g),title:l.value.title,message:l.value.message,danger:l.value.danger,onConfirm:v[6]||(v[6]=g=>{l.value.action(),l.value.show=!1})},null,8,["modelValue","title","message","danger"]),i.value?(D(),L("div",{key:3,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",i.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(i.value.msg),3)):ce("",!0)]))}},Yy={key:0,class:"text-gray-400 text-sm"},Zy={key:1,class:"text-gray-400 text-sm py-8 text-center"},eb={key:2,class:"space-y-2"},tb={class:"flex-1 min-w-0"},nb={class:"flex items-center gap-2"},sb={class:"font-medium text-gray-900"},rb={class:"text-xs text-gray-400 mt-1"},ob={class:"flex gap-1 ml-3"},ib=["onClick"],lb=["onClick"],ab={__name:"RecycleBin",setup(e){const t=z([]),n=z(!0),s=z(null),r=z({show:!1,title:"",message:"",danger:!1,confirmText:"确定",action:null});function o(f,d="success"){s.value={msg:f,type:d},setTimeout(()=>s.value=null,2500)}function i(f){return f?new Date(f).toLocaleString("zh-CN"):""}function l(f){return{source:"bg-blue-100 text-blue-700",collection:"bg-purple-100 text-purple-700",template:"bg-green-100 text-green-700",share:"bg-orange-100 text-orange-700"}[f]||"bg-gray-100 text-gray-600"}async function a(f){r.value={show:!0,title:"恢复",message:`恢复 "${f.resourceId}"?`,danger:!1,confirmText:"恢复",action:async()=>{try{await hm(f.id),await c(),o("已恢复")}catch(d){o(d.message,"error")}}}}async function u(f){r.value={show:!0,title:"彻底删除",message:`彻底删除 "${f.resourceId}"?此操作不可撤销!`,danger:!0,confirmText:"彻底删除",action:async()=>{try{await pm(f.id),await c(),o("已彻底删除")}catch(d){o(d.message,"error")}}}}async function c(){n.value=!0;try{const f=await dm();t.value=f.data||[]}catch(f){o(f.message,"error")}finally{n.value=!1}}return Rt(c),(f,d)=>(D(),L("div",null,[d[2]||(d[2]=p("h2",{class:"text-xl font-bold mb-5"},"回收站",-1)),n.value?(D(),L("div",Yy,"加载中...")):t.value.length===0?(D(),L("div",Zy,"回收站为空")):(D(),L("div",eb,[(D(!0),L(fe,null,Ne(t.value,m=>(D(),L("div",{key:m.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between"},[p("div",tb,[p("div",nb,[p("span",{class:Ve(["px-1.5 py-0.5 rounded text-xs",l(m.resourceType)])},q(m.resourceType),3),p("span",sb,q(m.resourceId),1)]),p("p",rb,"删除于: "+q(i(m.deletedAt)),1)]),p("div",ob,[p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:R=>a(m)},"恢复",8,ib),p("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:R=>u(m)},"彻底删除",8,lb)])]))),128))])),we(ps,{modelValue:r.value.show,"onUpdate:modelValue":d[0]||(d[0]=m=>r.value.show=m),title:r.value.title,message:r.value.message,danger:r.value.danger,confirmText:r.value.confirmText,onConfirm:d[1]||(d[1]=m=>{r.value.action(),r.value.show=!1})},null,8,["modelValue","title","message","danger","confirmText"]),s.value?(D(),L("div",{key:3,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",s.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(s.value.msg),3)):ce("",!0)]))}},ub={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},cb={class:"flex gap-2 mb-3"},fb=["value"],db={class:"flex gap-2 mb-2"},pb=["disabled"],hb={key:0,class:"text-xs text-gray-500 mb-2"},mb={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},gb={class:"flex gap-2 mb-3"},yb=["disabled"],bb={key:0,class:"bg-gray-50 rounded-lg p-3 text-sm space-y-1"},xb={class:"flex justify-between"},vb={class:"flex justify-between"},_b={class:"flex justify-between"},wb={class:"flex justify-between"},Eb={key:0,class:"flex justify-between"},Sb={class:"bg-white rounded-lg p-4 shadow-sm border"},Rb={class:"flex gap-2"},Cb={class:"px-4 py-2 bg-gray-600 text-white rounded-lg text-sm hover:bg-gray-700 cursor-pointer"},Ab={__name:"Tools",setup(e){const t=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],n=["mihomo","surge","loon","qx"],s=z("proxy"),r=z("mihomo"),o=z(""),i=z(""),l=z(""),a=z(!1),u=z(""),c=z(null),f=z(!1),d=z(null),m=Xe(()=>s.value==="proxy"?t:n);function R(g,x="success"){d.value={msg:g,type:x},setTimeout(()=>d.value=null,2500)}async function A(g){await navigator.clipboard.writeText(g),R("已复制")}async function O(){var g;if(!o.value.trim()){R("请输入内容","error");return}a.value=!0,i.value="",l.value="";try{const I=await(s.value==="proxy"?bm:xm)({content:o.value,target:r.value});i.value=I.data.content||I.data.par_res||"",l.value=`解析: ${I.data.parsed||0} · 输出: ${I.data.emitted||0} · 跳过: ${I.data.skipped||0}`,(g=I.data.warnings)!=null&&g.length&&(l.value+=" · ⚠ "+I.data.warnings.join("; ")),R("转换成功")}catch(x){R(x.message,"error")}finally{a.value=!1}}async function E(){f.value=!0,c.value=null;try{const g=await vm(u.value);c.value=g.data}catch(g){R(g.message,"error")}finally{f.value=!1}}async function w(){try{const g=await Yh(),x=new Blob([JSON.stringify(g,null,2)],{type:"application/json"}),I=URL.createObjectURL(x),C=document.createElement("a");C.href=I,C.download=`sub-store-backup-${Date.now()}.json`,C.click(),URL.revokeObjectURL(I),R("已导出")}catch(g){R(g.message,"error")}}async function v(g){var I;const x=(I=g.target.files)==null?void 0:I[0];if(x){try{const C=await x.text(),U=JSON.parse(C);await Zh(U),R("导入成功")}catch(C){R(C.message,"error")}g.target.value=""}}return(g,x)=>{var I;return D(),L("div",null,[x[16]||(x[16]=p("h2",{class:"text-xl font-bold mb-5"},"工具",-1)),p("div",ub,[x[7]||(x[7]=p("h3",{class:"font-semibold mb-3"},"转换器",-1)),p("div",cb,[se(p("select",{"onUpdate:modelValue":x[0]||(x[0]=C=>s.value=C),class:"px-3 py-2 border rounded-lg text-sm"},[...x[6]||(x[6]=[p("option",{value:"proxy"},"代理转换",-1),p("option",{value:"rule"},"规则转换",-1)])],512),[[St,s.value]]),se(p("select",{"onUpdate:modelValue":x[1]||(x[1]=C=>r.value=C),class:"px-3 py-2 border rounded-lg text-sm"},[(D(!0),L(fe,null,Ne(m.value,C=>(D(),L("option",{key:C,value:C},q(C),9,fb))),128))],512),[[St,r.value]])]),se(p("textarea",{"onUpdate:modelValue":x[2]||(x[2]=C=>o.value=C),rows:"5",placeholder:"粘贴订阅内容或规则...",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono mb-2"},null,512),[[Ae,o.value]]),p("div",db,[p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:a.value,onClick:O},q(a.value?"转换中...":"转换"),9,pb),i.value?(D(),L("button",{key:0,class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:x[3]||(x[3]=C=>A(i.value))},"复制结果")):ce("",!0)]),l.value?(D(),L("p",hb,q(l.value),1)):ce("",!0),i.value?se((D(),L("textarea",{key:1,"onUpdate:modelValue":x[4]||(x[4]=C=>i.value=C),rows:"8",readonly:"",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono bg-gray-50"},null,512)),[[Ae,i.value]]):ce("",!0)]),p("div",mb,[x[13]||(x[13]=p("h3",{class:"font-semibold mb-3"},"节点信息查询",-1)),p("div",gb,[se(p("input",{"onUpdate:modelValue":x[5]||(x[5]=C=>u.value=C),placeholder:"服务器地址 / IP",class:"flex-1 px-3 py-2 border rounded-lg text-sm",onKeyup:Nf(E,["enter"])},null,544),[[Ae,u.value]]),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:!u.value||f.value,onClick:E},q(f.value?"查询中...":"查询"),9,yb)]),c.value?(D(),L("div",bb,[p("div",xb,[x[8]||(x[8]=p("span",{class:"text-gray-500"},"IP",-1)),p("span",null,q(c.value.ip),1)]),p("div",vb,[x[9]||(x[9]=p("span",{class:"text-gray-500"},"国家",-1)),p("span",null,q(c.value.country),1)]),p("div",_b,[x[10]||(x[10]=p("span",{class:"text-gray-500"},"地区",-1)),p("span",null,q(c.value.region),1)]),p("div",wb,[x[11]||(x[11]=p("span",{class:"text-gray-500"},"城市",-1)),p("span",null,q(c.value.city),1)]),c.value.connection?(D(),L("div",Eb,[x[12]||(x[12]=p("span",{class:"text-gray-500"},"ISP",-1)),p("span",null,q(((I=c.value.connection)==null?void 0:I.isp)||"-"),1)])):ce("",!0)])):ce("",!0)]),p("div",Sb,[x[15]||(x[15]=p("h3",{class:"font-semibold mb-3"},"数据备份",-1)),p("div",Rb,[p("button",{class:"px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700",onClick:w},"导出全部"),p("label",Cb,[x[14]||(x[14]=un(" 导入备份 ",-1)),p("input",{type:"file",accept:".json",class:"hidden",onChange:v},null,32)])])]),d.value?(D(),L("div",{key:0,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",d.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(d.value.msg),3)):ce("",!0)])}}},Tb={key:0,class:"text-gray-400 text-sm"},Ob={key:1,class:"space-y-4 max-w-2xl"},Pb={class:"bg-white rounded-lg p-4 shadow-sm border"},Nb={class:"space-y-3"},Ib={class:"flex items-center gap-2"},kb={class:"bg-white rounded-lg p-4 shadow-sm border"},Db={class:"bg-white rounded-lg p-4 shadow-sm border"},$b={class:"flex items-center gap-2 mb-2"},Lb={class:"grid grid-cols-2 gap-2"},Ub={class:"bg-white rounded-lg p-4 shadow-sm border"},Fb={__name:"Settings",setup(e){const t=z(null),n=z(!0),s=z(null);function r(i,l="success"){s.value={msg:i,type:l},setTimeout(()=>s.value=null,2500)}async function o(){try{await Qh(t.value),r("设置已保存")}catch(i){r(i.message,"error")}}return Rt(async()=>{try{const i=await Xh();t.value=i.data}catch(i){r(i.message,"error")}finally{n.value=!1}}),(i,l)=>(D(),L("div",null,[l[26]||(l[26]=p("h2",{class:"text-xl font-bold mb-5"},"设置",-1)),n.value?(D(),L("div",Tb,"加载中...")):(D(),L("div",Ob,[p("div",Pb,[l[17]||(l[17]=p("h3",{class:"font-semibold mb-3 text-sm"},"通用",-1)),p("div",Nb,[p("div",null,[l[11]||(l[11]=p("label",{class:"block text-sm mb-1"},"默认 User-Agent",-1)),se(p("input",{"onUpdate:modelValue":l[0]||(l[0]=a=>t.value.defaultUserAgent=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.defaultUserAgent]])]),p("div",null,[l[12]||(l[12]=p("label",{class:"block text-sm mb-1"},"默认流量查询 User-Agent",-1)),se(p("input",{"onUpdate:modelValue":l[1]||(l[1]=a=>t.value.defaultFlowUserAgent=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.defaultFlowUserAgent]])]),p("div",null,[l[13]||(l[13]=p("label",{class:"block text-sm mb-1"},"请求超时 (ms)",-1)),se(p("input",{"onUpdate:modelValue":l[2]||(l[2]=a=>t.value.defaultTimeout=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.defaultTimeout]])]),p("div",null,[l[14]||(l[14]=p("label",{class:"block text-sm mb-1"},"后端并发数",-1)),se(p("input",{"onUpdate:modelValue":l[3]||(l[3]=a=>t.value.backendRequestConcurrency=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.backendRequestConcurrency]])]),p("div",null,[l[15]||(l[15]=p("label",{class:"block text-sm mb-1"},"远程缓存 TTL (秒)",-1)),se(p("input",{"onUpdate:modelValue":l[4]||(l[4]=a=>t.value.remoteCacheTtl=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.remoteCacheTtl]])]),p("div",Ib,[se(p("input",{type:"checkbox",id:"cache-stale","onUpdate:modelValue":l[5]||(l[5]=a=>t.value.remoteCacheStaleOnError=a),class:"rounded"},null,512),[[wn,t.value.remoteCacheStaleOnError]]),l[16]||(l[16]=p("label",{for:"cache-stale",class:"text-sm"},"缓存过期时仍返回旧数据",-1))])])]),p("div",kb,[l[18]||(l[18]=p("h3",{class:"font-semibold mb-3 text-sm"},"节点信息 API",-1)),se(p("input",{"onUpdate:modelValue":l[6]||(l[6]=a=>t.value.nodeInfoApiUrl=a),placeholder:"https://ipwho.is/{ip}",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[Ae,t.value.nodeInfoApiUrl]]),l[19]||(l[19]=p("p",{class:"text-xs text-gray-400 mt-1"},"URL 中 {ip} 会被替换为查询的 IP",-1))]),p("div",Db,[l[23]||(l[23]=p("h3",{class:"font-semibold mb-3 text-sm"},"主题",-1)),p("div",$b,[se(p("input",{type:"checkbox",id:"theme-auto","onUpdate:modelValue":l[7]||(l[7]=a=>t.value.theme.auto=a),class:"rounded"},null,512),[[wn,t.value.theme.auto]]),l[20]||(l[20]=p("label",{for:"theme-auto",class:"text-sm"},"自动跟随系统",-1))]),p("div",Lb,[p("div",null,[l[21]||(l[21]=p("label",{class:"text-xs text-gray-500"},"亮色主题",-1)),se(p("input",{"onUpdate:modelValue":l[8]||(l[8]=a=>t.value.theme.light=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.theme.light]])]),p("div",null,[l[22]||(l[22]=p("label",{class:"text-xs text-gray-500"},"暗色主题",-1)),se(p("input",{"onUpdate:modelValue":l[9]||(l[9]=a=>t.value.theme.dark=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.theme.dark]])])])]),p("div",Ub,[l[25]||(l[25]=p("h3",{class:"font-semibold mb-3 text-sm"},"应用",-1)),p("div",null,[l[24]||(l[24]=p("label",{class:"block text-sm mb-1"},"应用名称",-1)),se(p("input",{"onUpdate:modelValue":l[10]||(l[10]=a=>t.value.appName=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[Ae,t.value.appName]])])]),p("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:o},"保存设置")])),s.value?(D(),L("div",{key:2,class:Ve(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",s.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},q(s.value.msg),3)):ce("",!0)]))}},Vb=[{path:"/",component:Om,children:[{path:"",name:"dashboard",component:Km,meta:{title:"概览"}},{path:"sources",name:"sources",component:Lg,meta:{title:"订阅源"}},{path:"collections",name:"collections",component:fy,meta:{title:"合集"}},{path:"templates",name:"templates",component:Ny,meta:{title:"模板"}},{path:"shares",name:"shares",component:Qy,meta:{title:"分享"}},{path:"recycle-bin",name:"recycle-bin",component:ab,meta:{title:"回收站"}},{path:"tools",name:"tools",component:Ab,meta:{title:"工具"}},{path:"settings",name:"settings",component:Fb,meta:{title:"设置"}}]},{path:"/:pathMatch(.*)*",name:"not-found",component:Nm}],lu=Kd({history:Ed(),routes:Vb});let xs=null;lu.beforeEach(async(e,t,n)=>{if(e.name==="not-found")return n();const s=e.query.token;if(s){xs||(xs=Jd(s));const i=await xs;if(xs=null,i){Gd(s);const l={...e.query};return delete l.token,n({...e,query:l,replace:!0})}else return ka(),n({name:"not-found"})}const r=Ia(),o=zd();if(!r||!o)return n({name:"not-found"});n()});const So=Df(Vf);So.use(Ff());So.use(lu);So.mount("#app"); diff --git a/frontend/dist/config.js b/frontend/dist/config.js new file mode 100644 index 0000000..7c9ab93 --- /dev/null +++ b/frontend/dist/config.js @@ -0,0 +1,23 @@ +/** + * Frontend runtime configuration. + * + * This file is loaded at runtime (not bundled), so you can edit it + * after building without rebuilding the frontend. + * + * Copy this file to config.js in the same directory as index.html + * and adjust the values as needed. + */ +window.SUB_STORE_CONFIG = { + /** + * Base URL for the backend API. + * - Empty string '' means same origin (frontend served by the backend, or via reverse proxy). + * - Set to e.g. 'https://api.example.com' if frontend and backend are on different domains. + */ + apiBaseUrl: '', + + /** + * Whether to send token as Bearer header (true) or query parameter (false). + * Bearer header is more secure (token not in server logs/URLs). + */ + useBearerAuth: true, +} diff --git a/frontend/dist/index.html b/frontend/dist/index.html new file mode 100644 index 0000000..dbad744 --- /dev/null +++ b/frontend/dist/index.html @@ -0,0 +1,14 @@ + + + + + + Sub-Store + + + + + +
+ + diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..8f477d1 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + Sub-Store + + + +
+ + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..0c6a17d --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,2820 @@ +{ + "name": "sub-store-frontend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sub-store-frontend", + "version": "1.0.0", + "dependencies": { + "axios": "^1.7.9", + "pinia": "^2.3.0", + "vue": "^3.5.13", + "vue-router": "^4.5.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.2.1", + "autoprefixer": "^10.4.20", + "postcss": "^8.4.49", + "tailwindcss": "^3.4.17", + "vite": "^6.0.7" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.3.tgz", + "integrity": "sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.3.tgz", + "integrity": "sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.3.tgz", + "integrity": "sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.3.tgz", + "integrity": "sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.3.tgz", + "integrity": "sha512-zvBUvsQUpOWALdDsk6qbS8bXf2VxmPisuudNDrY7x0p0jBdsoZl8HsHczIOgkQiZldmcacMKtBzpoGVNeIe2bQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.3.tgz", + "integrity": "sha512-C2KmNrcSem/AMg984H/dev+si0lieQGdXdR/lYGJnuumXnFb9Y7QdiI62obFdLlxRYLBv4P0eUVIDbD4c1vVvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.3.tgz", + "integrity": "sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.3.tgz", + "integrity": "sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.3.tgz", + "integrity": "sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.3.tgz", + "integrity": "sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.3.tgz", + "integrity": "sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.3.tgz", + "integrity": "sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.3.tgz", + "integrity": "sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.3.tgz", + "integrity": "sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.3.tgz", + "integrity": "sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.3.tgz", + "integrity": "sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.3.tgz", + "integrity": "sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.3.tgz", + "integrity": "sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.3.tgz", + "integrity": "sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.3.tgz", + "integrity": "sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.3.tgz", + "integrity": "sha512-+2Cy/ldweGBLlPIKsQLF8U5N44a0KDdbrk1rAjHOM9M2K+kGdIVjHLmmrZIcx+9Ny3ke/1JomCsDI1ocb11+sg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.3.tgz", + "integrity": "sha512-dtZvzc8BedpSaFNy75x6uiWwAGTH+aZHDtdrqP6qk+WcLJrfti6sGje1ZJ9UxyzDLF23d/mV+PaMwuC0hL7UVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.3.tgz", + "integrity": "sha512-Rj8Ra4noo+aYy7sKBggCx0407mws34kAb1ySyWuq5DAtFBQdkSwnsjCgPrhPe9cvgBKZIukpE+CVHvORCS93kQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.3.tgz", + "integrity": "sha512-vp7N084ew/odXn2gi/mzm9mUkQu9l6AiN6dt4IeUM2Uvm9o+cVmP+YkqbMOteLbiGgqBBlJZjIMYVCfOOIVbVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.3.tgz", + "integrity": "sha512-MOG/3gTOn4Fwf574RVOaY61I5o6P90legkFADiTyn1hyjNydT+cerU2rLUwPdZkKKyJ+iT+K9p7WXK4LM1Ka6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.40.tgz", + "integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@vue/shared": "3.5.40", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz", + "integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.40", + "@vue/shared": "3.5.40" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz", + "integrity": "sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@vue/compiler-core": "3.5.40", + "@vue/compiler-dom": "3.5.40", + "@vue/compiler-ssr": "3.5.40", + "@vue/shared": "3.5.40", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.19", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz", + "integrity": "sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.40", + "@vue/shared": "3.5.40" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.40.tgz", + "integrity": "sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.40" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.40.tgz", + "integrity": "sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.40", + "@vue/shared": "3.5.40" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz", + "integrity": "sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.40", + "@vue/runtime-core": "3.5.40", + "@vue/shared": "3.5.40", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.40.tgz", + "integrity": "sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.40", + "@vue/runtime-dom": "3.5.40", + "@vue/shared": "3.5.40" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.40.tgz", + "integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.5.4", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.5.4.tgz", + "integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.6", + "caniuse-lite": "^1.0.30001806", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.18.1", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.4", + "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.4.tgz", + "integrity": "sha512-s4+sLr9mZ/CyqeRritFeYV/Zx73OAtmaHn6kkBS1XRoJn1hrg3xIDUcpicAEX68tkcIN0iBCgti31C8zxtkhsQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.7", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.396", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.396.tgz", + "integrity": "sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinia": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz", + "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.62.3", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.62.3.tgz", + "integrity": "sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.3", + "@rollup/rollup-android-arm64": "4.62.3", + "@rollup/rollup-darwin-arm64": "4.62.3", + "@rollup/rollup-darwin-x64": "4.62.3", + "@rollup/rollup-freebsd-arm64": "4.62.3", + "@rollup/rollup-freebsd-x64": "4.62.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.3", + "@rollup/rollup-linux-arm-musleabihf": "4.62.3", + "@rollup/rollup-linux-arm64-gnu": "4.62.3", + "@rollup/rollup-linux-arm64-musl": "4.62.3", + "@rollup/rollup-linux-loong64-gnu": "4.62.3", + "@rollup/rollup-linux-loong64-musl": "4.62.3", + "@rollup/rollup-linux-ppc64-gnu": "4.62.3", + "@rollup/rollup-linux-ppc64-musl": "4.62.3", + "@rollup/rollup-linux-riscv64-gnu": "4.62.3", + "@rollup/rollup-linux-riscv64-musl": "4.62.3", + "@rollup/rollup-linux-s390x-gnu": "4.62.3", + "@rollup/rollup-linux-x64-gnu": "4.62.3", + "@rollup/rollup-linux-x64-musl": "4.62.3", + "@rollup/rollup-openbsd-x64": "4.62.3", + "@rollup/rollup-openharmony-arm64": "4.62.3", + "@rollup/rollup-win32-arm64-msvc": "4.62.3", + "@rollup/rollup-win32-ia32-msvc": "4.62.3", + "@rollup/rollup-win32-x64-gnu": "4.62.3", + "@rollup/rollup-win32-x64-msvc": "4.62.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmmirror.com/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vue": { + "version": "3.5.40", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.40.tgz", + "integrity": "sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.40", + "@vue/compiler-sfc": "3.5.40", + "@vue/runtime-dom": "3.5.40", + "@vue/server-renderer": "3.5.40", + "@vue/shared": "3.5.40" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.6.4", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.6.4.tgz", + "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..21c8c70 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,24 @@ +{ + "name": "sub-store-frontend", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.5.13", + "vue-router": "^4.5.0", + "pinia": "^2.3.0", + "axios": "^1.7.9" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.2.1", + "vite": "^6.0.7", + "tailwindcss": "^3.4.17", + "postcss": "^8.4.49", + "autoprefixer": "^10.4.20" + } +} diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/frontend/public/config.js b/frontend/public/config.js new file mode 100644 index 0000000..7c9ab93 --- /dev/null +++ b/frontend/public/config.js @@ -0,0 +1,23 @@ +/** + * Frontend runtime configuration. + * + * This file is loaded at runtime (not bundled), so you can edit it + * after building without rebuilding the frontend. + * + * Copy this file to config.js in the same directory as index.html + * and adjust the values as needed. + */ +window.SUB_STORE_CONFIG = { + /** + * Base URL for the backend API. + * - Empty string '' means same origin (frontend served by the backend, or via reverse proxy). + * - Set to e.g. 'https://api.example.com' if frontend and backend are on different domains. + */ + apiBaseUrl: '', + + /** + * Whether to send token as Bearer header (true) or query parameter (false). + * Bearer header is more secure (token not in server logs/URLs). + */ + useBearerAuth: true, +} diff --git a/frontend/src/App.vue b/frontend/src/App.vue new file mode 100644 index 0000000..8693d1b --- /dev/null +++ b/frontend/src/App.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js new file mode 100644 index 0000000..6363814 --- /dev/null +++ b/frontend/src/api/index.js @@ -0,0 +1,98 @@ +import axios from 'axios' +import { getEffectiveToken, clearToken } from '@/utils/token' + +// Read runtime config (injected by config.js, defaults to same-origin) +const apiBaseUrl = (window.SUB_STORE_CONFIG?.apiBaseUrl) || '' + +const api = axios.create({ + baseURL: apiBaseUrl + '/api', + timeout: 30000, +}) + +// Request interceptor — attach admin token +api.interceptors.request.use((config) => { + const token = getEffectiveToken() + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config +}) + +// Response interceptor — unwrap data, handle errors +api.interceptors.response.use( + (response) => response.data, + (error) => { + if (error.response?.status === 401) { + // Token might be stale — clear it and let the router guard handle redirect + clearToken() + } + const msg = error.response?.data?.error?.message || error.message || 'Request failed' + return Promise.reject(new Error(msg)) + } +) + +// --- API methods --- + +// Env +export const getEnv = () => api.get('/env') +export const getScripts = () => api.get('/scripts') + +// Settings +export const getSettings = () => api.get('/settings') +export const updateSettings = (data) => api.patch('/settings', data) + +// Storage +export const exportStorage = () => api.get('/storage') +export const importStorage = (data) => api.post('/storage', data) + +// Sources +export const listSources = () => api.get('/sources') +export const createSource = (data) => api.post('/sources', data) +export const getSource = (name) => api.get(`/sources/${name}`) +export const updateSource = (name, data) => api.patch(`/sources/${name}`, data) +export const deleteSource = (name) => api.delete(`/sources/${name}`) +export const sortSources = (ids) => api.put('/sources', ids) + +// Collections +export const listCollections = () => api.get('/collections') +export const createCollection = (data) => api.post('/collections', data) +export const getCollection = (name) => api.get(`/collections/${name}`) +export const updateCollection = (name, data) => api.patch(`/collections/${name}`, data) +export const deleteCollection = (name) => api.delete(`/collections/${name}`) +export const sortCollections = (ids) => api.put('/collections', ids) + +// Templates +export const listTemplates = () => api.get('/templates') +export const createTemplate = (data) => api.post('/templates', data) +export const getTemplate = (name) => api.get(`/templates/${name}`) +export const updateTemplate = (name, data) => api.patch(`/templates/${name}`, data) +export const deleteTemplate = (name) => api.delete(`/templates/${name}`) + +// Shares +export const listShares = () => api.get('/shares') +export const createShare = (data) => api.post('/shares', data) +export const updateShare = (id, data) => api.patch(`/shares/${id}`, data) +export const deleteShare = (id) => api.delete(`/shares/${id}`) + +// Recycle bin +export const listRecycleBin = () => api.get('/recycle-bin') +export const deleteRecycleEntry = (id) => api.delete(`/recycle-bin/${id}`) +export const restoreRecycleEntry = (id) => api.post(`/recycle-bin/${id}/restore`) + +// Preview +export const previewSource = (data) => api.post('/preview/source', data) +export const previewCollection = (data) => api.post('/preview/collection', data) + +// Download links +export const getLinkSource = (name, target) => api.get(`/link/source/${name}`, { params: target ? { target } : {} }) +export const getLinkCollection = (name, target) => api.get(`/link/collection/${name}`, { params: target ? { target } : {} }) + +// Flow info +export const getFlowInfo = (name) => api.get(`/source/flow/${name}`) + +// Tools +export const parseProxy = (data) => api.post('/proxy/parse', data) +export const parseRule = (data) => api.post('/rule/parse', data) +export const getNodeInfo = (server) => api.post('/utils/node-info', { server }) + +export default api diff --git a/frontend/src/components/ConfirmDialog.vue b/frontend/src/components/ConfirmDialog.vue new file mode 100644 index 0000000..ae9c197 --- /dev/null +++ b/frontend/src/components/ConfirmDialog.vue @@ -0,0 +1,28 @@ + + + diff --git a/frontend/src/components/Modal.vue b/frontend/src/components/Modal.vue new file mode 100644 index 0000000..6db4c73 --- /dev/null +++ b/frontend/src/components/Modal.vue @@ -0,0 +1,27 @@ + + + diff --git a/frontend/src/layouts/AdminLayout.vue b/frontend/src/layouts/AdminLayout.vue new file mode 100644 index 0000000..b96d411 --- /dev/null +++ b/frontend/src/layouts/AdminLayout.vue @@ -0,0 +1,64 @@ + + + diff --git a/frontend/src/main.js b/frontend/src/main.js new file mode 100644 index 0000000..501dee0 --- /dev/null +++ b/frontend/src/main.js @@ -0,0 +1,10 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import App from './App.vue' +import router from './router' +import './style.css' + +const app = createApp(App) +app.use(createPinia()) +app.use(router) +app.mount('#app') diff --git a/frontend/src/pages/Collections.vue b/frontend/src/pages/Collections.vue new file mode 100644 index 0000000..3221067 --- /dev/null +++ b/frontend/src/pages/Collections.vue @@ -0,0 +1,198 @@ + + + diff --git a/frontend/src/pages/Dashboard.vue b/frontend/src/pages/Dashboard.vue new file mode 100644 index 0000000..8347178 --- /dev/null +++ b/frontend/src/pages/Dashboard.vue @@ -0,0 +1,79 @@ + + + diff --git a/frontend/src/pages/NotFound.vue b/frontend/src/pages/NotFound.vue new file mode 100644 index 0000000..94047c5 --- /dev/null +++ b/frontend/src/pages/NotFound.vue @@ -0,0 +1,12 @@ + + + diff --git a/frontend/src/pages/RecycleBin.vue b/frontend/src/pages/RecycleBin.vue new file mode 100644 index 0000000..4393933 --- /dev/null +++ b/frontend/src/pages/RecycleBin.vue @@ -0,0 +1,111 @@ + + + diff --git a/frontend/src/pages/Settings.vue b/frontend/src/pages/Settings.vue new file mode 100644 index 0000000..ff3cff2 --- /dev/null +++ b/frontend/src/pages/Settings.vue @@ -0,0 +1,116 @@ + + + diff --git a/frontend/src/pages/Shares.vue b/frontend/src/pages/Shares.vue new file mode 100644 index 0000000..2f344f2 --- /dev/null +++ b/frontend/src/pages/Shares.vue @@ -0,0 +1,164 @@ + + + diff --git a/frontend/src/pages/Sources.vue b/frontend/src/pages/Sources.vue new file mode 100644 index 0000000..be42772 --- /dev/null +++ b/frontend/src/pages/Sources.vue @@ -0,0 +1,251 @@ + + + diff --git a/frontend/src/pages/Templates.vue b/frontend/src/pages/Templates.vue new file mode 100644 index 0000000..d79b794 --- /dev/null +++ b/frontend/src/pages/Templates.vue @@ -0,0 +1,174 @@ + + + diff --git a/frontend/src/pages/Tools.vue b/frontend/src/pages/Tools.vue new file mode 100644 index 0000000..17e8c03 --- /dev/null +++ b/frontend/src/pages/Tools.vue @@ -0,0 +1,164 @@ + + + diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js new file mode 100644 index 0000000..f4ea2d8 --- /dev/null +++ b/frontend/src/router/index.js @@ -0,0 +1,94 @@ +import { createRouter, createWebHistory } from 'vue-router' +import { getTokenFromURL, getStoredToken, isTokenValidated, storeToken, clearToken, validateToken } from '@/utils/token' + +// Layouts +import AdminLayout from '@/layouts/AdminLayout.vue' + +// Pages +import NotFound from '@/pages/NotFound.vue' +import Dashboard from '@/pages/Dashboard.vue' +import Sources from '@/pages/Sources.vue' +import Collections from '@/pages/Collections.vue' +import Templates from '@/pages/Templates.vue' +import Shares from '@/pages/Shares.vue' +import RecycleBin from '@/pages/RecycleBin.vue' +import Tools from '@/pages/Tools.vue' +import Settings from '@/pages/Settings.vue' + +const routes = [ + { + path: '/', + component: AdminLayout, + children: [ + { path: '', name: 'dashboard', component: Dashboard, meta: { title: '概览' } }, + { path: 'sources', name: 'sources', component: Sources, meta: { title: '订阅源' } }, + { path: 'collections', name: 'collections', component: Collections, meta: { title: '合集' } }, + { path: 'templates', name: 'templates', component: Templates, meta: { title: '模板' } }, + { path: 'shares', name: 'shares', component: Shares, meta: { title: '分享' } }, + { path: 'recycle-bin', name: 'recycle-bin', component: RecycleBin, meta: { title: '回收站' } }, + { path: 'tools', name: 'tools', component: Tools, meta: { title: '工具' } }, + { path: 'settings', name: 'settings', component: Settings, meta: { title: '设置' } }, + ] + }, + // Catch-all 404 + { path: '/:pathMatch(.*)*', name: 'not-found', component: NotFound } +] + +const router = createRouter({ + history: createWebHistory(), + routes, +}) + +// Track if we're currently validating to avoid duplicate calls +let validatingPromise = null + +/** + * Global async token guard. + * The page must be opened with ?token=xxx. + * When a token is provided in the URL, it's validated against the backend. + * If valid → stored and URL stripped. If invalid → 404. + * Subsequent navigations use the stored, already-validated token. + */ +router.beforeEach(async (to, from, next) => { + // If navigating to 404 page, always allow (avoid infinite loop) + if (to.name === 'not-found') { + return next() + } + + // Check token from Vue Router query (authoritative during navigation) + const routeToken = to.query.token + + // If URL has a token, validate it before allowing access + if (routeToken) { + // Avoid duplicate validation + if (!validatingPromise) { + validatingPromise = validateToken(routeToken) + } + const isValid = await validatingPromise + validatingPromise = null + + if (isValid) { + storeToken(routeToken) + // Navigate to same route without token in query + const cleanQuery = { ...to.query } + delete cleanQuery.token + return next({ ...to, query: cleanQuery, replace: true }) + } else { + // Invalid token → clear storage, show 404 + clearToken() + return next({ name: 'not-found' }) + } + } + + // No token in URL — check if we have a validated stored token + const storedToken = getStoredToken() + const validated = isTokenValidated() + + if (!storedToken || !validated) { + return next({ name: 'not-found' }) + } + + next() +}) + +export default router diff --git a/frontend/src/style.css b/frontend/src/style.css new file mode 100644 index 0000000..4fc4d21 --- /dev/null +++ b/frontend/src/style.css @@ -0,0 +1,13 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Scrollbar */ +::-webkit-scrollbar { width: 8px; height: 8px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; } +::-webkit-scrollbar-thumb:hover { background: #94a3b8; } + +/* Transition */ +.fade-enter-active, .fade-leave-active { transition: opacity 0.2s; } +.fade-enter-from, .fade-leave-to { opacity: 0; } diff --git a/frontend/src/utils/token.js b/frontend/src/utils/token.js new file mode 100644 index 0000000..1b2c05d --- /dev/null +++ b/frontend/src/utils/token.js @@ -0,0 +1,65 @@ +/** + * Token management — the page MUST be opened with ?token=xxx + * The token is validated against the backend /api/env endpoint. + * If invalid or missing, the router guard shows a 404 page. + */ + +const TOKEN_KEY = 'sub_store_admin_token' +const VALIDATED_KEY = 'sub_store_token_validated' + +/** Extract token from URL query string */ +export function getTokenFromURL() { + const params = new URLSearchParams(window.location.search) + return params.get('token') || '' +} + +/** Store token in localStorage (persists across page reloads) */ +export function storeToken(token) { + if (token) { + localStorage.setItem(TOKEN_KEY, token) + localStorage.setItem(VALIDATED_KEY, 'true') + } +} + +/** Get stored token */ +export function getStoredToken() { + return localStorage.getItem(TOKEN_KEY) || '' +} + +/** Check if token has been validated */ +export function isTokenValidated() { + return localStorage.getItem(VALIDATED_KEY) === 'true' +} + +/** Clear token (logout) */ +export function clearToken() { + localStorage.removeItem(TOKEN_KEY) + localStorage.removeItem(VALIDATED_KEY) +} + +/** + * Validate token against backend by calling /api/env. + * Returns true if token is valid, false otherwise. + */ +export async function validateToken(token) { + if (!token) return false + try { + const base = (window.SUB_STORE_CONFIG?.apiBaseUrl) || '' + const resp = await fetch(`${base}/api/env?token=${encodeURIComponent(token)}`) + if (!resp.ok) return false + const data = await resp.json() + return data.status === 'success' + } catch { + return false + } +} + +/** + * Get the effective token: from URL if present, otherwise from storage. + * This is used by the API layer to always send the token. + */ +export function getEffectiveToken() { + const urlToken = getTokenFromURL() + if (urlToken) return urlToken + return getStoredToken() +} diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js new file mode 100644 index 0000000..1075ab0 --- /dev/null +++ b/frontend/tailwind.config.js @@ -0,0 +1,27 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{vue,js,ts,jsx,tsx}", + ], + darkMode: 'class', + theme: { + extend: { + colors: { + primary: { + 50: '#eff6ff', + 100: '#dbeafe', + 200: '#bfdbfe', + 300: '#93c5fd', + 400: '#60a5fa', + 500: '#3b82f6', + 600: '#2563eb', + 700: '#1d4ed8', + 800: '#1e40af', + 900: '#1e3a8a', + } + } + }, + }, + plugins: [], +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js new file mode 100644 index 0000000..f840c09 --- /dev/null +++ b/frontend/vite.config.js @@ -0,0 +1,30 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import { fileURLToPath, URL } from 'node:url' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + }, + server: { + port: 5173, + host: '0.0.0.0', + proxy: { + '/api': { + target: 'http://localhost:3001', + changeOrigin: true + }, + '/download': { + target: 'http://localhost:3001', + changeOrigin: true + } + } + }, + build: { + outDir: 'dist', + assetsDir: 'assets' + } +}) diff --git a/internal/proxy/uri_parser.go b/internal/proxy/uri_parser.go index 83b736b..99dc9a2 100644 --- a/internal/proxy/uri_parser.go +++ b/internal/proxy/uri_parser.go @@ -510,21 +510,52 @@ func ParseTuic(line string, index int) model.ProxyNode { func ParseWireGuard(line string, index int) model.ProxyNode { normalized := strings.Replace(line, "wg://", "wireguard://", 1) u := parseURL(normalized) + // WireGuard keys are base64-encoded and may contain '+' characters. + // Go's url.Query() treats '+' as space (form-encoding behavior), which corrupts base64 keys. + // Use rawQueryUnescapeForKeys to preserve '+' in key values. return StripUndefined(map[string]any{ - "name": fragmentName(u, fmt.Sprintf("wireguard-%d", index+1)), - "type": "wireguard", - "server": u.Hostname(), - "port": portFromURL(u, 51820), - "ip": firstNonEmpty(paramGet(u, "ip"), paramGet(u, "address")), - "ipv6": paramGet(u, "ipv6"), - "private-key": firstNonEmpty(userInfo(u), paramGet(u, "private-key"), paramGet(u, "privatekey")), - "public-key": firstNonEmpty(paramGet(u, "public-key"), paramGet(u, "publickey"), paramGet(u, "peer-public-key")), - "pre-shared-key": firstNonEmpty(paramGet(u, "pre-shared-key"), paramGet(u, "presharedkey"), paramGet(u, "psk")), - "reserved": paramGet(u, "reserved"), - "udp": true, + "name": fragmentName(u, fmt.Sprintf("wireguard-%d", index+1)), + "type": "wireguard", + "server": u.Hostname(), + "port": portFromURL(u, 51820), + "ip": firstNonEmpty(rawParamGet(u, "ip"), rawParamGet(u, "address")), + "ipv6": rawParamGet(u, "ipv6"), + "private-key": firstNonEmpty(userInfo(u), rawParamGet(u, "private-key"), rawParamGet(u, "privatekey")), + "public-key": firstNonEmpty(rawParamGet(u, "public-key"), rawParamGet(u, "publickey"), rawParamGet(u, "peer-public-key")), + "pre-shared-key": firstNonEmpty(rawParamGet(u, "pre-shared-key"), rawParamGet(u, "presharedkey"), rawParamGet(u, "psk")), + "reserved": rawParamGet(u, "reserved"), + "udp": true, }) } +// rawParamGet retrieves a query parameter value while preserving '+' characters. +// This is necessary for base64-encoded values (e.g., WireGuard keys) where +// Go's standard url.Query() would incorrectly convert '+' to spaces. +func rawParamGet(u *url.URL, key string) string { + raw := u.RawQuery + if raw == "" { + return "" + } + for _, pair := range strings.Split(raw, "&") { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + continue + } + k, _ := url.QueryUnescape(kv[0]) + if k != key { + continue + } + // Unescape manually, but preserve '+' as literal '+' + val := strings.ReplaceAll(kv[1], "+", "%2B") + v, err := url.QueryUnescape(val) + if err != nil { + return kv[1] + } + return v + } + return "" +} + // BoolParam returns true if value is "1" or "true". func BoolParam(value string) bool { return value == "1" || value == "true" diff --git a/internal/render/dispatch.go b/internal/render/dispatch.go index 2caedd4..8d4ae43 100644 --- a/internal/render/dispatch.go +++ b/internal/render/dispatch.go @@ -31,7 +31,7 @@ func RenderTarget(proxies []model.ProxyNode, target string, template map[string] case model.TargetQX: return RenderQxProxies(proxies) case model.TargetSingBox: - return RenderSingBoxJson(proxies), nil + return RenderSingBoxWithTemplate(proxies, template), nil case model.TargetV2ray: return util.Base64Utf8(RenderProxyUris(proxies)), nil case model.TargetURI, model.TargetShadowrocket: @@ -63,7 +63,7 @@ func RenderBuildTarget(proxies []model.ProxyNode, target string, requestUrl stri case model.TargetQX: return RenderQxProxies(proxies) case model.TargetSingBox: - return RenderSingBoxJson(proxies), nil + return RenderSingBoxWithTemplate(proxies, template), nil case model.TargetV2ray: return util.Base64Utf8(RenderProxyUris(proxies)), nil case model.TargetURI: diff --git a/internal/render/mihomo.go b/internal/render/mihomo.go index bee2aa0..6c62381 100644 --- a/internal/render/mihomo.go +++ b/internal/render/mihomo.go @@ -239,6 +239,9 @@ func extractGroupTemplates(cfg map[string]any) []map[string]any { } func toGroupList(v any) []map[string]any { + if arr, ok := v.([]map[string]any); ok { + return arr + } arr, ok := v.([]any) if !ok { return nil diff --git a/internal/render/render_extra_test.go b/internal/render/render_extra_test.go index 95f0bce..7aff278 100644 --- a/internal/render/render_extra_test.go +++ b/internal/render/render_extra_test.go @@ -878,8 +878,8 @@ func TestExtraSingBoxStructure(t *testing.T) { t.Errorf("expected listen_port=7890, got: %v", inbound["listen_port"]) } outbounds, _ := parsed["outbounds"].([]any) - if len(outbounds) < 4 { - t.Fatalf("expected at least 4 outbounds (PROXY, AUTO, nodes, DIRECT, REJECT), got %d", len(outbounds)) + if len(outbounds) < 3 { + t.Fatalf("expected at least 3 outbounds (PROXY, AUTO, nodes, DIRECT), got %d", len(outbounds)) } proxyOut, _ := outbounds[0].(map[string]any) if proxyOut["tag"] != "PROXY" || proxyOut["type"] != "selector" { @@ -889,16 +889,29 @@ func TestExtraSingBoxStructure(t *testing.T) { if autoOut["tag"] != "AUTO" || autoOut["type"] != "urltest" { t.Errorf("expected second outbound AUTO urltest, got: %v", autoOut) } - // DIRECT and REJECT should be at the end + // DIRECT should be at the end (REJECT is now a route rule action, not a special outbound) last, _ := outbounds[len(outbounds)-1].(map[string]any) - if last["tag"] != "REJECT" || last["type"] != "block" { - t.Errorf("expected last outbound REJECT block, got: %v", last) + if last["tag"] != "DIRECT" || last["type"] != "direct" { + t.Errorf("expected last outbound DIRECT direct, got: %v", last) } - secondLast, _ := outbounds[len(outbounds)-2].(map[string]any) - if secondLast["tag"] != "DIRECT" || secondLast["type"] != "direct" { - t.Errorf("expected second-last outbound DIRECT direct, got: %v", secondLast) + // Inbound should NOT have sniff field (migrated to route rule action in sing-box 1.11+) + if _, hasSniff := inbound["sniff"]; hasSniff { + t.Errorf("inbound should not have sniff field (migrated to route rule action)") } + // Route should have rules with sniff and reject actions routeMap, _ := parsed["route"].(map[string]any) + rules, _ := routeMap["rules"].([]any) + if len(rules) < 2 { + t.Fatalf("expected at least 2 route rules (sniff, reject), got %d", len(rules)) + } + rule0, _ := rules[0].(map[string]any) + if rule0["action"] != "sniff" { + t.Errorf("expected first route rule action=sniff, got: %v", rule0["action"]) + } + rule1, _ := rules[1].(map[string]any) + if rule1["action"] != "reject" { + t.Errorf("expected second route rule action=reject, got: %v", rule1["action"]) + } if routeMap == nil || routeMap["final"] != "PROXY" { t.Errorf("expected route.final=PROXY, got: %v", parsed["route"]) } @@ -923,7 +936,6 @@ func TestExtraSingBoxOutboundAllTypes(t *testing.T) { {"tuic", nodeByName("TUIC"), "tuic"}, {"socks5", nodeByName("SOCKS5"), "socks"}, {"http", nodeByName("HTTP"), "http"}, - {"wireguard", nodeByName("WG"), "wireguard"}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { @@ -941,6 +953,31 @@ func TestExtraSingBoxOutboundAllTypes(t *testing.T) { } } +func TestExtraSingBoxWireGuardEndpoint(t *testing.T) { + node := nodeByName("WG") + ep := ToSingBoxWireGuardEndpoint(node) + if ep == nil { + t.Fatalf("ToSingBoxWireGuardEndpoint(WG) nil") + } + if ep["type"] != "wireguard" { + t.Errorf("expected type=wireguard, got %v", ep["type"]) + } + if ep["tag"] != "WG-Node" { + t.Errorf("expected tag=WG-Node, got %v", ep["tag"]) + } + peers, ok := ep["peers"].([]any) + if !ok || len(peers) == 0 { + t.Fatalf("expected peers array, got: %v", ep["peers"]) + } + peer, ok := peers[0].(map[string]any) + if !ok { + t.Fatalf("expected peer map, got: %v", peers[0]) + } + if peer["public_key"] == nil { + t.Errorf("expected peer.public_key to be set") + } +} + func TestExtraSingBoxUnsupportedType(t *testing.T) { node := model.ProxyNode{"type": "snell", "name": "x"} if out := ToSingBoxOutbound(node); out != nil { @@ -1029,10 +1066,15 @@ func TestExtraSingBoxHTTPTls(t *testing.T) { func TestExtraSingBoxWireGuardReserved(t *testing.T) { node := nodeByName("WG") - out := ToSingBoxOutbound(node) - reserved, ok := out["reserved"].([]int) + ep := ToSingBoxWireGuardEndpoint(node) + peers, ok := ep["peers"].([]any) + if !ok || len(peers) == 0 { + t.Fatalf("expected peers array, got: %v", ep["peers"]) + } + peer := peers[0].(map[string]any) + reserved, ok := peer["reserved"].([]int) if !ok { - t.Fatalf("expected reserved []int, got: %v", out["reserved"]) + t.Fatalf("expected peer reserved []int, got: %v", peer["reserved"]) } if !reflect.DeepEqual(reserved, []int{1, 2, 3}) { t.Errorf("expected reserved=[1,2,3], got: %v", reserved) @@ -1041,13 +1083,13 @@ func TestExtraSingBoxWireGuardReserved(t *testing.T) { func TestExtraSingBoxWireGuardLocalAddress(t *testing.T) { node := nodeByName("WG") - out := ToSingBoxOutbound(node) - la, ok := out["local_address"].([]string) + ep := ToSingBoxWireGuardEndpoint(node) + addr, ok := ep["address"].([]string) if !ok { - t.Fatalf("expected local_address, got: %v", out["local_address"]) + t.Fatalf("expected address, got: %v", ep["address"]) } - if len(la) != 2 { - t.Errorf("expected 2 local addresses (ip+ipv6), got %d", len(la)) + if len(addr) != 2 { + t.Errorf("expected 2 addresses (ip+ipv6), got %d", len(addr)) } } diff --git a/internal/render/singbox.go b/internal/render/singbox.go index 98573e5..2e70b74 100644 --- a/internal/render/singbox.go +++ b/internal/render/singbox.go @@ -10,9 +10,16 @@ import ( // RenderSingBoxJson renders proxies as a sing-box JSON config. // Per review-resolution #42: full structure with log, inbounds, outbounds, route. +// Updated for sing-box 1.11+ migration: legacy inbound fields (sniff) → route rule actions, +// legacy special outbound (block) → route rule action (reject), WireGuard outbound → endpoint. func RenderSingBoxJson(proxies []model.ProxyNode) string { var nodeOutbounds []map[string]any + var wireGuardEndpoints []map[string]any for _, p := range proxies { + if wg := ToSingBoxWireGuardEndpoint(p); wg != nil { + wireGuardEndpoints = append(wireGuardEndpoints, wg) + continue + } if out := ToSingBoxOutbound(p); out != nil { nodeOutbounds = append(nodeOutbounds, out) } @@ -25,29 +32,26 @@ func RenderSingBoxJson(proxies []model.ProxyNode) string { } } - if len(tags) == 0 { - // return minimal config even with no supported nodes - } - - // Build outbounds: PROXY (selector), AUTO (urltest), node outbounds, DIRECT, REJECT + // Build outbounds: PROXY (selector), AUTO (urltest), node outbounds, DIRECT + // (REJECT is now a route rule action, not a special outbound) proxyOutbounds := append([]string{"AUTO"}, tags...) outbounds := []any{ map[string]any{ - "type": "selector", - "tag": "PROXY", - "outbounds": proxyOutbounds, - "default": "AUTO", - "interrupt_exist_connections": false, + "type": "selector", + "tag": "PROXY", + "outbounds": proxyOutbounds, + "default": "AUTO", + "interrupt_exist_connections": false, }, map[string]any{ - "type": "urltest", - "tag": "AUTO", - "outbounds": tags, - "url": model.TestURL, - "interval": "5m", - "tolerance": 50, - "interrupt_exist_connections": false, + "type": "urltest", + "tag": "AUTO", + "outbounds": tags, + "url": model.TestURL, + "interval": "5m", + "tolerance": 50, + "interrupt_exist_connections": false, }, } for _, out := range nodeOutbounds { @@ -55,7 +59,6 @@ func RenderSingBoxJson(proxies []model.ProxyNode) string { } outbounds = append(outbounds, map[string]any{"type": "direct", "tag": "DIRECT"}, - map[string]any{"type": "block", "tag": "REJECT"}, ) doc := map[string]any{ @@ -66,16 +69,26 @@ func RenderSingBoxJson(proxies []model.ProxyNode) string { "tag": "mixed-in", "listen": "0.0.0.0", "listen_port": 7890, - "sniff": true, }, }, "outbounds": outbounds, "route": map[string]any{ "auto_detect_interface": true, "final": "PROXY", + "rules": []any{ + // Migrated from legacy inbound sniff field (sing-box 1.11+) + map[string]any{"action": "sniff"}, + // Migrated from legacy block outbound (sing-box 1.11+) + map[string]any{"action": "reject", "outbound": "REJECT"}, + }, }, } + // Add WireGuard endpoints if any (sing-box 1.11+ migration) + if len(wireGuardEndpoints) > 0 { + doc["endpoints"] = wireGuardEndpoints + } + data, _ := json.MarshalIndent(doc, "", " ") return string(data) } @@ -243,31 +256,6 @@ func ToSingBoxOutbound(proxy model.ProxyNode) map[string]any { "password": proxy["password"], }) - case "wireguard": - var localAddress []string - if ip := stringSetting(proxy["ip"]); ip != "" { - localAddress = append(localAddress, ip) - } - if ipv6 := stringSetting(proxy["ipv6"]); ipv6 != "" { - localAddress = append(localAddress, ipv6) - } - result := util.StripUndefined(map[string]any{ - "type": "wireguard", - "tag": name, - "server": server, - "server_port": port, - "private_key": proxy["private-key"], - "peer_public_key": proxy["public-key"], - "pre_shared_key": proxy["pre-shared-key"], - }) - if len(localAddress) > 0 { - result["local_address"] = localAddress - } - if reserved := parseWireGuardReserved(proxy["reserved"]); reserved != nil { - result["reserved"] = reserved - } - return result - case "vmess": var tls any if getBool(proxy, "tls") { @@ -309,6 +297,51 @@ func ToSingBoxOutbound(proxy model.ProxyNode) map[string]any { return nil } +// ToSingBoxWireGuardEndpoint converts a WireGuard proxy node to a sing-box endpoint. +// Per sing-box 1.11+ migration: WireGuard outbound → endpoint format. +// Returns nil for non-wireguard proxies. +func ToSingBoxWireGuardEndpoint(proxy model.ProxyNode) map[string]any { + ptype := getString(proxy, "type") + if ptype != "wireguard" { + return nil + } + server := getString(proxy, "server") + port := getInt(proxy, "port") + name := getString(proxy, "name") + + var addresses []string + if ip := stringSetting(proxy["ip"]); ip != "" { + addresses = append(addresses, ip) + } + if ipv6 := stringSetting(proxy["ipv6"]); ipv6 != "" { + addresses = append(addresses, ipv6) + } + + peer := util.StripUndefined(map[string]any{ + "address": server, + "port": port, + "public_key": proxy["public-key"], + "allowed_ips": []string{"0.0.0.0/0", "::/0"}, + }) + if psk := stringSetting(proxy["pre-shared-key"]); psk != "" { + peer["pre_shared_key"] = psk + } + if reserved := parseWireGuardReserved(proxy["reserved"]); reserved != nil { + peer["reserved"] = reserved + } + + endpoint := util.StripUndefined(map[string]any{ + "type": "wireguard", + "tag": name, + "private_key": proxy["private-key"], + "peers": []any{peer}, + }) + if len(addresses) > 0 { + endpoint["address"] = addresses + } + return endpoint +} + func parseWireGuardReserved(value any) []int { switch v := value.(type) { case []any: diff --git a/internal/render/singbox_template.go b/internal/render/singbox_template.go new file mode 100644 index 0000000..3537f8d --- /dev/null +++ b/internal/render/singbox_template.go @@ -0,0 +1,788 @@ +package render + +import ( + "encoding/json" + "strings" + + "github.com/peterqiu0516/sub-store/internal/model" + "github.com/peterqiu0516/sub-store/internal/util" +) + +// RenderSingBoxWithTemplate renders proxies as a sing-box JSON config, +// applying the Clash-style routing template (proxy-groups, rules, DNS, rule-providers). +// If template is nil or empty, falls back to the default sing-box config (no template). +func RenderSingBoxWithTemplate(proxies []model.ProxyNode, template map[string]any) string { + if template == nil || len(template) == 0 { + return RenderSingBoxJson(proxies) + } + + // Parse proxies into node outbounds and WireGuard endpoints + var nodeOutbounds []map[string]any + var wireGuardEndpoints []map[string]any + for _, p := range proxies { + if wg := ToSingBoxWireGuardEndpoint(p); wg != nil { + wireGuardEndpoints = append(wireGuardEndpoints, wg) + continue + } + if out := ToSingBoxOutbound(p); out != nil { + nodeOutbounds = append(nodeOutbounds, out) + } + } + + // Collect node tags + nodeTags := make([]string, 0, len(nodeOutbounds)) + nodeTagSet := make(map[string]bool) + for _, out := range nodeOutbounds { + if t, ok := out["tag"].(string); ok { + nodeTags = append(nodeTags, t) + nodeTagSet[t] = true + } + } + + // Build outbounds from template proxy-groups + groupOutbounds, groupNames := buildSingBoxOutboundsFromTemplate(template, nodeTags) + allOutbounds := append([]any{}, groupOutbounds...) + for _, out := range nodeOutbounds { + allOutbounds = append(allOutbounds, out) + } + // Always add DIRECT and REJECT (block) outbounds. + // REJECT is kept as a block-type outbound because Clash proxy-groups reference it + // as a member (e.g. "🛑 全球拦截" → ["REJECT", "DIRECT"]). + // While sing-box 1.11+ deprecated block as a route rule action, a block outbound + // is still valid when referenced directly by selector/urltest groups. + allOutbounds = append(allOutbounds, + map[string]any{"type": "direct", "tag": "DIRECT"}, + map[string]any{"type": "block", "tag": "REJECT"}, + ) + + // Determine final outbound + finalOutbound := "PROXY" + if len(groupNames) > 0 { + finalOutbound = groupNames[0] + } + + // Build route rules from template rules, skipping rules that reference + // skipped rule-sets (those with empty .srs mappings). + skippedRuleSets := getSkippedRuleSets(template) + routeRules := buildSingBoxRouteRules(template, groupNames, nodeTagSet, skippedRuleSets) + + // Always add sniff action first + allRules := []any{ + map[string]any{"action": "sniff"}, + } + allRules = append(allRules, routeRules...) + + // Build the document + mixedPort := firstInt(template, "mixedPort", "mixed-port") + if mixedPort == 0 { + mixedPort = 7890 + } + + logLevel := firstStr(template, "logLevel", "log-level") + if logLevel == "" { + logLevel = "info" + } + + doc := map[string]any{ + "log": map[string]any{"level": logLevel}, + "inbounds": []any{ + map[string]any{ + "type": "mixed", + "tag": "mixed-in", + "listen": "0.0.0.0", + "listen_port": mixedPort, + }, + }, + "outbounds": allOutbounds, + "route": map[string]any{ + "auto_detect_interface": true, + "final": finalOutbound, + "rules": allRules, + "default_domain_resolver": map[string]any{"server": "local-dns"}, + }, + } + + // Add WireGuard endpoints + if len(wireGuardEndpoints) > 0 { + doc["endpoints"] = wireGuardEndpoints + } + + // Add DNS if configured + if dnsCfg := buildSingBoxDNS(template); dnsCfg != nil { + doc["dns"] = dnsCfg + } + + // Add rule_set if rule-providers configured + ruleSets := buildSingBoxRuleSets(template) + // Also add auto-generated rule_sets for GEOIP/GEOSITE rules + geoRuleSets := collectGeoRuleSets(template) + allRuleSets := append(ruleSets, geoRuleSets...) + if len(allRuleSets) > 0 { + route := doc["route"].(map[string]any) + route["rule_set"] = allRuleSets + } + + data, _ := jsonMarshalIndent(doc) + return data +} + +// buildSingBoxOutboundsFromTemplate converts Clash proxy-groups to sing-box outbounds. +func buildSingBoxOutboundsFromTemplate(template map[string]any, nodeTags []string) ([]any, []string) { + groups := extractGroupTemplates(template) + if len(groups) == 0 { + // Fallback: default PROXY + AUTO + proxyOutbounds := append([]string{"AUTO"}, nodeTags...) + return []any{ + map[string]any{ + "type": "selector", + "tag": "PROXY", + "outbounds": proxyOutbounds, + "default": "AUTO", + "interrupt_exist_connections": false, + }, + map[string]any{ + "type": "urltest", + "tag": "AUTO", + "outbounds": nodeTags, + "url": model.TestURL, + "interval": "5m", + "tolerance": 50, + "interrupt_exist_connections": false, + }, + }, []string{"PROXY", "AUTO"} + } + + // Expand group proxies and build sing-box outbounds + expandedGroups := expandGroupsForSingBox(groups, nodeTags) + + var outbounds []any + var groupNames []string + groupNameSet := make(map[string]bool) + + for _, g := range expandedGroups { + if len(g.proxies) == 0 { + continue + } + name := getString(g.template, "name") + groupNames = append(groupNames, name) + groupNameSet[name] = true + + clashType := getString(g.template, "type") + outbound := buildSingBoxGroupOutbound(name, clashType, g.proxies, g.template, groupNameSet) + if outbound != nil { + outbounds = append(outbounds, outbound) + } + } + + return outbounds, groupNames +} + +type expandedGroup struct { + template map[string]any + proxies []string +} + +// expandGroupsForSingBox expands $all and filter regex for each group, +// then filters references to non-existent nodes/groups. +func expandGroupsForSingBox(groups []map[string]any, nodeTags []string) []expandedGroup { + // First pass: expand all groups + var expanded []expandedGroup + for _, group := range groups { + expanded = append(expanded, expandedGroup{ + template: group, + proxies: ExpandGroupProxies(group, nodeTags), + }) + } + + // Collect all valid group names + groupNames := make(map[string]bool) + for _, g := range expanded { + if len(g.proxies) > 0 { + groupNames[getString(g.template, "name")] = true + } + } + + // Second pass: filter references + allowedLiterals := map[string]bool{"DIRECT": true, "REJECT": true, "PASS": true} + nodeSet := make(map[string]bool) + for _, t := range nodeTags { + nodeSet[t] = true + } + + for i := range expanded { + var filtered []string + seen := make(map[string]bool) + for _, name := range expanded[i].proxies { + if seen[name] { + continue + } + seen[name] = true + if nodeSet[name] || groupNames[name] || allowedLiterals[name] { + filtered = append(filtered, name) + } + } + expanded[i].proxies = filtered + } + + return expanded +} + +// buildSingBoxGroupOutbound converts a single Clash proxy-group to a sing-box outbound. +func buildSingBoxGroupOutbound(name, clashType string, proxies []string, template map[string]any, groupNames map[string]bool) map[string]any { + // Map DIRECT/REJECT to sing-box equivalents + // sing-box uses "direct" outbound tag and route rule "reject" action + sbProxies := make([]string, 0, len(proxies)) + for _, p := range proxies { + sbProxies = append(sbProxies, p) + } + + switch clashType { + case "select": + return util.StripUndefined(map[string]any{ + "type": "selector", + "tag": name, + "outbounds": sbProxies, + "interrupt_exist_connections": false, + }) + + case "url-test": + interval := getString(template, "interval") + if interval == "" { + interval = "5m" + } + // Clash interval is in seconds; convert to sing-box duration string + if n := toInt(interval); n > 0 { + interval = formatDuration(n) + } + tolerance := toInt(getString(template, "tolerance")) + if tolerance == 0 { + tolerance = 50 + } + return util.StripUndefined(map[string]any{ + "type": "urltest", + "tag": name, + "outbounds": sbProxies, + "url": strOr(template, "url", model.TestURL), + "interval": interval, + "tolerance": tolerance, + "interrupt_exist_connections": false, + }) + + case "fallback": + // sing-box has no fallback type; use urltest as closest equivalent + interval := getString(template, "interval") + if interval == "" { + interval = "5m" + } + if n := toInt(interval); n > 0 { + interval = formatDuration(n) + } + return util.StripUndefined(map[string]any{ + "type": "urltest", + "tag": name, + "outbounds": sbProxies, + "url": strOr(template, "url", model.TestURL), + "interval": interval, + "tolerance": 50, + "interrupt_exist_connections": false, + }) + + case "load-balance": + // sing-box has no load-balance type; use selector as closest equivalent + strategy := getString(template, "strategy") + _ = strategy // not directly mappable + return util.StripUndefined(map[string]any{ + "type": "selector", + "tag": name, + "outbounds": sbProxies, + "interrupt_exist_connections": false, + }) + + default: + // Unknown type: default to selector + return util.StripUndefined(map[string]any{ + "type": "selector", + "tag": name, + "outbounds": sbProxies, + "interrupt_exist_connections": false, + }) + } +} + +// buildSingBoxRouteRules converts Clash rules to sing-box route rules. +// Rules referencing skipped rule-sets (no sing-box equivalent) are skipped. +func buildSingBoxRouteRules(template map[string]any, groupNames []string, nodeTagSet map[string]bool, skippedRuleSets map[string]bool) []any { + rules, _ := template["rules"].([]any) + if len(rules) == 0 { + return []any{ + map[string]any{"outbound": "PROXY"}, + } + } + + groupSet := make(map[string]bool) + for _, g := range groupNames { + groupSet[g] = true + } + + var result []any + for _, r := range rules { + ruleStr, ok := r.(string) + if !ok || ruleStr == "" { + continue + } + // Skip RULE-SET rules that reference skipped rule-sets + parts := strings.Split(ruleStr, ",") + if len(parts) >= 2 && strings.TrimSpace(parts[0]) == "RULE-SET" { + rsName := strings.TrimSpace(parts[1]) + if skippedRuleSets[rsName] { + continue + } + } + sbRule := convertClashRuleToSingBox(ruleStr, groupSet, nodeTagSet) + if sbRule != nil { + result = append(result, sbRule) + } + } + + return result +} + +// getSkippedRuleSets returns the set of rule-provider names that have empty +// mappings in clashRuleSetMappings (i.e., no sing-box equivalent exists). +func getSkippedRuleSets(template map[string]any) map[string]bool { + skipped := make(map[string]bool) + rpRaw, ok := template["ruleProviders"] + if !ok { + rpRaw, ok = template["rule-providers"] + } + if !ok || rpRaw == nil { + return skipped + } + rp, ok := rpRaw.(map[string]any) + if !ok { + return skipped + } + for name := range rp { + if srsURL, mapped := clashRuleSetMappings[name]; mapped && srsURL == "" { + skipped[name] = true + } + } + return skipped +} + +// collectGeoRuleSets scans Clash rules for GEOIP/GEOSITE references and returns +// auto-generated rule_set definitions pointing to SagerNet's sing-geoip/sing-geosite repos. +func collectGeoRuleSets(template map[string]any) []any { + rules, _ := template["rules"].([]any) + seen := make(map[string]bool) + var result []any + + for _, r := range rules { + ruleStr, ok := r.(string) + if !ok { + continue + } + parts := strings.Split(ruleStr, ",") + if len(parts) < 2 { + continue + } + ruleType := strings.TrimSpace(parts[0]) + code := strings.ToLower(strings.TrimSpace(parts[1])) + + var tag, url string + switch ruleType { + case "GEOIP": + tag = "geoip-" + code + url = "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-" + code + ".srs" + case "GEOSITE": + tag = "geosite-" + code + url = "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-" + code + ".srs" + default: + continue + } + + if seen[tag] { + continue + } + seen[tag] = true + + result = append(result, map[string]any{ + "tag": tag, + "type": "remote", + "format": "binary", + "url": url, + "download_detour": "DIRECT", + }) + } + + return result +} + +// convertClashRuleToSingBox converts a single Clash rule line to a sing-box route rule. +func convertClashRuleToSingBox(rule string, groupSet, nodeSet map[string]bool) map[string]any { + parts := strings.Split(rule, ",") + if len(parts) < 2 { + return nil + } + + ruleType := strings.TrimSpace(parts[0]) + + // Determine the outbound (policy) + var policy string + if ruleType == "MATCH" { + if len(parts) >= 2 { + policy = strings.TrimSpace(parts[1]) + } + } else { + if len(parts) >= 3 { + policy = strings.TrimSpace(parts[2]) + } + } + + // Map policy to sing-box outbound + outbound := mapPolicyToSingBox(policy, groupSet, nodeSet) + + switch ruleType { + case "DOMAIN": + return map[string]any{"domain": []string{parts[1]}, "outbound": outbound} + + case "DOMAIN-SUFFIX": + return map[string]any{"domain_suffix": []string{parts[1]}, "outbound": outbound} + + case "DOMAIN-KEYWORD": + return map[string]any{"domain_keyword": []string{parts[1]}, "outbound": outbound} + + case "IP-CIDR", "IP-CIDR6": + opts := []string{} + for i := 3; i < len(parts); i++ { + opt := strings.TrimSpace(parts[i]) + if opt == "no-resolve" { + opts = append(opts, "no_resolve") + } + } + rule := map[string]any{"ip_cidr": []string{parts[1]}, "outbound": outbound} + if len(opts) > 0 { + rule["ip_cidr_no_resolve"] = true + } + return rule + + case "GEOIP": + geoip := strings.TrimSpace(parts[1]) + // sing-box 1.12+ removed legacy geoip database; use rule_set instead. + // Auto-map common geoip codes to remote rule_sets. + return map[string]any{"rule_set": "geoip-" + strings.ToLower(geoip), "outbound": outbound} + + case "GEOSITE": + geosite := strings.TrimSpace(parts[1]) + // sing-box 1.12+ removed legacy geosite database; use rule_set instead. + return map[string]any{"rule_set": "geosite-" + strings.ToLower(geosite), "outbound": outbound} + + case "PROCESS-NAME": + return map[string]any{"process_name": []string{parts[1]}, "outbound": outbound} + + case "DST-PORT": + return map[string]any{"port": parts[1], "outbound": outbound} + + case "SRC-PORT": + return map[string]any{"source_port": parts[1], "outbound": outbound} + + case "RULE-SET": + // RULE-SET,provider-name,policy → rule_set + outbound + return map[string]any{"rule_set": parts[1], "outbound": outbound} + + case "MATCH": + // MATCH is the final catch-all; handled by route.final + return nil + + default: + return nil + } +} + +// mapPolicyToSingBox maps a Clash policy name to the sing-box outbound tag. +func mapPolicyToSingBox(policy string, groupSet, nodeSet map[string]bool) string { + switch policy { + case "DIRECT": + return "DIRECT" + case "REJECT": + return "REJECT" + case "PASS": + return "DIRECT" + case "": + return "PROXY" + default: + // It's a group name or node name + if groupSet[policy] || nodeSet[policy] { + return policy + } + return "PROXY" + } +} + +// buildSingBoxDNS converts Clash DNS config to sing-box DNS config. +func buildSingBoxDNS(template map[string]any) map[string]any { + dnsRaw, ok := template["dns"] + if !ok || dnsRaw == nil { + return nil + } + dns, ok := dnsRaw.(map[string]any) + if !ok { + return nil + } + + // Build sing-box DNS servers from nameserver list + var servers []any + if nameservers, ok := dns["nameserver"].([]any); ok { + for _, ns := range nameservers { + nsStr, ok := ns.(string) + if !ok || nsStr == "" { + continue + } + servers = append(servers, convertDNSServer(nsStr)) + } + } + + if len(servers) == 0 { + return nil + } + + // sing-box 1.12+ requires a domain resolver for DNS servers that use domain addresses. + // Add a local UDP resolver as the first server to resolve other servers' domain names. + localServer := map[string]any{"type": "local", "tag": "local-dns"} + servers = append([]any{localServer}, servers...) + + // Add domain_resolver to each non-local server so they can resolve their own domain address + for i, s := range servers { + sm, ok := s.(map[string]any) + if !ok { + continue + } + stype, _ := sm["type"].(string) + if stype == "local" || stype == "fakeip" { + continue + } + sm["domain_resolver"] = "local-dns" + servers[i] = sm + } + + result := map[string]any{ + "servers": servers, + } + + // Set the local resolver as the default domain resolver + result["final"] = "local-dns" + + // Handle fake-ip mode (sing-box 1.12+ format) + if mode := getString(dns, "enhanced-mode"); mode == "fake-ip" { + // Add a fakeip DNS server as the last server + fakeipServer := map[string]any{ + "type": "fakeip", + "tag": "fakeip", + } + servers = append(servers, fakeipServer) + + // Add DNS rule to route A/AAAA queries to fakeip + rules := []any{ + map[string]any{ + "query_type": []string{"A", "AAAA"}, + "server": "fakeip", + }, + } + result["rules"] = rules + } + + // Handle IPv6 setting + if ipv6, ok := dns["ipv6"].(bool); ok && !ipv6 { + result["strategy"] = "prefer_ipv4" + } + + return result +} + +// convertDNSServer converts a Clash nameserver URL to a sing-box DNS server. +func convertDNSServer(ns string) map[string]any { + // Clash formats: "https://doh.pub/dns-query", "https://dns.alidns.com/dns-query", + // "tls://8.8.8.8", "quic://dns.adguard.com", "system", "localhost" + switch { + case strings.HasPrefix(ns, "https://"): + return map[string]any{"type": "https", "server": extractHost(ns, "https://")} + case strings.HasPrefix(ns, "tls://"): + return map[string]any{"type": "tls", "server": strings.TrimPrefix(ns, "tls://")} + case strings.HasPrefix(ns, "quic://"): + return map[string]any{"type": "quic", "server": strings.TrimPrefix(ns, "quic://")} + case strings.HasPrefix(ns, "h3://"): + return map[string]any{"type": "h3", "server": strings.TrimPrefix(ns, "h3://")} + case strings.HasPrefix(ns, "tcp://"): + return map[string]any{"type": "tcp", "server": strings.TrimPrefix(ns, "tcp://")} + case ns == "system": + return map[string]any{"type": "local"} + case ns == "localhost": + return map[string]any{"type": "local"} + default: + // Assume it's a plain IP/UDP server + return map[string]any{"type": "udp", "server": ns} + } +} + +// clashRuleSetMappings maps common Clash rule-provider names to sing-box +// community-maintained .srs binary rule-set URLs. +// When a Clash rule-provider name has a known sing-box equivalent, +// the .srs URL is used instead of the Clash .list/.yaml URL. +var clashRuleSetMappings = map[string]string{ + // ACL4SSR rule names → SagerNet sing-geosite/sing-geoip + "LocalAreaNetwork": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-private.srs", + "UnBan": "", + "BanAD": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs", + "BanProgramAD": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs", + "GoogleCN": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-google.srs", + "SteamCN": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-steam.srs", + "Microsoft": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-microsoft.srs", + "Apple": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-apple.srs", + "Telegram": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-telegram.srs", + "YouTube": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-youtube.srs", + "Netflix": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-netflix.srs", + "DisneyPlus": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-disney.srs", + "ProxyGFWlist": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs", + "ChinaDomain": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs", + "ChinaCompanyIp": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs", + "ChinaIp": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs", + "Download": "", + + // Loyalsoldier rule names → SagerNet sing-geosite/sing-geoip + "reject": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs", + "icloud": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-icloud.srs", + "apple": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-apple.srs", + "google": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-google.srs", + "proxy": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs", + "direct": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs", + "private": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-private.srs", + "gfw": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-gfw.srs", + "greatfire": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-greatfire.srs", + "tld-not-cn": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-tld-!cn.srs", + "telegramcidr": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-telegram.srs", + "cncidr": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs", + "lancidr": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-private.srs", + "applications": "", + + // blackmatrix7 rule names → SagerNet sing-geosite + "OpenAI": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-openai.srs", + "Claude": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-anthropic.srs", + "Gemini": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-google.srs", + "Disney": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-disney.srs", + "Spotify": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-spotify.srs", + "GitHub": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-github.srs", + "China": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs", + + // Common service names + "Google": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-google.srs", + "Twitter": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-twitter.srs", + "Facebook": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-facebook.srs", + "TikTok": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-tiktok.srs", + "Bilibili": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-bilibili.srs", + "PayPal": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-paypal.srs", +} + +// buildSingBoxRuleSets converts Clash rule-providers to sing-box rule_set. +// When a Clash rule-provider name has a known sing-box .srs equivalent in +// clashRuleSetMappings, the binary .srs URL is used. Otherwise the original +// Clash URL is kept with source format (may not work for all Clash-format files). +func buildSingBoxRuleSets(template map[string]any) []any { + rpRaw, ok := template["ruleProviders"] + if !ok { + rpRaw, ok = template["rule-providers"] + } + if !ok || rpRaw == nil { + return nil + } + rp, ok := rpRaw.(map[string]any) + if !ok { + return nil + } + + var result []any + for name, cfgRaw := range rp { + cfg, ok := cfgRaw.(map[string]any) + if !ok { + continue + } + + // Check if this rule-provider name has a sing-box .srs mapping + if srsURL, mapped := clashRuleSetMappings[name]; mapped { + if srsURL == "" { + // Empty mapping = skip this rule-set (no sing-box equivalent) + continue + } + rs := map[string]any{ + "tag": name, + "type": "remote", + "format": "binary", + "url": srsURL, + "download_detour": "DIRECT", + } + if interval := toInt(getString(cfg, "interval")); interval > 0 { + rs["update_interval"] = formatDuration(interval) + } + result = append(result, rs) + continue + } + + // Fallback: use the original Clash URL with source format + url := getString(cfg, "url") + if url == "" { + continue + } + rs := map[string]any{ + "tag": name, + "type": "remote", + "format": "source", + "url": url, + "download_detour": "DIRECT", + } + if interval := toInt(getString(cfg, "interval")); interval > 0 { + rs["update_interval"] = formatDuration(interval) + } + result = append(result, rs) + } + + return result +} + +// --- helpers --- + +func toInt(s string) int { + n := 0 + for i := 0; i < len(s); i++ { + if s[i] < '0' || s[i] > '9' { + return 0 + } + n = n*10 + int(s[i]-'0') + } + return n +} + +func formatDuration(seconds int) string { + if seconds <= 0 { + return "5m" + } + if seconds%3600 == 0 { + return itoa(seconds/3600) + "h" + } + if seconds%60 == 0 { + return itoa(seconds/60) + "m" + } + return itoa(seconds) + "s" +} + +func extractHost(url, prefix string) string { + s := strings.TrimPrefix(url, prefix) + // Remove path + if idx := strings.Index(s, "/"); idx >= 0 { + s = s[:idx] + } + return s +} + +func jsonMarshalIndent(v any) (string, error) { + data, err := json.MarshalIndent(v, "", " ") + return string(data), err +}