feat(commands): 推送日志第三视图与 CSV 导入模板

按对齐计划 Phase1:Commands 页增加推送日志筛选视图;补全 servers_import_template.csv;扩写功能指南 §12.6/12.8/12.10 与 acceptance_catalog。
This commit is contained in:
Nexus Agent
2026-06-08 02:45:17 +08:00
parent dfb0ea2d8f
commit fb6a4be797
60 changed files with 1513 additions and 33 deletions
@@ -0,0 +1,23 @@
# Changelog — 缺失功能对齐计划
**日期**2026-06-07
## 摘要
新增 `docs/design/plans/2026-06-07-missing-features-alignment-plan.md`,将相对功能 SSOT 的缺口、待部署项、API 无 UI、产品 backlog 与验收工程债共 **31 项**逐项编号(A~E),含优先级、验收标准与推荐排期。
## 动机
用户要求计划任务清单;避免与 `dfb0ea2` 已修复项(脚本库/调度)及已实现误报(WebSSH 自动重连、CSV 导入、文件预览)重复排期。
## 涉及文件
- `docs/design/plans/2026-06-07-missing-features-alignment-plan.md`(新建)
## 迁移 / 重启
## 验证
打开计划文档,按 ID 勾选进度总表。
@@ -0,0 +1,33 @@
# Changelog — 对齐计划 Phase 1B-01/B-04/B-05 + 文档)
**日期**2026-06-07
## 摘要
`docs/design/plans/2026-06-07-missing-features-alignment-plan.md` 实施首批 P1 项:Commands 推送日志第三视图、CSV 导入静态模板、功能指南 §12.6/12.8/12.10 与附录 E.1 扩写;`acceptance_catalog` 与 E2E 用例同步。
## 动机
计划 Week 1 优先项;旧版 `commands.html` 三视图在 SPA 缺推送日志;导入对话框链接的模板文件不存在。
## 涉及文件
- `frontend/src/pages/CommandsPage.vue` — 推送日志视图 + status/sync_mode/trigger 筛选
- `web/app/servers_import_template.csv` — 静态模板(与 `GET /servers/import/template` 列一致)
- `frontend/src/pages/ServersPage.vue` — 模板说明
- `docs/project/nexus-functional-development-guide.md` — §12.6/12.8/12.10
- `docs/project/nexus-functional-development-guide-appendix.md` — E.1
- `tests/acceptance_catalog.py`
- `frontend/e2e/full-acceptance.spec.mjs`
## 迁移 / 重启
- 仅前端静态 + 文档;`vite build` 后部署 `web/app/`
## 验证
```bash
cd frontend && npx vite build
# Commands #/commands → 推送日志视图 → 筛选器可见、表格加载
# Servers 导入对话框 → 下载模板 CSV 200
```
@@ -0,0 +1,197 @@
# Nexus 6.0 — 缺失功能对齐计划(Backlog)
**日期**2026-06-07
**基线**`docs/project/nexus-functional-development-guide.md` §12 + 附录 E/J · `dfb0ea2`(脚本库+调度已 push
**对照审计**`docs/reports/2026-06-06-frontend-14p-contract-audit.md`
**用途**:逐项排期、勾选验收;**禁止**与已完成项重复实现。
---
## 0. 总览
| 类别 | 项数 | 说明 |
|------|------|------|
| **A 待部署/生产验证** | 4 | 代码已在 Gitea,生产未生效或未点验 |
| **B 14 页 SPA 能力缺口** | 6 | 相对功能 SSOT / 旧版 HTML 仍缺 UI 或细节 |
| **C 后端有 API、前端无页** | 4 | Sync/Assets 等 API 已存在 |
| **D 产品增强(P1/P2/可选)** | 5 | 非 14 页核心,但 backlog 仍列 |
| **E 验收与工程债** | 12 | L4/L5、POSIX、ENH、文档 SSOT |
| **合计可排期项** | **31** | 不含「已否决」功能 |
**14 页 API 路径层**2026-06-06 审计 **PASS**(端点存在 ≠ 能力完整)。
**已否决(不做,勿排期)**:RBAC、移动端、会话录像、审计 CSV 导出、邮件报告、Redis Cluster、独立文件编辑器模块。
---
## A. 待部署与生产验证(优先)
> 代码已合入 `main@dfb0ea2`,**不算功能缺失**,但必须上线后才算对齐完成。
| ID | 任务 | 优先级 | 状态 | 涉及 | 验收标准 |
|----|------|--------|------|------|----------|
| A-01 | **生产部署** `dfb0ea2`API + 前端静态) | P0 | ☐ | `deploy/deploy-production.sh` | 生产 `git pull` 后 API 重启;`web/app/` 同步;`/health` 200 |
| A-02 | **DB 迁移** `push_schedules.target_path` | P0 | ☐ | `migrations.py` 启动时 DDL | 生产 `SHOW COLUMNS FROM push_schedules LIKE 'target_path'` 有列 |
| A-03 | **脚本库**生产点验 | P0 | ☐ | ScriptsPage + `/scripts/exec` | 新建 ops 脚本 → 选机执行 → 状态条 #id;历史按 script_id 过滤;长任务/凭据可用 |
| A-04 | **推送调度**生产点验 | P0 | ☐ | SchedulesPage + `schedule_runner` | 新建 cron 推送:target_path 可选、next_run 有值、runNow 留空目标走各机配置;script 调度 runNow 走 `/scripts/exec` |
| A-05 | **边端 Agent** 401 停循环 | P1 | ☐ | `web/agent/agent.py` | 错误 key 心跳 401 后子机 agent 不再无限重试(需各机同步 agent 文件) |
**依赖**A-01 → A-02 → A-03/A-04 可并行点验。
---
## B. 十四页 SPA — 相对设计 SSOT 的能力缺口
| ID | 页面 | 缺失能力 | 优先级 | 状态 | 设计依据 | 验收标准 |
|----|------|----------|--------|------|----------|----------|
| B-01 | **Commands** `/commands` | **推送日志视图**(第三 Tab:rsync 历史、状态/模式/触发源过滤) | P1 | ☐ | 旧版 `commands.html` 三视图;现 SPA 仅命令+会话 | 第三视图可调 `GET /servers/logs` 或 sync_logs 分页 API;筛选与 Push 历史一致 |
| B-02 | **Dashboard** `/` | **历史趋势图**(CPU/内存/磁盘时序,非仅 Redis 实时) | P2 | ☐ | `nexus-full-site-features.md` §23 | 至少 24h 折线图;数据来自 MySQL 历史或现有 heartbeat 落库 |
| B-03 | **Files** `/files` | **树形侧栏**目录导航 | P3 | ☐ | 归档 §12 文件管理「未实现:树形侧栏」 | 左树右表;与 browse API 联动 |
| B-04 | **Servers** `/servers` | **CSV 导入模板**静态文件缺失 | P2 | ☐ | UI 链到 `/app/servers_import_template.csv` 但仓库无此文件 | 提供模板 CSV + 文档列说明;导入 E2E 一条 |
| B-05 | **Schedules** `/schedules` | **设计文档 §12.8 扩写**push/script、cron/once 已代码实现) | P2 | ☐ | 功能指南仍只写一行「Cron 调度推送」 | 更新 SSOT 与附录 E.1 字段表;避免下轮误判缺失 |
| B-06 | **Settings** `/settings` | **子机 Agent 批量同步入口**(若运维需要一键提示) | P3 | ☐ | 边端 A-05 依赖人工 scp | 文档或设置页展示 agent 升级/同步命令(非必须新 API) |
**说明(勿重复做)**
- **WebSSH 断线自动重连**`useTerminalSessions.ts` 已实现指数退避重连 → 归档 §23 过时,仅需 **生产验证**,不新开 B 项。
- **CSV 批量导入**`ServersPage` + `POST /servers/import` **已实现** → 仅 B-04 补模板。
- **文件内容预览**`FilesDialogs.vue` preview **已实现** → 不列入缺口。
- **脚本库 / 调度**:B 类无缺口;归 **A-03/A-04 部署验证**
---
## C. 后端 API 已有、前端无独立页面
| ID | API 模块 | 端点(示例) | 缺失 UI | 优先级 | 状态 | 验收标准 |
|----|----------|--------------|---------|--------|------|----------|
| C-01 | **资产管理** | `GET/POST/PUT/DELETE /api/assets/platforms` | 无 `#/assets` 页;Platform/Node 仅在服务器表单下拉只读 | P2 | ☐ | 独立页或 Settings 子 TabPlatform/Node CRUD + 审计 |
| C-02 | **Sync 配置推送** | `POST /api/sync/config``/config/rollback` | 无配置批量下发 UI | P2 | ☐ | 选服务器 + key/value 或文件;回滚一次操作 |
| C-03 | **Sync 批量命令** | `POST /api/sync/commands` | 无独立页(脚本库部分覆盖) | P3 | ☐ | 与 Scripts 边界写清:临时命令 vs 入库脚本 |
| C-04 | **Sync SFTP** | `POST /api/sync/sftp` | 文件页 upload 走 `/sync/upload`SFTP 专用流未暴露 | P3 | ☐ | 文档明确等价路径或补 UI |
---
## D. 产品 Backlog(非 14 页核心)
| ID | 功能 | 优先级 | 状态 | 说明 | 验收标准 |
|----|------|--------|------|------|----------|
| D-01 | **Agent upgrade 与 install.sh venv 对齐** | P1 | ☐ | `upgrade-agent` API 已有;需与 `web/agent/install.sh` 路径/venv 一致 | 升级后 agent 版本与中心一致;install 脚本 idempotent |
| D-02 | **宝塔 API 监控集成** | 可选 | ☐ | 可选增强 | 设计文档 + 配置项 + 只读指标 |
| D-03 | **Agent mTLS** | 可选 | ☐ | 安全增强 | ADR + 双端证书轮换方案 |
| D-04 | **全局搜索**增强 | P3 | ☐ | `App.vue` 已有 `/search/` | 结果分组、键盘导航、schedules 新字段展示 |
| D-05 | **E2E:凭据轮询** | P2 | ☐ | 审计报告 §5 建议 | add-by-ip 失败 → pending → 重试/删除 Playwright |
---
## E. 验收、审计与文档工程债
### E.1 测试与验收(Phase F / L4L5
| ID | 任务 | 优先级 | 状态 | 命令/文档 |
|----|------|--------|------|-----------|
| E-01 | 修复本地 `local_verify.sh` 登录 401 环境 | P1 | ☐ | `.env` + `seed_local_admin.py` |
| E-02 | L4 Playwright 15 用例全绿 | P1 | ☐ | `frontend/e2e/full-acceptance.spec.mjs` |
| E-03 | L5 生产验收清单勾选 | P1 | ☐ | `production-verification-checklist.md` |
| E-04 | T-01 心跳 Redis 写入 | P2 | ☐ | Agent 60s → `heartbeat:{id}` |
| E-05 | T-02 WebSocket 告警 + Telegram | P2 | ☐ | 浏览器 WS + 消息 |
| E-06 | T-03 三层守护杀进程重启 | P2 | ☐ | Supervisor 恢复 |
| E-07 | T-05 install 向导五步 | P2 | ☐ | 干净环境 E2E |
| E-08 | `acceptance_catalog` 增 add-by-ip / schedules 字段 | P3 | ☐ | `tests/acceptance_catalog.py` |
### E.2 POSIX 审计批次(Phase E
| ID | 任务 | 状态 |
|----|------|------|
| E-09 | POSIX-14 `unix_ls.py` 边界用例 | ☐ |
| E-10 | POSIX-15 前端 `remotePath.ts` 扫尾 | ☐ |
| E-11 | POSIX-16 `sync_engine_v2` rsync 目标回归 | ☐ |
| E-12 | POSIX-17 生产 Win 开发 + Linux SSH 目标回归 | ☐ |
| E-13 | POSIX-18 `nexus-posix-paths.mdc` + 可选 CI | ☐ |
### E.3 增强项(Phase G
| ID | 任务 | 优先级 | 状态 |
|----|------|--------|------|
| E-14 | ENH-01 危险路径 chmod 二次确认 | P2 | ☐ |
| E-15 | ENH-02 `find -maxdepth` 替代大范围 chmod -R | P3 | ☐ |
| E-16 | ENH-03 预加载失败聚合提示 | P3 | ☐ |
| E-17 | ENH-04 `NEXUS_FILES_ELEVATION_DEFAULT` env | P3 | ☐ |
| E-18 | ENH-08 文件列表「权限」列默认隐藏 + 列设置 | P3 | ☐ |
### E.4 文档 SSOT 漂移(避免误判「缺失」)
| ID | 任务 | 优先级 | 状态 |
|----|------|--------|------|
| E-19 | 更新 `AI-HANDOFF-2026-06-03.md` 指针与 commit | P1 | ☐ |
| E-20 | 修正 `nexus-full-site-features.md` §23(重连/CSV/预览已实现) | P1 | ☐ |
| E-21 | 更新 `status.md`Vue SPA 非 Alpine | P2 | ☐ |
| E-22 | 扩写功能指南 §12.8 Schedules、§12.6 Scripts 能力表 | P2 | ☐ |
---
## 1. 推荐执行顺序
```
Week 0(立即)
A-01 → A-02 → A-03 + A-04 + A-05
Week 1P1 能力)
B-01 Commands 推送日志视图
B-04 CSV 模板
D-01 Agent upgrade 对齐
E-01 E-02 E-03
Week 2+P2/P3
B-02 Dashboard 趋势
C-01 资产管理页
C-02 配置推送 UI
E-09E-13 POSIX
D-02D-05 按需
```
---
## 2. 单项 DoD(通用)
每项关闭须满足:
1.`docs/design/specs/` 或本计划 ID 引用(中改以上)
2. 实现 + `bash scripts/local_verify.sh` 或针对性 pytest
3. `docs/changelog/YYYY-MM-DD-*.md`
4. 生产点验(A/B/C/D 类)或 E2EE-02
5. 更新功能指南 / 本表状态 ☐→☑
---
## 3. 进度总表
```
A 部署验证 [ ] 0/5
B 14页缺口 [ ] 0/6
C API无UI [ ] 0/4
D 产品backlog [ ] 0/5
E 工程债 [ ] 0/22
─────────────────────
合计 [ ] 0/31(不含已否决)
```
---
## 4. 相关文档
| 文档 | 路径 |
|------|------|
| 功能 SSOT | `docs/project/nexus-functional-development-guide.md` |
| 14 页契约审计 | `docs/reports/2026-06-06-frontend-14p-contract-audit.md` |
| Master backlog | `docs/project/2026-06-01-master-backlog-plan.md` |
| 脚本库修复 changelog | `docs/changelog/2026-06-07-scripts-spa-perfect-implementation.md` |
| 调度修复 changelog | `docs/changelog/2026-06-07-schedules-perfect-implementation.md` |
| 验收标准 | `docs/project/development-acceptance-standard.md` |
---
## 变更记录
| 日期 | 变更 |
|------|------|
| 2026-06-07 | 初版:31 项可排期 backlog;标注 dfb0ea2 待部署;剔除已实现误报(自动重连、CSV 导入、文件预览) |
@@ -253,12 +253,14 @@ useTerminalSettings → localStorage 主题/字体(非敏感)
| 方法 | 路径 | 说明 | | 方法 | 路径 | 说明 |
|------|------|------| |------|------|------|
| GET | `/` | 列表 | | GET | `/` | 列表(含 `next_run``target_path``schedule_type``run_mode` |
| POST | `/` | 创建cron + server_ids + source/target + sync_mode 或 script_id | | POST | `/` | 创建 push`source_path``target_path?``sync_mode``cron_expr`/`fire_at`script`script_id`/`script_content` |
| PUT | `/{id}` | 更新 | | PUT | `/{id}` | 更新allowlist 含 `target_path` |
| DELETE | `/{id}` | 删除 | | DELETE | `/{id}` | 删除 |
后台 `schedule_runner` 每分钟扫描 `enabled=1` 且 cron 到期项 → 调 SyncEngine 或 ScriptService `PushSchedule.target_path` 留空时 runner / `runNow` 与各机 `servers.target_path` 一致
后台 `schedule_runner` 每分钟扫描 `enabled=1` 且到期项 → SyncEngineV2 或 ScriptService。
### E.2 重试 `/api/retries` ### E.2 重试 `/api/retries`
@@ -586,11 +586,14 @@ main.ts → App.vue(侧栏/搜索)→ router-view
| 功能 | API | | 功能 | API |
|------|-----| |------|-----|
| 脚本 CRUD | `/scripts/` | | 脚本 CRUD | `GET/POST/PUT/DELETE /scripts/`(分类 ops/deploy/check/cleanup |
| Monaco 编辑 | content 字段 | | Monaco 编辑 | `ScriptContentEditor` · `content` 字段 |
| 执行 | `POST /scripts/exec` + 轮询 executions | | 库内执行 | `POST /scripts/exec``script_id``command` 二选一) |
| 临时命令 | quick exec 面板 | | 临时命令 | 页内 quick exec 面板 |
| 停止 | `POST /scripts/executions/{id}/stop` | | 长任务 / DB 凭据 | `long_task``credential_id``GET /scripts/exec-config` |
| 执行状态 | 10s 轮询 `GET /scripts/executions/{id}` |
| 历史 | `GET /scripts/executions?script_id=` |
| 停止 / 重试 / 卡住 | `POST .../stop``.../retry``.../mark-stuck` |
### 12.7 CredentialsPage `/credentials` ### 12.7 CredentialsPage `/credentials`
@@ -606,7 +609,15 @@ main.ts → App.vue(侧栏/搜索)→ router-view
### 12.8 SchedulesPage `/schedules` ### 12.8 SchedulesPage `/schedules`
Cron 调度推送;`runNow``POST /sync/files`cron 前端正则校验。 | 功能 | API / 行为 |
|------|------------|
| 类型 | `schedule_type`: `push`rsync)或 `script`ScriptService |
| 运行模式 | `run_mode`: `cron`5 字段 cron_expr)或 `once`fire_at |
| 推送字段 | `source_path`(必填)、`target_path`(可选,留空走各机配置)、`sync_mode` |
| 脚本字段 | `script_id``script_content``exec_timeout``long_task` |
| 列表 | `next_run` API 计算;`GET /schedules/` |
| 立即执行 | push → `POST /sync/files`script → `POST /scripts/exec` |
| 后台 | `schedule_runner` 60s 扫描到期项 |
### 12.9 RetriesPage `/retries` ### 12.9 RetriesPage `/retries`
@@ -614,7 +625,11 @@ Cron 调度推送;`runNow` → `POST /sync/files`cron 前端正则校验。
### 12.10 CommandsPage `/commands` ### 12.10 CommandsPage `/commands`
命令视图 / 会话视图;`GET /assets/command-logs|ssh-sessions` | 视图 | API | 筛选 |
|------|-----|------|
| 命令视图 | `GET /assets/command-logs` | server_id |
| 会话视图 | `GET /assets/ssh-sessions` | server_id |
| 推送日志 | `GET /servers/logs` | server_id、status、sync_mode、trigger_type |
### 12.11 AlertsPage `/alerts` ### 12.11 AlertsPage `/alerts`
+4 -1
View File
@@ -108,11 +108,14 @@ test('10 retries list', async ({ page }) => {
await expect(page.getByText(/重试|队列/).first()).toBeVisible({ timeout: 20000 }) await expect(page.getByText(/重试|队列/).first()).toBeVisible({ timeout: 20000 })
}) })
test('11 commands: command and session views', async ({ page }) => { test('11 commands: command, session and push log views', async ({ page }) => {
await login(page) await login(page)
await nav(page, '/commands') await nav(page, '/commands')
await expect(page.getByText('命令日志')).toBeVisible({ timeout: 20000 }) await expect(page.getByText('命令日志')).toBeVisible({ timeout: 20000 })
await page.locator('.v-card-title .v-select').first().click() await page.locator('.v-card-title .v-select').first().click()
await page.locator('.v-overlay-container').getByText('推送日志').click()
await expect(page.locator('table').first()).toBeVisible()
await page.locator('.v-card-title .v-select').first().click()
await page.locator('.v-overlay-container').getByText('会话视图').click() await page.locator('.v-overlay-container').getByText('会话视图').click()
await expect(page.locator('table').first()).toBeVisible() await expect(page.locator('table').first()).toBeVisible()
}) })
+210 -16
View File
@@ -1,19 +1,61 @@
<template> <template>
<v-container fluid class="pa-6"> <v-container fluid class="pa-6">
<v-card elevation="0" border rounded="lg"> <v-card elevation="0" border rounded="lg">
<v-card-title class="d-flex align-center"> <v-card-title class="d-flex align-center flex-wrap ga-2">
命令日志 命令日志
<v-spacer /> <v-spacer />
<v-select <v-select
v-model="viewMode" v-model="viewMode"
:items="[{ title: '命令视图', value: 'commands' }, { title: '会话视图', value: 'sessions' }]" :items="viewModeOptions"
item-title="title" item-title="title"
item-value="value" item-value="value"
variant="outlined" variant="outlined"
density="compact" density="compact"
hide-details hide-details
style="max-width: 160px" style="max-width: 160px"
@update:model-value="loadData" @update:model-value="onViewModeChange"
/>
<v-select
v-if="viewMode === 'push'"
v-model="pushStatusFilter"
:items="pushStatusOptions"
item-title="label"
item-value="value"
label="状态"
variant="outlined"
density="compact"
hide-details
clearable
style="max-width: 120px"
@update:model-value="onPushFilterChange"
/>
<v-select
v-if="viewMode === 'push'"
v-model="pushSyncModeFilter"
:items="pushSyncModeOptions"
item-title="label"
item-value="value"
label="模式"
variant="outlined"
density="compact"
hide-details
clearable
style="max-width: 120px"
@update:model-value="onPushFilterChange"
/>
<v-select
v-if="viewMode === 'push'"
v-model="pushTriggerFilter"
:items="pushTriggerOptions"
item-title="label"
item-value="value"
label="触发"
variant="outlined"
density="compact"
hide-details
clearable
style="max-width: 120px"
@update:model-value="onPushFilterChange"
/> />
<v-select <v-select
v-model="serverFilter" v-model="serverFilter"
@@ -25,9 +67,8 @@
density="compact" density="compact"
hide-details hide-details
style="max-width: 180px" style="max-width: 180px"
class="ml-3"
clearable clearable
@update:model-value="loadData" @update:model-value="onServerFilterChange"
/> />
</v-card-title> </v-card-title>
@@ -41,10 +82,10 @@
:items-length="total" :items-length="total"
:loading="loading" :loading="loading"
:page="page" :page="page"
:items-per-page="30" :items-per-page="itemsPerPage"
hover hover
density="compact" density="compact"
@update:page="page = $event; loadData()" @update:page="onPageChange"
> >
<template #item.command="{ item }"> <template #item.command="{ item }">
<code class="text-body-2">{{ item.command }}</code> <code class="text-body-2">{{ item.command }}</code>
@@ -65,16 +106,16 @@
<!-- Session View --> <!-- Session View -->
<v-data-table-server <v-data-table-server
v-else v-else-if="viewMode === 'sessions'"
:items="sessions" :items="sessions"
:headers="sessionHeaders" :headers="sessionHeaders"
:items-length="total" :items-length="total"
:loading="loading" :loading="loading"
:page="page" :page="page"
:items-per-page="30" :items-per-page="itemsPerPage"
hover hover
density="compact" density="compact"
@update:page="page = $event; loadData()" @update:page="onPageChange"
> >
<template #item.server_name="{ item }"> <template #item.server_name="{ item }">
<span class="font-weight-medium">{{ item.server_name || '—' }}</span> <span class="font-weight-medium">{{ item.server_name || '—' }}</span>
@@ -91,6 +132,60 @@
<div class="text-center text-medium-emphasis py-6">暂无数据</div> <div class="text-center text-medium-emphasis py-6">暂无数据</div>
</template> </template>
</v-data-table-server> </v-data-table-server>
<!-- Push Log View -->
<v-data-table-server
v-else
:items="pushLogs"
:headers="pushHeaders"
:items-length="total"
:loading="loading"
:page="page"
:items-per-page="itemsPerPage"
hover
density="compact"
@update:page="onPageChange"
>
<template #item.started_at="{ item }">
<span class="text-caption text-medium-emphasis">{{ item.started_at || '—' }}</span>
</template>
<template #item.server_name="{ item }">
<span class="text-medium-emphasis">{{ item.server_name || '—' }}</span>
</template>
<template #item.status="{ item }">
<v-chip :color="pushStatusColor(item.status)" size="small" variant="tonal" label>
{{ pushStatusLabel(item.status) }}
</v-chip>
</template>
<template #item.sync_mode="{ item }">
<span class="text-caption">{{ syncModeLabel(item.sync_mode) }}</span>
</template>
<template #item.trigger_type="{ item }">
<span class="text-caption">{{ triggerLabel(item.trigger_type) }}</span>
</template>
<template #item.source_path="{ item }">
<span class="text-caption text-truncate d-inline-block" style="max-width: 200px" :title="item.source_path">
{{ item.source_path }}
</span>
</template>
<template #item.target_path="{ item }">
<span class="text-caption text-truncate d-inline-block" style="max-width: 160px" :title="item.target_path">
{{ item.target_path }}
</span>
</template>
<template #item.error_message="{ item }">
<span
v-if="item.error_message"
class="text-caption text-error text-truncate d-inline-block"
style="max-width: 180px"
:title="item.error_message"
>{{ item.error_message }}</span>
<span v-else class="text-caption text-medium-emphasis"></span>
</template>
<template #no-data>
<div class="text-center text-medium-emphasis py-6">暂无推送记录</div>
</template>
</v-data-table-server>
</v-card> </v-card>
</v-container> </v-container>
</template> </template>
@@ -101,21 +196,54 @@ import { http } from '@/api'
import { useServerList } from '@/composables/useServerList' import { useServerList } from '@/composables/useServerList'
import { useSnackbar } from '@/composables/useSnackbar' import { useSnackbar } from '@/composables/useSnackbar'
import { formatApiError } from '@/utils/apiError' import { formatApiError } from '@/utils/apiError'
import type { CommandLogItem, SshSessionItem } from '@/types/api' import type { CommandLogItem, PushItem, SshSessionItem } from '@/types/api'
type ViewMode = 'commands' | 'sessions' | 'push'
const snackbar = useSnackbar() const snackbar = useSnackbar()
const { servers: serverList, loadServers } = useServerList() const { servers: serverList, loadServers } = useServerList()
// ── State ── const viewModeOptions = [
{ title: '命令视图', value: 'commands' as const },
{ title: '会话视图', value: 'sessions' as const },
{ title: '推送日志', value: 'push' as const },
]
const pushStatusOptions = [
{ label: '成功', value: 'success' },
{ label: '失败', value: 'failed' },
{ label: '进行中', value: 'running' },
{ label: '已取消', value: 'cancelled' },
]
const pushSyncModeOptions = [
{ label: '增量', value: 'incremental' },
{ label: '全量', value: 'full' },
{ label: '覆盖', value: 'overwrite' },
{ label: '校验和', value: 'checksum' },
]
const pushTriggerOptions = [
{ label: '手动', value: 'manual' },
{ label: '调度', value: 'schedule' },
{ label: '重试', value: 'retry' },
{ label: '批量', value: 'batch' },
]
const loading = ref(false) const loading = ref(false)
const viewMode = ref<'commands' | 'sessions'>('commands') const viewMode = ref<ViewMode>('commands')
const page = ref(1) const page = ref(1)
const total = ref(0) const total = ref(0)
const itemsPerPage = ref(30) const itemsPerPage = ref(30)
const serverFilter = ref<number | null>(null) const serverFilter = ref<number | null>(null)
const pushStatusFilter = ref<string | null>(null)
const pushSyncModeFilter = ref<string | null>(null)
const pushTriggerFilter = ref<string | null>(null)
const commands = ref<CommandLogItem[]>([]) const commands = ref<CommandLogItem[]>([])
const sessions = ref<SshSessionItem[]>([]) const sessions = ref<SshSessionItem[]>([])
const pushLogs = ref<PushItem[]>([])
const commandHeaders = [ const commandHeaders = [
{ title: '命令', key: 'command' }, { title: '命令', key: 'command' },
@@ -131,7 +259,59 @@ const sessionHeaders = [
{ title: '开始时间', key: 'started_at', width: 160 }, { title: '开始时间', key: 'started_at', width: 160 },
] ]
// ── Data loading ── const pushHeaders = [
{ title: '时间', key: 'started_at', width: 160 },
{ title: '服务器', key: 'server_name', width: 120 },
{ title: '状态', key: 'status', width: 88 },
{ title: '模式', key: 'sync_mode', width: 80 },
{ title: '触发', key: 'trigger_type', width: 72 },
{ title: '源路径', key: 'source_path' },
{ title: '目标路径', key: 'target_path' },
{ title: '错误', key: 'error_message', width: 180 },
]
function pushStatusColor(status: string): string {
switch (status) {
case 'success': return 'success'
case 'failed': return 'error'
case 'running': return 'warning'
case 'cancelled': return 'grey'
default: return 'default'
}
}
function pushStatusLabel(status: string): string {
return pushStatusOptions.find((o) => o.value === status)?.label || status
}
function syncModeLabel(mode?: string): string {
return pushSyncModeOptions.find((o) => o.value === mode)?.label || mode || '—'
}
function triggerLabel(trigger?: string): string {
return pushTriggerOptions.find((o) => o.value === trigger)?.label || trigger || '—'
}
function onViewModeChange() {
page.value = 1
loadData()
}
function onServerFilterChange() {
page.value = 1
loadData()
}
function onPushFilterChange() {
page.value = 1
loadData()
}
function onPageChange(p: number) {
page.value = p
loadData()
}
async function loadData() { async function loadData() {
loading.value = true loading.value = true
try { try {
@@ -143,7 +323,7 @@ async function loadData() {
}) })
commands.value = res.items commands.value = res.items
total.value = res.total total.value = res.total
} else { } else if (viewMode.value === 'sessions') {
const res = await http.getList<SshSessionItem>('/assets/ssh-sessions', { const res = await http.getList<SshSessionItem>('/assets/ssh-sessions', {
server_id: serverFilter.value || undefined, server_id: serverFilter.value || undefined,
page: page.value, page: page.value,
@@ -151,11 +331,25 @@ async function loadData() {
}) })
sessions.value = res.items sessions.value = res.items
total.value = res.total total.value = res.total
} else {
const params: Record<string, string | number> = {
page: page.value,
per_page: itemsPerPage.value,
}
if (serverFilter.value != null) params.server_id = serverFilter.value
if (pushStatusFilter.value) params.status = pushStatusFilter.value
if (pushSyncModeFilter.value) params.sync_mode = pushSyncModeFilter.value
if (pushTriggerFilter.value) params.trigger_type = pushTriggerFilter.value
const res = await http.get<{ items: PushItem[]; total: number }>('/servers/logs', params)
pushLogs.value = res.items || []
total.value = res.total || 0
} }
} catch (e: unknown) { } catch (e: unknown) {
commands.value = [] commands.value = []
sessions.value = [] sessions.value = []
snackbar(formatApiError(e, '加载命令日志失败'), 'error') pushLogs.value = []
total.value = 0
snackbar(formatApiError(e, '加载失败'), 'error')
} finally { } finally {
loading.value = false loading.value = false
} }
+2 -1
View File
@@ -398,8 +398,9 @@
<v-card-title>导入服务器</v-card-title> <v-card-title>导入服务器</v-card-title>
<v-card-text> <v-card-text>
<div class="text-body-2 text-medium-emphasis mb-3"> <div class="text-body-2 text-medium-emphasis mb-3">
上传 CSV 文件批量导入服务器 上传 CSV 文件批量导入服务器名称地址必填SSH端口用户名认证方式密码目标路径等可选
<a href="/app/servers_import_template.csv" download class="text-primary">下载模板</a> <a href="/app/servers_import_template.csv" download class="text-primary">下载模板</a>
<span class="text-caption text-medium-emphasis">亦可登录后访问 API <code>/api/servers/import/template</code></span>
</div> </div>
<v-file-input v-model="importFile" label="选择 CSV 文件" variant="outlined" density="compact" accept=".csv" show-size /> <v-file-input v-model="importFile" label="选择 CSV 文件" variant="outlined" density="compact" accept=".csv" show-size />
<v-alert v-if="importResult" :type="importResult.failed > 0 ? 'warning' : 'success'" density="compact" variant="tonal" class="mt-3"> <v-alert v-if="importResult" :type="importResult.failed > 0 ? 'warning' : 'success'" density="compact" variant="tonal" class="mt-3">
+3 -3
View File
@@ -22,12 +22,12 @@ FEATURES: tuple[FeatureSpec, ...] = (
FeatureSpec("infra_app", "前端静态 /app/", "infra", "SPA 入口可访问", ("/app/", "static")), FeatureSpec("infra_app", "前端静态 /app/", "infra", "SPA 入口可访问", ("/app/", "static")),
FeatureSpec("auth", "认证与 JWT", "api", "登录、me、刷新", ("/api/auth/", "Auth")), FeatureSpec("auth", "认证与 JWT", "api", "登录、me、刷新", ("/api/auth/", "Auth")),
FeatureSpec("dashboard", "仪表盘统计", "api", "服务器统计与概览", ("/api/servers/stats", "stats")), FeatureSpec("dashboard", "仪表盘统计", "api", "服务器统计与概览", ("/api/servers/stats", "stats")),
FeatureSpec("servers", "服务器管理", "api", "CRUD、分类、日志", ("/api/servers/", "Server")), FeatureSpec("servers", "服务器管理", "api", "CRUD、分类、日志、CSV 导入", ("/api/servers/", "Server", "import")),
FeatureSpec("files", "文件管理", "api", "browse、files-capability", ("browse", "files-capability", "sync/")), FeatureSpec("files", "文件管理", "api", "browse、files-capability", ("browse", "files-capability", "sync/")),
FeatureSpec("terminal", "Web 终端", "api", "快捷命令、webssh-token", ("terminal", "webssh", "quick-commands")), FeatureSpec("terminal", "Web 终端", "api", "快捷命令、webssh-token", ("terminal", "webssh", "quick-commands")),
FeatureSpec("push_sync", "推送与同步", "api", "validate-source、sync", ("sync", "validate-source", "Push")), FeatureSpec("push_sync", "推送与同步", "api", "validate-source、sync", ("sync", "validate-source", "Push")),
FeatureSpec("scripts", "脚本库", "api", "脚本 CRUD、执行记录", ("/api/scripts/", "Scripts")), FeatureSpec("scripts", "脚本库", "api", "脚本 CRUD、执行记录", ("/api/scripts/", "Scripts")),
FeatureSpec("schedules", "调度任务", "api", "调度 CRUD", ("/api/schedules/", "Schedules")), FeatureSpec("schedules", "调度任务", "api", "调度 CRUD、target_path、next_run", ("/api/schedules/", "Schedules")),
FeatureSpec("credentials", "凭据预设", "api", "密码/SSH 密钥预设", ("/api/presets/", "ssh-key", "Password")), FeatureSpec("credentials", "凭据预设", "api", "密码/SSH 密钥预设", ("/api/presets/", "ssh-key", "Password")),
FeatureSpec("retries", "重试队列", "api", "失败任务重试列表", ("/api/retries/", "Retry")), FeatureSpec("retries", "重试队列", "api", "失败任务重试列表", ("/api/retries/", "Retry")),
FeatureSpec("audit", "审计日志", "api", "操作审计分页", ("/api/audit/", "Audit")), FeatureSpec("audit", "审计日志", "api", "操作审计分页", ("/api/audit/", "Audit")),
@@ -45,7 +45,7 @@ FEATURES: tuple[FeatureSpec, ...] = (
FeatureSpec("ui_credentials", "页面·凭据", "ui", "路由 /credentials", ("08 credentials",)), FeatureSpec("ui_credentials", "页面·凭据", "ui", "路由 /credentials", ("08 credentials",)),
FeatureSpec("ui_schedules", "页面·调度", "ui", "路由 /schedules", ("09 schedules",)), FeatureSpec("ui_schedules", "页面·调度", "ui", "路由 /schedules", ("09 schedules",)),
FeatureSpec("ui_retries", "页面·重试", "ui", "路由 /retries", ("10 retries",)), FeatureSpec("ui_retries", "页面·重试", "ui", "路由 /retries", ("10 retries",)),
FeatureSpec("ui_commands", "页面·命令日志", "ui", "路由 /commands", ("11 commands",)), FeatureSpec("ui_commands", "页面·命令日志", "ui", "路由 /commands 三视图", ("11 commands", "推送日志")),
FeatureSpec("ui_alerts", "页面·告警", "ui", "路由 /alerts", ("12 alerts",)), FeatureSpec("ui_alerts", "页面·告警", "ui", "路由 /alerts", ("12 alerts",)),
FeatureSpec("ui_audit", "页面·审计", "ui", "路由 /audit", ("13 audit",)), FeatureSpec("ui_audit", "页面·审计", "ui", "路由 /audit", ("13 audit",)),
FeatureSpec("ui_settings", "页面·设置", "ui", "路由 /settings", ("14 settings",)), FeatureSpec("ui_settings", "页面·设置", "ui", "路由 /settings", ("14 settings",)),
+1
View File
@@ -0,0 +1 @@
import{A as e,F as t,N as n,Vr as r,Z as i,Zn as a,ar as o,er as s,gr as c,jr as l,k as u,mr as d,or as f,rr as p,sr as m,tr as h,vr as g,w as _,wr as v,zt as y}from"./index-AmyXDl4i.js";import{o as b,t as x}from"./VContainer-Dqw80qLq.js";import{t as S}from"./VChip-D3vZhJU3.js";import{t as C}from"./VSelect-DZ1vTOq0.js";import{t as w}from"./VDataTableServer-BYd6EHtC.js";import{n as T,t as E}from"./VRow-BOFF76XF.js";import{t as D}from"./VSpacer-e_QpSKFJ.js";var O={class:`font-weight-medium`},k={class:`text-body-2`},A={class:`text-caption text-medium-emphasis`},j=m({__name:`AlertsPage`,setup(m){let j=b(),M=l(!1),N=l([]),P=l(0),F=l(1),I=l(null),L=l(null),R=l([{label:`今日告警`,value:`0`,color:`blue`,icon:`mdi-alert`},{label:`活跃告警`,value:`0`,color:`orange`,icon:`mdi-bell-ring`},{label:`已恢复`,value:`0`,color:`green`,icon:`mdi-check-circle`},{label:`Top 服务器`,value:``,color:`red`,icon:`mdi-server`}]),z=[{label:`CPU`,value:`cpu`},{label:`内存`,value:`memory`},{label:`磁盘`,value:`disk`},{label:`连接`,value:`connection`}],B=[{label:`活跃`,value:`active`},{label:`已恢复`,value:`recovered`}],V=[{title:`类型`,key:`alert_type`,width:100},{title:`服务器`,key:`server_name`},{title:`详情`,key:`value`},{title:`状态`,key:`is_recovery`,width:100},{title:`时间`,key:`created_at`,width:160}];async function H(){try{let e=await y.get(`/alert-history/stats`);R.value[0].value=String(e.today||0),R.value[1].value=String(e.active||0),R.value[2].value=String(e.recovered||0),R.value[3].value=e.top_server||``}catch{j(`加载统计失败`,`error`)}}async function U(){M.value=!0;try{let e=await y.get(`/alert-history/`,{page:F.value,per_page:20,type:I.value||void 0,status:L.value||void 0});N.value=e.items||[],P.value=e.total||0}catch{N.value=[]}finally{M.value=!1}}function W(e){return e===`cpu`||e===`CPU`?`error`:e===`memory`||e===`内存`?`warning`:e===`disk`||e===`磁盘`?`info`:`primary`}function G(e){return e===`cpu`||e===`CPU`?`mdi-chip`:e===`memory`||e===`内存`?`mdi-memory`:e===`disk`||e===`磁盘`?`mdi-harddisk`:`mdi-lan-disconnect`}return d(()=>{H(),U()}),(l,d)=>(c(),h(x,{fluid:``,class:`pa-6`},{default:v(()=>[f(E,{class:`mb-4`},{default:v(()=>[(c(!0),p(a,null,g(R.value,t=>(c(),h(T,{cols:`12`,sm:`6`,lg:`3`,key:t.label},{default:v(()=>[f(_,{elevation:`0`,lines:`two`,rounded:`lg`,border:``},{default:v(()=>[f(u,null,{append:v(()=>[f(i,{color:t.color,size:`30`},{default:v(()=>[o(r(t.icon),1)]),_:2},1032,[`color`])]),default:v(()=>[f(e,{class:`text-body-small`},{default:v(()=>[o(r(t.label),1)]),_:2},1024),f(e,null,{default:v(()=>[o(r(t.value),1)]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1}),f(n,{elevation:`0`,border:``,rounded:`lg`},{default:v(()=>[f(t,{class:`d-flex align-center`},{default:v(()=>[d[5]||=o(` 告警历史 `,-1),f(D),f(C,{modelValue:I.value,"onUpdate:modelValue":[d[0]||=e=>I.value=e,d[1]||=e=>{F.value=1,U()}],items:z,"item-title":`label`,"item-value":`value`,label:`类型`,variant:`outlined`,density:`compact`,"hide-details":``,style:{"max-width":`140px`},clearable:``},null,8,[`modelValue`]),f(C,{modelValue:L.value,"onUpdate:modelValue":[d[2]||=e=>L.value=e,d[3]||=e=>{F.value=1,U()}],items:B,"item-title":`label`,"item-value":`value`,label:`状态`,variant:`outlined`,density:`compact`,"hide-details":``,style:{"max-width":`140px`},class:`ml-3`,clearable:``},null,8,[`modelValue`])]),_:1}),f(w,{items:N.value,headers:V,"items-length":P.value,loading:M.value,page:F.value,"items-per-page":20,hover:``,density:`comfortable`,"onUpdate:page":d[4]||=e=>{F.value=e,U()}},{"item.alert_type":v(({item:e})=>[f(S,{color:W(e.alert_type),size:`small`,variant:`tonal`,label:``},{prepend:v(()=>[f(i,{size:`12`},{default:v(()=>[o(r(G(e.alert_type)),1)]),_:2},1024)]),default:v(()=>[o(` `+r(e.alert_type),1)]),_:2},1032,[`color`])]),"item.server_name":v(({item:e})=>[s(`span`,O,r(e.server_name),1)]),"item.value":v(({item:e})=>[s(`span`,k,r(e.value),1)]),"item.is_recovery":v(({item:e})=>[e.is_recovery?(c(),h(S,{key:0,color:`success`,size:`small`,variant:`tonal`,label:``},{default:v(()=>[...d[6]||=[o(`已恢复`,-1)]]),_:1})):(c(),h(S,{key:1,color:`error`,size:`small`,variant:`tonal`,label:``},{default:v(()=>[...d[7]||=[o(`告警中`,-1)]]),_:1}))]),"item.created_at":v(({item:e})=>[s(`span`,A,r(e.created_at),1)]),"no-data":v(()=>[...d[8]||=[s(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无数据`,-1)]]),_:1},8,[`items`,`items-length`,`loading`,`page`])]),_:1})]),_:1}))}});export{j as default};
+1
View File
@@ -0,0 +1 @@
import{F as e,Lr as t,N as n,Vr as r,ar as i,er as a,gr as o,jr as s,mr as c,or as l,sr as u,t as d,tr as f,wr as p,zt as m}from"./index-AmyXDl4i.js";import{o as h,t as g}from"./VContainer-Dqw80qLq.js";import{t as _}from"./VChip-D3vZhJU3.js";import{t as v}from"./VSelect-DZ1vTOq0.js";import{t as y}from"./VDataTableServer-BYd6EHtC.js";import{t as b}from"./VSpacer-e_QpSKFJ.js";import{a as x,n as S,r as C,t as w}from"./auditNormalize-bmSA0RyN.js";var T={class:`font-weight-medium`},E={class:`text-body-2`},D={class:`text-body-2 text-medium-emphasis text-truncate`,style:{"max-width":`300px`,display:`inline-block`}},O={class:`text-caption text-medium-emphasis`},k={class:`text-caption text-medium-emphasis`},A=u({__name:`AuditPage`,setup(u){let A=h(),j=s(!1),M=s([]),N=s(0),P=s(1),F=s(null),I=s(``),L=s(``),R=S,z=[{title:`操作`,key:`action`,width:100},{title:`用户`,key:`admin_username`,width:100},{title:`目标`,key:`target`,width:140},{title:`详情`,key:`detail`},{title:`IP`,key:`ip_address`,width:120},{title:`时间`,key:`created_at`,width:160}];async function B(){j.value=!0;try{let e=(P.value-1)*50,t=await m.get(`/audit/`,{limit:50,offset:e,action:F.value||void 0,admin_username:I.value||void 0,date_from:L.value||void 0});M.value=w(t.items||[]),N.value=t.total||0}catch{M.value=[],A(`加载审计日志失败`,`error`)}finally{j.value=!1}}function V(e){return e.startsWith(`create`)||e===`login`?`success`:e.startsWith(`update`)?`info`:e.startsWith(`delete`)||e===`logout`?`error`:e.includes(`execute`)||e.includes(`push`)||e.includes(`retry`)?`warning`:`primary`}return c(()=>B()),(s,c)=>(o(),f(g,{fluid:``,class:`pa-6`},{default:p(()=>[l(n,{elevation:`0`,border:``,rounded:`lg`},{default:p(()=>[l(e,{class:`d-flex align-center`},{default:p(()=>[c[7]||=i(` 审计日志 `,-1),l(b),l(v,{modelValue:F.value,"onUpdate:modelValue":[c[0]||=e=>F.value=e,c[1]||=e=>{P.value=1,B()}],items:t(R),"item-title":`label`,"item-value":`value`,label:`操作类型`,variant:`outlined`,density:`compact`,"hide-details":``,style:{"max-width":`200px`},clearable:``},null,8,[`modelValue`,`items`]),l(d,{modelValue:I.value,"onUpdate:modelValue":[c[2]||=e=>I.value=e,c[3]||=e=>{P.value=1,B()}],"prepend-inner-icon":`mdi-account`,label:`用户`,variant:`outlined`,density:`compact`,"hide-details":``,style:{"max-width":`140px`},class:`ml-3`,clearable:``},null,8,[`modelValue`]),l(d,{modelValue:L.value,"onUpdate:modelValue":[c[4]||=e=>L.value=e,c[5]||=e=>{P.value=1,B()}],"prepend-inner-icon":`mdi-calendar`,label:`日期`,variant:`outlined`,density:`compact`,"hide-details":``,style:{"max-width":`160px`},class:`ml-3`,type:`date`,clearable:``},null,8,[`modelValue`])]),_:1}),l(y,{items:M.value,headers:z,"items-length":N.value,loading:j.value,page:P.value,"items-per-page":50,hover:``,density:`compact`,"onUpdate:page":c[6]||=e=>{P.value=e,B()}},{"item.action":p(({item:e})=>[l(_,{color:V(e.action),size:`small`,variant:`tonal`,label:``},{default:p(()=>[i(r(t(C)(e.action)),1)]),_:2},1032,[`color`])]),"item.admin_username":p(({item:e})=>[a(`span`,T,r(e.admin_username),1)]),"item.target":p(({item:e})=>[a(`span`,E,r(t(x)(e.resource_type))+r(e.resource_id?` #${e.resource_id}`:``),1)]),"item.detail":p(({item:e})=>[a(`span`,D,r(e.detail||``),1)]),"item.ip_address":p(({item:e})=>[a(`span`,O,r(e.ip_address||``),1)]),"item.created_at":p(({item:e})=>[a(`span`,k,r(e.created_at),1)]),"no-data":p(()=>[...c[8]||=[a(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无数据`,-1)]]),_:1},8,[`items`,`items-length`,`loading`,`page`])]),_:1})]),_:1}))}});export{A as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{$n as e,Br as t,Ft as n,Ht as r,It as i,Lt as a,N as o,Sr as s,Ut as c,Vr as l,Xn as u,ar as d,c as f,er as p,fn as m,gr as h,hr as g,jr as _,l as v,ln as y,mr as b,nr as x,or as S,pn as C,rn as w,rr as T,sr as E,t as D,tr as O,v as k,wr as A,z as j,zr as M,zt as N}from"./index-AmyXDl4i.js";import{t as P}from"./VChip-D3vZhJU3.js";import{t as F}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as I}from"./VAlert-ChpnVvRE.js";var L=C({...m(),...v()},`VForm`),R=y()({name:`VForm`,props:L(),emits:{"update:modelValue":e=>!0,submit:e=>!0},setup(e,{slots:n,emit:r}){let i=f(e),a=_();function o(e){e.preventDefault(),i.reset()}function s(e){let t=e,n=i.validate();t.then=n.then.bind(n),t.catch=n.catch.bind(n),t.finally=n.finally.bind(n),r(`submit`,t),t.defaultPrevented||n.then(({valid:e})=>{e&&a.value?.submit()}),t.preventDefault()}return w(()=>p(`form`,{ref:a,class:M([`v-form`,e.class]),style:t(e.style),novalidate:!0,onReset:o,onSubmit:s},[n.default?.({get errors(){return i.errors.value},get isDisabled(){return i.isDisabled.value},get isReadonly(){return i.isReadonly.value},get isValidating(){return i.isValidating.value},get isValid(){return i.isValid.value},get items(){return i.items.value},validate:i.validate,reset:i.reset,resetValidation:i.resetValidation})])),k(i,a)}}),z={class:`login-page`},B={class:`login-center`},V={key:2,class:`text-center mt-4`},H=F(E({__name:`LoginPage`,setup(f){let m=r(),v=c(),y=n(),C=_(``),w=_(``),E=_(``),k=_(!1),M=_(!1),F=_(``),L=_(!1),H=_(0),U=_(null),W=_([]),G=_(0),K=null,q=e(()=>W.value.length===0?``:W.value[G.value]);async function J(){try{let e=await N.get(`/settings/bing-wallpapers`);e?.urls?.length&&(W.value=e.urls,G.value=Math.floor(Math.random()*e.urls.length))}catch{}}function Y(){K&&clearInterval(K),!(W.value.length<=1)&&(K=setInterval(()=>{G.value=(G.value+1)%W.value.length},36e5))}b(async()=>{await J(),Y()}),g(()=>{K&&clearInterval(K),Z&&clearInterval(Z)});let X=_(Date.now()),Z=null,Q=e(()=>{if(!U.value)return 0;let e=new Date(U.value).getTime()-X.value;return Math.max(0,Math.ceil(e/6e4))});s(U,e=>{Z&&=(clearInterval(Z),null),e&&(Z=setInterval(()=>{X.value=Date.now()},3e4))});async function $(){if(!C.value||!w.value){F.value=`请输入用户名和密码`;return}M.value=!0,F.value=``;try{await y.login(C.value,w.value,L.value?E.value:void 0);let e=m.query.redirect||`/`,t=e.startsWith(`/`)&&!e.startsWith(`//`)?e:`/`;v.push(t)}catch(e){e instanceof a?(L.value=!0,F.value=e.message):e instanceof i?e.status===429?(U.value=new Date(Date.now()+900*1e3).toISOString(),F.value=`登录尝试过多,账户已锁定 15 分钟`):(H.value++,F.value=e.message):F.value=`网络错误,请重试`}finally{M.value=!1}}return(e,n)=>(h(),T(`div`,z,[p(`div`,{class:`wallpaper-bg`,style:t({backgroundImage:`url(${q.value})`})},null,4),n[6]||=p(`div`,{class:`wallpaper-overlay`},null,-1),p(`div`,B,[S(o,{elevation:`0`,rounded:`xl`,class:`login-card pa-10`,border:``},{default:A(()=>[F.value?(h(),O(I,{key:0,type:`error`,density:`compact`,class:`mb-4`,closable:``,"onClick:close":n[0]||=e=>F.value=``,rounded:`lg`,variant:`tonal`},{default:A(()=>[d(l(F.value),1)]),_:1})):x(``,!0),U.value?(h(),O(I,{key:1,type:`warning`,density:`compact`,class:`mb-4`,rounded:`lg`,variant:`tonal`},{default:A(()=>[d(` 账户已锁定,请 `+l(Q.value)+` 分钟后重试 `,1)]),_:1})):x(``,!0),S(R,{onSubmit:u($,[`prevent`])},{default:A(()=>[S(D,{modelValue:C.value,"onUpdate:modelValue":n[1]||=e=>C.value=e,label:`用户名`,variant:`outlined`,density:`comfortable`,"prepend-inner-icon":`mdi-account-outline`,disabled:M.value,class:`mb-4`,autocomplete:`username`,rounded:`lg`,"hide-details":`auto`},null,8,[`modelValue`,`disabled`]),S(D,{modelValue:w.value,"onUpdate:modelValue":n[2]||=e=>w.value=e,label:`密码`,variant:`outlined`,density:`comfortable`,"prepend-inner-icon":`mdi-lock-outline`,"append-inner-icon":k.value?`mdi-eye`:`mdi-eye-off`,type:k.value?`text`:`password`,"onClick:appendInner":n[3]||=e=>k.value=!k.value,disabled:M.value,class:`mb-4`,autocomplete:`current-password`,rounded:`lg`,"hide-details":`auto`},null,8,[`modelValue`,`append-inner-icon`,`type`,`disabled`]),L.value?(h(),O(D,{key:0,modelValue:E.value,"onUpdate:modelValue":n[4]||=e=>E.value=e,label:`TOTP 验证码`,variant:`outlined`,density:`comfortable`,"prepend-inner-icon":`mdi-shield-key-outline`,disabled:M.value,class:`mb-4`,autocomplete:`one-time-code`,rounded:`lg`,"hide-details":`auto`},null,8,[`modelValue`,`disabled`])):x(``,!0),S(j,{type:`submit`,color:`primary`,variant:`flat`,block:``,size:`large`,loading:M.value,disabled:!!U.value,rounded:`lg`,class:`mt-2`,height:`48`},{default:A(()=>[...n[5]||=[d(` 登录 `,-1)]]),_:1},8,[`loading`,`disabled`])]),_:1}),H.value>0&&!U.value?(h(),T(`div`,V,[S(P,{size:`small`,variant:`tonal`,color:`warning`,label:``},{default:A(()=>[d(` 已失败 `+l(H.value)+``,1)]),_:1})])):x(``,!0)]),_:1})])]))}}),[[`__scopeId`,`data-v-c0c6156f`]]);export{H as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{F as e,L as t,N as n,P as r,Vr as i,ar as a,er as o,gr as s,jr as c,mr as l,nr as u,or as d,sr as f,tr as p,wr as m,z as h,zt as g}from"./index-AmyXDl4i.js";import{o as _,t as v}from"./VContainer-Dqw80qLq.js";import{t as y}from"./VChip-D3vZhJU3.js";import{t as b}from"./VSelect-DZ1vTOq0.js";import{t as x}from"./VDataTableServer-BYd6EHtC.js";import{t as S}from"./VSpacer-e_QpSKFJ.js";import{t as C}from"./VDialog-hWg6_Knl.js";var w={class:`font-weight-medium text-truncate d-inline-block`,style:{"max-width":`240px`}},T={class:`text-medium-emphasis`},E={class:`text-medium-emphasis`},D={class:`text-caption text-medium-emphasis`},O={class:`text-caption text-medium-emphasis`},k=f({__name:`RetriesPage`,setup(f){let k=_(),A=c(!1),j=c([]),M=c(0),N=c(1),P=c(null),F=c(!1),I=c(null),L=[{label:`待重试`,value:`pending`},{label:`重试中`,value:`retrying`},{label:`成功`,value:`success`},{label:`失败`,value:`failed`}],R=[{title:`状态`,key:`status`,width:100},{title:`任务`,key:`operation`},{title:`服务器`,key:`server_name`},{title:`次数`,key:`retry_count`,width:100},{title:`下次重试`,key:`next_retry_at`,width:140},{title:`创建时间`,key:`created_at`,width:160},{title:``,key:`actions`,width:120,align:`end`,sortable:!1}];async function z(){A.value=!0;try{let e=(await g.getList(`/retries/`,{limit:200})).items||[];P.value&&(e=e.filter(e=>e.status===P.value)),M.value=e.length;let t=(N.value-1)*20;j.value=e.slice(t,t+20)}catch(e){j.value=[],M.value=0,k(e instanceof Error?e.message:`加载重试队列失败`,`error`)}finally{A.value=!1}}async function B(e){try{await g.post(`/retries/${e.id}/retry`),z(),k(`重试已触发`)}catch(e){k(e.message||`操作失败`,`error`)}}function V(e){I.value=e.id,F.value=!0}async function H(){if(I.value)try{await g.delete(`/retries/${I.value}`),F.value=!1,z(),k(`已删除`)}catch(e){k(e.message||`删除失败`,`error`)}}function U(e){return e===`success`?`success`:e===`failed`?`error`:e===`retrying`?`warning`:`info`}function W(e){return e===`pending`?`待重试`:e===`retrying`?`重试中`:e===`success`?`成功`:e===`failed`?`失败`:e}function G(e){return e.source_path&&e.target_path?`${e.source_path}${e.target_path}`:e.source_path||e.target_path||`文件推送`}return l(()=>z()),(c,l)=>(s(),p(v,{fluid:``,class:`pa-6`},{default:m(()=>[d(n,{elevation:`0`,border:``,rounded:`lg`},{default:m(()=>[d(e,{class:`d-flex align-center text-h6`},{default:m(()=>[l[5]||=a(` 重试队列 `,-1),d(S),d(b,{modelValue:P.value,"onUpdate:modelValue":[l[0]||=e=>P.value=e,l[1]||=e=>{N.value=1,z()}],items:L,"item-title":`label`,"item-value":`value`,label:`状态筛选`,variant:`outlined`,density:`compact`,"hide-details":``,style:{"max-width":`160px`},clearable:``},null,8,[`modelValue`])]),_:1}),d(x,{items:j.value,headers:R,"items-length":M.value,loading:A.value,page:N.value,"items-per-page":20,hover:``,density:`comfortable`,"onUpdate:page":l[2]||=e=>{N.value=e,z()}},{"item.status":m(({item:e})=>[d(y,{color:U(e.status),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:m(()=>[a(i(W(e.status)),1)]),_:2},1032,[`color`])]),"item.operation":m(({item:e})=>[o(`span`,w,i(G(e)),1)]),"item.server_name":m(({item:e})=>[o(`span`,T,i(e.server_name||``),1)]),"item.retry_count":m(({item:e})=>[o(`span`,E,i(e.retry_count||0)+` / `+i(e.max_retries||3),1)]),"item.next_retry_at":m(({item:e})=>[o(`span`,D,i(e.next_retry_at||``),1)]),"item.created_at":m(({item:e})=>[o(`span`,O,i(e.created_at),1)]),"item.actions":m(({item:e})=>[e.status===`pending`||e.status===`failed`?(s(),p(h,{key:0,variant:`text`,size:`x-small`,color:`primary`,density:`compact`,onClick:t=>B(e)},{default:m(()=>[...l[6]||=[a(` 重试 `,-1)]]),_:1},8,[`onClick`])):u(``,!0),d(h,{variant:`text`,size:`x-small`,color:`error`,density:`compact`,onClick:t=>V(e)},{default:m(()=>[...l[7]||=[a(` 删除 `,-1)]]),_:1},8,[`onClick`])]),"no-data":m(()=>[...l[8]||=[o(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无数据`,-1)]]),_:1},8,[`items`,`items-length`,`loading`,`page`])]),_:1}),d(C,{modelValue:F.value,"onUpdate:modelValue":l[4]||=e=>F.value=e,"max-width":`400`},{default:m(()=>[d(n,{border:``},{default:m(()=>[d(e,null,{default:m(()=>[...l[9]||=[a(`确认删除`,-1)]]),_:1}),d(r,null,{default:m(()=>[...l[10]||=[a(`确定要删除此重试任务吗?`,-1)]]),_:1}),d(t,null,{default:m(()=>[d(S),d(h,{variant:`text`,onClick:l[3]||=e=>F.value=!1},{default:m(()=>[...l[11]||=[a(`取消`,-1)]]),_:1}),d(h,{color:`error`,variant:`flat`,onClick:H},{default:m(()=>[...l[12]||=[a(`删除`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`])]),_:1}))}});export{k as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{N as e,P as t,R as n,Vr as r,Z as i,Zn as a,er as o,gr as s,hr as c,jr as l,or as u,rr as d,sr as f,tr as p,vr as m,wr as h,zr as g,zt as _}from"./index-AmyXDl4i.js";import{n as v,t as y}from"./VRow-BOFF76XF.js";import{t as b}from"./_plugin-vue_export-helper-BDNMzG2s.js";function x(){let e=l([]),t=l(!1),n=l(1),r=l(20),i=l(0),a=l(``);async function o(){t.value=!0;try{let t=await _.get(`/servers/`,{page:n.value,per_page:r.value,search:a.value||void 0});e.value=t.items||[],i.value=t.total||0}catch(t){throw e.value=[],i.value=0,t}finally{t.value=!1}}let s;c(()=>clearTimeout(s));function u(){clearTimeout(s),s=setTimeout(()=>{n.value=1,o()},300)}function d(e){n.value=e,o()}function f(e){r.value=e,n.value=1,o()}return{servers:e,loading:t,page:n,itemsPerPage:r,total:i,search:a,loadServers:o,onSearch:u,onPageChange:d,onItemsPerPageChange:f}}function S(e){switch(e){case`online`:return`success`;case`offline`:return`error`;default:return`warning`}}function C(e){switch(e){case`online`:return`在线`;case`offline`:return`离线`;default:return`未知`}}function w(e){if(!e)return``;let t=new Date(e);if(isNaN(t.getTime()))return``;let n=Date.now()-t.getTime();return n<6e4?`刚刚`:n<36e5?`${Math.floor(n/6e4)} 分钟前`:n<864e5?`${Math.floor(n/36e5)} 小时前`:`${Math.floor(n/864e5)} 天前`}var T={class:`text-caption text-medium-emphasis mb-1`,style:{"font-size":`14px`,"letter-spacing":`0.5px`,"text-transform":`uppercase`}},E=b(f({__name:`StatCardsRow`,props:{items:{}},setup(c){return(l,f)=>(s(),p(y,null,{default:h(()=>[(s(!0),d(a,null,m(c.items,(a,c)=>(s(),p(v,{key:c,cols:`6`,sm:`3`},{default:h(()=>[u(e,{elevation:`0`,rounded:`xl`,border:``,class:`stat-card`},{default:h(()=>[u(t,{class:`pa-4 d-flex align-center justify-space-between`},{default:h(()=>[o(`div`,null,[o(`div`,T,r(a.subtitle),1),o(`div`,{class:g([`font-weight-bold`,`text-`+a.color]),style:{"font-size":`36px`,"line-height":`1.1`}},r(a.title),3)]),u(n,{color:a.color,size:`48`,rounded:`lg`,class:`stat-icon`},{default:h(()=>[u(i,{icon:a.icon,size:`24`,color:`white`},null,8,[`icon`])]),_:2},1032,[`color`])]),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1}))}}),[[`__scopeId`,`data-v-68b984da`]]);export{x as a,C as i,w as n,S as r,E as t};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{$n as e,Br as t,Ct as n,Et as r,G as i,Gt as a,Kt as o,Mt as s,Pr as c,Qt as l,Tt as u,W as d,Z as f,at as p,bt as m,ct as h,dt as g,en as _,er as v,fn as y,ft as b,ln as x,lt as S,mt as C,nn as w,or as T,ot as E,pn as D,pt as O,sn as k,st as A,ur as j,wt as M,xt as N,z as P,zr as F}from"./index-AmyXDl4i.js";var I=k(`v-alert-title`),L=D({iconSize:[Number,String],iconSizes:{type:Array,default:()=>[[`x-small`,10],[`small`,16],[`default`,24],[`large`,28],[`x-large`,32]]}},`iconSize`);function R(t,n){return{iconSize:e(()=>{let e=new Map(t.iconSizes),r=t.iconSize??n()??`default`;return e.has(r)?e.get(r):r})}}var z=[`success`,`info`,`warning`,`error`],B=D({border:{type:[Boolean,String],validator:e=>typeof e==`boolean`||[`top`,`end`,`bottom`,`start`].includes(e)},borderColor:String,closable:Boolean,closeIcon:{type:w,default:`$close`},closeLabel:{type:String,default:`$vuetify.close`},icon:{type:[Boolean,String,Function,Object],default:null},modelValue:{type:Boolean,default:!0},prominent:Boolean,title:String,text:String,type:{type:String,validator:e=>z.includes(e)},...y(),...h(),...M(),...O(),...L(),...g(),...d(),...m(),...s(),...a(),...E({variant:`flat`})},`VAlert`),V=x()({name:`VAlert`,props:B(),emits:{"click:close":e=>!0,"update:modelValue":e=>!0},setup(e,{emit:a,slots:s}){let d=_(e,`modelValue`),m=c(()=>{if(e.icon!==!1)return e.type?e.icon??`$${e.type}`:e.icon}),{iconSize:h}=R(e,()=>e.prominent?44:void 0),{themeClasses:g}=o(e),{colorClasses:y,colorStyles:x,variantClasses:w}=A(()=>({color:e.color??e.type,variant:e.variant})),{densityClasses:E}=S(e),{dimensionStyles:D}=u(e),{elevationClasses:O}=C(e),{locationStyles:k}=b(e),{positionClasses:M}=i(e),{roundedClasses:L}=N(e),{textColorClasses:z,textColorStyles:B}=n(()=>e.borderColor),{t:V}=l(),H=c(()=>({"aria-label":V(e.closeLabel),onClick(e){d.value=!1,a(`click:close`,e)}}));return()=>{let n=!!(s.prepend||m.value),i=!!(s.title||e.title),a=!!(s.close||e.closable),o={density:e.density,icon:m.value,size:e.iconSize||e.prominent?h.value:void 0};return d.value&&T(e.tag,{class:F([`v-alert`,e.border&&{"v-alert--border":!!e.border,[`v-alert--border-${e.border===!0?`start`:e.border}`]:!0},{"v-alert--prominent":e.prominent},g.value,y.value,E.value,O.value,M.value,L.value,w.value,e.class]),style:t([x.value,D.value,k.value,e.style]),role:`alert`},{default:()=>[p(!1,`v-alert`),e.border&&v(`div`,{key:`border`,class:F([`v-alert__border`,z.value]),style:t(B.value)},null),n&&v(`div`,{key:`prepend`,class:`v-alert__prepend`},[s.prepend?T(r,{key:`prepend-defaults`,disabled:!m.value,defaults:{VIcon:{...o}}},s.prepend):T(f,j({key:`prepend-icon`},o),null)]),v(`div`,{class:`v-alert__content`},[i&&T(I,{key:`title`},{default:()=>[s.title?.()??e.title]}),s.text?.()??e.text,s.default?.()]),s.append&&v(`div`,{key:`append`,class:`v-alert__append`},[s.append()]),a&&v(`div`,{key:`close`,class:`v-alert__close`},[s.close?T(r,{key:`close-defaults`,defaults:{VBtn:{icon:e.closeIcon,size:`x-small`,variant:`text`}}},{default:()=>[s.close?.({props:H.value})]}):T(P,j({key:`close-btn`,icon:e.closeIcon,size:`x-small`,variant:`text`},H.value),null)])]})}}});export{V as t};
+1
View File
@@ -0,0 +1 @@
import{Tn as e,en as t,jr as n,ln as r,o as i,or as a,p as o,pn as s,rn as c,s as l,ur as u,v as d,xr as f,zn as p}from"./index-AmyXDl4i.js";import{f as m,p as h}from"./VSelect-DZ1vTOq0.js";var g=s({...p(l(),[`direction`]),...p(h(),[`inline`])},`VCheckbox`),_=r()({name:`VCheckbox`,inheritAttrs:!1,props:g(),emits:{"update:modelValue":e=>!0,"update:focused":e=>!0},setup(r,{attrs:s,slots:l}){let p=t(r,`modelValue`),{isFocused:h,focus:g,blur:_}=o(r),v=n(),y=f();return c(()=>{let[t,n]=e(s),o=i.filterProps(r),c=m.filterProps(r);return a(i,u({ref:v,class:[`v-checkbox`,r.class]},t,o,{modelValue:p.value,"onUpdate:modelValue":e=>p.value=e,id:r.id||`checkbox-${y}`,focused:h.value,style:r.style}),{...l,default:({id:e,messagesId:t,isDisabled:r,isReadonly:i,isValid:o})=>a(m,u(c,{id:e.value,"aria-describedby":t.value,disabled:r.value,readonly:i.value},n,{error:o.value===!1,modelValue:p.value,"onUpdate:modelValue":e=>p.value=e,onFocus:g,onBlur:_}),l)})}),d({},v)}});export{_ as t};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
import{_ as e,a as t,b as n,c as r,d as i,f as a,g as o,h as s,i as c,l,m as u,n as d,o as f,p,r as m,s as h,u as ee,v as te,y as g}from"./VDataTable-Dy8TLadm.js";import{$n as _,Fr as v,M as y,Pr as b,Zn as x,_r as S,er as C,ln as w,or as T,pn as E,rn as ne,un as D,ur as O,zn as k}from"./index-AmyXDl4i.js";var A=E({itemsLength:{type:[Number,String],required:!0},...g(),...d(),...e()},`VDataTableServer`),j=w()({name:`VDataTableServer`,props:A(),emits:{"update:modelValue":e=>!0,"update:page":e=>!0,"update:itemsPerPage":e=>!0,"update:sortBy":e=>!0,"update:options":e=>!0,"update:expanded":e=>!0,"update:groupBy":e=>!0},setup(e,{attrs:d,slots:g}){let{groupBy:w}=r(e),{initialSortOrder:E,sortBy:A,multiSort:j,mustSort:M}=a(e),{page:N,itemsPerPage:P}=te(e),{disableSort:F}=v(e),I=_(()=>parseInt(e.itemsLength,10)),{columns:L,headers:R}=s(e,{groupBy:w,showSelect:b(()=>e.showSelect),showExpand:b(()=>e.showExpand)}),{items:z}=c(e,L),{toggleSort:B}=p({initialSortOrder:E,sortBy:A,multiSort:j,mustSort:M,page:N}),{opened:V,isGroupOpen:H,toggleGroup:re,extractRows:U}=l({groupBy:w,sortBy:A,disableSort:F}),{pageCount:W,setItemsPerPage:G,prevPage:K,nextPage:q,setPage:J}=n({page:N,itemsPerPage:P,itemsLength:I}),{flatItems:Y}=ee(z,w,V,()=>!!g[`group-summary`]),{isSelected:X,select:ie,selectAll:ae,toggleSelect:oe,someSelected:se,allSelected:ce}=u(e,{allItems:z,currentPage:z}),{isExpanded:Z,toggleExpand:le}=h(e),Q=_(()=>U(z.value));m({page:N,itemsPerPage:P,sortBy:A,groupBy:w,search:b(()=>e.search)}),S(`v-data-table`,{toggleSort:B,sortBy:A}),D({VDataTableRows:{hideNoData:b(()=>e.hideNoData),noDataText:b(()=>e.noDataText),loading:b(()=>e.loading),loadingText:b(()=>e.loadingText)}});let $=_(()=>({page:N.value,itemsPerPage:P.value,sortBy:A.value,pageCount:W.value,toggleSort:B,setItemsPerPage:G,prevPage:K,nextPage:q,setPage:J,someSelected:se.value,allSelected:ce.value,isSelected:X,select:ie,selectAll:ae,toggleSelect:oe,isExpanded:Z,toggleExpand:le,isGroupOpen:H,toggleGroup:re,items:Q.value.map(e=>e.raw),internalItems:Q.value,groupedItems:Y.value,columns:L.value,headers:R.value}));ne(()=>{let n=o.filterProps(e),r=i.filterProps(k(e,[`multiSort`])),a=f.filterProps(e),s=t.filterProps(e);return T(t,O({class:[`v-data-table`,{"v-data-table--loading":e.loading},e.class],style:e.style},s,{fixedHeader:e.fixedHeader||e.sticky}),{top:()=>g.top?.($.value),default:()=>g.default?g.default($.value):C(x,null,[g.colgroup?.($.value),!e.hideDefaultHeader&&C(`thead`,{key:`thead`,class:`v-data-table__thead`,role:`rowgroup`},[T(i,O(r,{multiSort:!!e.multiSort}),g)]),g.thead?.($.value),!e.hideDefaultBody&&C(`tbody`,{class:`v-data-table__tbody`,role:`rowgroup`},[g[`body.prepend`]?.($.value),g.body?g.body($.value):T(f,O(d,a,{items:Y.value}),g),g[`body.append`]?.($.value)]),g.tbody?.($.value),g.tfoot?.($.value)]),bottom:()=>g.bottom?g.bottom($.value):!e.hideDefaultFooter&&C(x,null,[T(y,null,null),T(o,n,{prepend:g[`footer.prepend`]})])})})}});export{j as t};
+1
View File
@@ -0,0 +1 @@
import{Et as e,Sr as t,b as n,dr as r,en as i,jr as a,jt as o,ln as s,or as c,pn as l,rn as u,ur as d,v as f,x as p,y as m,zn as h}from"./index-AmyXDl4i.js";var g=l({fullscreen:Boolean,scrollable:Boolean,...h(n({captureFocus:!0,origin:`center center`,scrollStrategy:`block`,transition:{component:o},zIndex:2400,retainFocus:!0}),[`disableInitialFocus`])},`VDialog`),_=s()({name:`VDialog`,props:g(),emits:{"update:modelValue":e=>!0,afterEnter:()=>!0,afterLeave:()=>!0},setup(n,{emit:o,slots:s}){let l=i(n,`modelValue`),{scopeId:h}=p(),g=a();function _(){o(`afterEnter`),(n.scrim||n.retainFocus)&&g.value?.contentEl&&!g.value.contentEl.contains(document.activeElement)&&g.value.contentEl.focus({preventScroll:!0})}function v(){o(`afterLeave`)}return t(l,async e=>{e||(await r(),g.value.activatorEl?.focus({preventScroll:!0}))}),u(()=>{let t=m.filterProps(n),r=d({"aria-haspopup":`dialog`},n.activatorProps),i=d({tabindex:-1},n.contentProps);return c(m,d({ref:g,class:[`v-dialog`,{"v-dialog--fullscreen":n.fullscreen,"v-dialog--scrollable":n.scrollable},n.class],style:n.style},t,{modelValue:l.value,"onUpdate:modelValue":e=>l.value=e,"aria-modal":`true`,activatorProps:r,contentProps:i,height:n.fullscreen?void 0:n.height,width:n.fullscreen?void 0:n.width,maxHeight:n.fullscreen?void 0:n.maxHeight,maxWidth:n.fullscreen?void 0:n.maxWidth,role:`dialog`,onAfterEnter:_,onAfterLeave:v},h),{activator:s.activator,default:(...t)=>c(e,{root:`VDialog`},{default:()=>[s.default?.(...t)]})})}),f({},g)}});export{_ as t};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{$n as e,In as t,Kn as n,Mt as r,Rr as i,Yt as a,bn as o,cr as s,ct as c,fn as l,ln as u,pn as d}from"./index-AmyXDl4i.js";var f=a.reduce((e,t)=>(e[t]={type:[Boolean,String,Number],default:!1},e),{}),p=a.reduce((e,t)=>{let n=`offset`+i(t);return e[n]={type:[String,Number],default:null},e},{}),m={col:t(f),offset:t(p),order:[`order`,`orderSm`,`orderMd`,`orderLg`,`orderXl`,`orderXxl`]};function h(e){if(typeof e==`string`&&e.includes(`/`)){let[t,n]=e.split(`/`);return{cols:Number(t),size:Number(n)}}return{cols:e}}function g(e,t,n){if(n==null||n===!1)return{};let{cols:r,size:i}=h(n),a=t.replace(e,``).toLowerCase();return e===`offset`?{className:`v-col--offset-${a}-${r}`,variables:[{[`--v-col-offset-base-${a}`]:i}]}:e===`order`?{className:`order-${a}-${r}`}:{className:r===``||r===!0?`v-col--${a}`:`v-col--cols-${a}-${r}`,variables:[{[`--v-col-size-base-${a}`]:i}]}}var _=[`auto`,`start`,`end`,`center`,`baseline`,`stretch`],v=e=>_.includes(e),y=d({cols:{type:[Boolean,String,Number],default:!1},...f,offset:{type:[String,Number],default:null},...p,order:{type:[String,Number],default:null},orderSm:{type:[String,Number],default:null},orderMd:{type:[String,Number],default:null},orderLg:{type:[String,Number],default:null},orderXl:{type:[String,Number],default:null},orderXxl:{type:[String,Number],default:null},alignSelf:{type:String,default:null,validator:v},...l(),...r()},`VCol`),b=u()({name:`VCol`,props:y(),setup(t,{slots:n}){let r=e(()=>h(t.cols).size),i=e(()=>h(t.offset).size),a=e(()=>{let e=[`v-col`],n=[],r;for(r in m)m[r].forEach(i=>{let a=t[i],{className:o,variables:s}=g(r,i,a);o&&e.push(o),s&&n.push(...s)});let{cols:i}=h(t.cols),{cols:a}=h(t.offset);return e.push({[`v-col--cols-${i}`]:i,[`v-col--offset-${a}`]:a,[`order-${t.order}`]:t.order,[`align-self-${t.alignSelf}`]:t.alignSelf}),{classes:e,variables:n}});return()=>s(t.tag,{class:[a.value.classes,t.class],style:[{"--v-col-size-base":r.value},{"--v-col-offset-base":i.value},a.value.variables,t.style]},n.default?.())}}),x=[`start`,`end`,`center`],S=[`space-between`,`space-around`,`space-evenly`],C=[...x,`baseline`,`stretch`],w=e=>C.includes(e),T=[...x,...S],E=e=>T.includes(e),D=[...x,...S,`stretch`],O=e=>D.includes(e),k={align:[`align`,`alignSm`,`alignMd`,`alignLg`,`alignXl`,`alignXxl`],justify:[`justify`,`justifySm`,`justifyMd`,`justifyLg`,`justifyXl`,`justifyXxl`],alignContent:[`alignContent`,`alignContentSm`,`alignContentMd`,`alignContentLg`,`alignContentXl`,`alignContentXxl`]},A={align:`align`,justify:`justify`,alignContent:`align-content`};function j(e,t,n){let r=A[e];if(n!=null){if(t){let n=t.replace(e,``);r+=`-${n}`}return r+=`-${n}`,r.toLowerCase()}}var M=d({dense:Boolean,align:{type:String,default:null,validator:w},alignSm:{type:String,default:null,validator:w},alignMd:{type:String,default:null,validator:w},alignLg:{type:String,default:null,validator:w},alignXl:{type:String,default:null,validator:w},alignXxl:{type:String,default:null,validator:w},justify:{type:String,default:null,validator:E},justifySm:{type:String,default:null,validator:E},justifyMd:{type:String,default:null,validator:E},justifyLg:{type:String,default:null,validator:E},justifyXl:{type:String,default:null,validator:E},justifyXxl:{type:String,default:null,validator:E},alignContent:{type:String,default:null,validator:O},alignContentSm:{type:String,default:null,validator:O},alignContentMd:{type:String,default:null,validator:O},alignContentLg:{type:String,default:null,validator:O},alignContentXl:{type:String,default:null,validator:O},alignContentXxl:{type:String,default:null,validator:O},noGutters:Boolean,gap:[Number,String,Array],size:[Number,String],...l(),...c(),...r()},`VRow`),N=u()({name:`VRow`,props:M(),setup(t,{slots:r}){t.dense&&n(`dense`,`density="comfortable"`);let i=e(()=>{let e=[],n;for(n in k)k[n].forEach(r=>{let i=t[r],a=j(n,r,i);a&&e.push(a)});return e.push({"v-row--no-gutters":t.noGutters,"v-row--density-default":t.density===`default`&&!t.noGutters&&!t.dense,"v-row--density-compact":t.density===`compact`,"v-row--density-comfortable":t.density===`comfortable`||t.dense,[`align-${t.align}`]:t.align,[`justify-${t.justify}`]:t.justify,[`align-content-${t.alignContent}`]:t.alignContent}),e}),a=e(()=>Array.isArray(t.gap)?o(t.gap[0]||0):o(t.gap)),c=e(()=>Array.isArray(t.gap)?o(t.gap[1]||0):a.value);return()=>s(t.tag,{class:[`v-row`,i.value,t.class],style:[{"--v-col-gap-x":a.value,"--v-col-gap-y":c.value,"--v-row-columns":t.size},t.style]},r.default?.())}});export{b as n,N as t};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{sn as e}from"./index-AmyXDl4i.js";var t=e(`v-spacer`,`div`,`VSpacer`);export{t};
+1
View File
@@ -0,0 +1 @@
import{At as e,Br as t,Et as n,J as r,K as i,Pr as a,Tn as o,Wn as s,X as c,Z as l,Zn as u,en as d,er as f,jr as p,ln as m,o as h,or as g,p as _,pn as v,rn as y,s as b,ur as x,v as S,xr as C,zr as w}from"./index-AmyXDl4i.js";import{n as T,r as E}from"./VContainer-Dqw80qLq.js";var D=v({indeterminate:Boolean,inset:Boolean,flat:Boolean,loading:{type:[Boolean,String],default:!1},...b(),...E()},`VSwitch`),O=m()({name:`VSwitch`,inheritAttrs:!1,props:D(),emits:{"update:focused":e=>!0,"update:modelValue":e=>!0,"update:indeterminate":e=>!0},setup(m,{attrs:v,slots:b}){let E=d(m,`indeterminate`),D=d(m,`modelValue`),{loaderClasses:O}=r(m),{isFocused:k,focus:A,blur:j}=_(m),M=p(),N=p(),P=s&&window.matchMedia(`(forced-colors: active)`).matches,F=a(()=>typeof m.loading==`string`&&m.loading!==``?m.loading:m.color),I=C(),L=a(()=>m.id||`switch-${I}`);function R(){E.value&&=!1}function z(e){e.stopPropagation(),e.preventDefault(),M.value?.input?.click()}return y(()=>{let[r,a]=o(v),s=h.filterProps(m),d=T.filterProps(m);return g(h,x({ref:N,class:[`v-switch`,{"v-switch--flat":m.flat},{"v-switch--inset":m.inset},{"v-switch--indeterminate":E.value},O.value,m.class]},r,s,{modelValue:D.value,"onUpdate:modelValue":e=>D.value=e,id:L.value,focused:k.value,style:m.style}),{...b,default:({id:r,messagesId:o,isDisabled:s,isReadonly:p,isValid:h})=>{let _={model:D,isValid:h};return g(T,x({ref:M},d,{modelValue:D.value,"onUpdate:modelValue":[e=>D.value=e,R],id:r.value,"aria-describedby":o.value,type:`checkbox`,"aria-checked":E.value?`mixed`:void 0,disabled:s.value,readonly:p.value,onFocus:A,onBlur:j},a),{...b,default:({backgroundColorClasses:e,backgroundColorStyles:n})=>f(`div`,{class:w([`v-switch__track`,P?void 0:e.value]),style:t(n.value),onClick:z},[b[`track-true`]&&f(`div`,{key:`prepend`,class:`v-switch__track-true`},[b[`track-true`](_)]),b[`track-false`]&&f(`div`,{key:`append`,class:`v-switch__track-false`},[b[`track-false`](_)])]),input:({inputNode:r,icon:a,backgroundColorClasses:o,backgroundColorStyles:s})=>f(u,null,[r,f(`div`,{class:w([`v-switch__thumb`,{"v-switch__thumb--filled":a||m.loading},m.inset||P?void 0:o.value]),style:t(m.inset?void 0:s.value)},[b.thumb?g(n,{defaults:{VIcon:{icon:a,size:`x-small`}}},{default:()=>[b.thumb({..._,icon:a})]}):g(e,null,{default:()=>[m.loading?g(i,{name:`v-switch`,active:!0,color:h.value===!1?void 0:F.value},{default:e=>b.loader?b.loader(e):g(c,{active:e.isActive,color:e.color,indeterminate:!0,size:`16`,width:`2`},null)}):a&&g(l,{key:String(a),icon:a,size:`x-small`},null)]})])])})}})}),S({},N)}});export{O as t};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{It as e}from"./index-AmyXDl4i.js";function t(t,n){if(t instanceof e){let e=t.detail??t.message;return typeof e==`string`?e:Array.isArray(e)?e.map(e=>e?.msg||JSON.stringify(e)).join(`; `):e&&typeof e==`object`?JSON.stringify(e):t.message||n}return t instanceof Error&&t.message||n}export{t};
+1
View File
@@ -0,0 +1 @@
import{p as e,s as t}from"./initMonaco-x1oyshyc.js";import{_ as n,a as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v,v as y}from"./lspLanguageFeatures-BA8ehupj.js";var b=120*1e3,x=class{constructor(e){this._defaults=e,this._worker=null,this._client=null,this._idleCheckInterval=window.setInterval(()=>this._checkIfIdle(),30*1e3),this._lastUsedTime=0,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker())}_stopWorker(){this._worker&&=(this._worker.dispose(),null),this._client=null}dispose(){clearInterval(this._idleCheckInterval),this._configChangeListener.dispose(),this._stopWorker()}_checkIfIdle(){this._worker&&Date.now()-this._lastUsedTime>b&&this._stopWorker()}_getClient(){return this._lastUsedTime=Date.now(),this._client||=(this._worker=t({moduleId:`vs/language/css/cssWorker`,createWorker:()=>new Worker(new URL(`/app/assets/css.worker-CvXBzhp8.js`,``+import.meta.url),{type:`module`}),label:this._defaults.languageId,createData:{options:this._defaults.options,languageId:this._defaults.languageId}}),this._worker.getProxy()),this._client}getLanguageServiceWorker(...e){let t;return this._getClient().then(e=>{t=e}).then(t=>{if(this._worker)return this._worker.withSyncedResources(e)}).then(e=>t)}};function S(t){let n=[],s=[],c=new x(t);n.push(c);let g=(...e)=>c.getLanguageServiceWorker(...e);function y(){let{languageId:n,modeConfiguration:c}=t;w(s),c.completionItems&&s.push(e.registerCompletionItemProvider(n,new _(g,[`/`,`-`,`:`]))),c.hovers&&s.push(e.registerHoverProvider(n,new a(g))),c.documentHighlights&&s.push(e.registerDocumentHighlightProvider(n,new p(g))),c.definitions&&s.push(e.registerDefinitionProvider(n,new f(g))),c.references&&s.push(e.registerReferenceProvider(n,new o(g))),c.documentSymbols&&s.push(e.registerDocumentSymbolProvider(n,new u(g))),c.rename&&s.push(e.registerRenameProvider(n,new m(g))),c.colors&&s.push(e.registerColorProvider(n,new l(g))),c.foldingRanges&&s.push(e.registerFoldingRangeProvider(n,new v(g))),c.diagnostics&&s.push(new h(n,g,t.onDidChange)),c.selectionRanges&&s.push(e.registerSelectionRangeProvider(n,new d(g))),c.documentFormattingEdits&&s.push(e.registerDocumentFormattingEditProvider(n,new r(g))),c.documentRangeFormattingEdits&&s.push(e.registerDocumentRangeFormattingEditProvider(n,new i(g)))}return y(),n.push(C(s)),C(n)}function C(e){return{dispose:()=>w(e)}}function w(e){for(;e.length;)e.pop().dispose()}export{_ as CompletionAdapter,f as DefinitionAdapter,h as DiagnosticsAdapter,l as DocumentColorAdapter,r as DocumentFormattingEditProvider,p as DocumentHighlightAdapter,g as DocumentLinkAdapter,i as DocumentRangeFormattingEditProvider,u as DocumentSymbolAdapter,v as FoldingRangeAdapter,a as HoverAdapter,o as ReferenceAdapter,m as RenameAdapter,d as SelectionRangeAdapter,x as WorkerManager,c as fromPosition,s as fromRange,S as setupMode,n as toRange,y as toTextEdit};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t=[`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`keygen`,`link`,`menuitem`,`meta`,`param`,`source`,`track`,`wbr`],n={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,comments:{blockComment:[`<!--`,`-->`]},brackets:[[`<!--`,`-->`],[`<`,`>`],[`{`,`}`],[`(`,`)`]],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],surroundingPairs:[{open:`"`,close:`"`},{open:`'`,close:`'`},{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`<`,close:`>`}],onEnterRules:[{beforeText:RegExp(`<(?!(?:${t.join(`|`)}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:e.IndentAction.IndentOutdent}},{beforeText:RegExp(`<(?!(?:${t.join(`|`)}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),action:{indentAction:e.IndentAction.Indent}}],folding:{markers:{start:RegExp(`^\\s*<!--\\s*#region\\b.*-->`),end:RegExp(`^\\s*<!--\\s*#endregion\\b.*-->`)}}},r={defaultToken:``,tokenPostfix:`.html`,ignoreCase:!0,tokenizer:{root:[[/<!DOCTYPE/,`metatag`,`@doctype`],[/<!--/,`comment`,`@comment`],[/(<)((?:[\w\-]+:)?[\w\-]+)(\s*)(\/>)/,[`delimiter`,`tag`,``,`delimiter`]],[/(<)(script)/,[`delimiter`,{token:`tag`,next:`@script`}]],[/(<)(style)/,[`delimiter`,{token:`tag`,next:`@style`}]],[/(<)((?:[\w\-]+:)?[\w\-]+)/,[`delimiter`,{token:`tag`,next:`@otherTag`}]],[/(<\/)((?:[\w\-]+:)?[\w\-]+)/,[`delimiter`,{token:`tag`,next:`@otherTag`}]],[/</,`delimiter`],[/[^<]+/]],doctype:[[/[^>]+/,`metatag.content`],[/>/,`metatag`,`@pop`]],comment:[[/-->/,`comment`,`@pop`],[/[^-]+/,`comment.content`],[/./,`comment.content`]],otherTag:[[/\/?>/,`delimiter`,`@pop`],[/"([^"]*)"/,`attribute.value`],[/'([^']*)'/,`attribute.value`],[/[\w\-]+/,`attribute.name`],[/=/,`delimiter`],[/[ \t\r\n]+/]],script:[[/type/,`attribute.name`,`@scriptAfterType`],[/"([^"]*)"/,`attribute.value`],[/'([^']*)'/,`attribute.value`],[/[\w\-]+/,`attribute.name`],[/=/,`delimiter`],[/>/,{token:`delimiter`,next:`@scriptEmbedded`,nextEmbedded:`text/javascript`}],[/[ \t\r\n]+/],[/(<\/)(script\s*)(>)/,[`delimiter`,`tag`,{token:`delimiter`,next:`@pop`}]]],scriptAfterType:[[/=/,`delimiter`,`@scriptAfterTypeEquals`],[/>/,{token:`delimiter`,next:`@scriptEmbedded`,nextEmbedded:`text/javascript`}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:`@rematch`,next:`@pop`}]],scriptAfterTypeEquals:[[/"module"/,{token:`attribute.value`,switchTo:`@scriptWithCustomType.text/javascript`}],[/'module'/,{token:`attribute.value`,switchTo:`@scriptWithCustomType.text/javascript`}],[/"([^"]*)"/,{token:`attribute.value`,switchTo:`@scriptWithCustomType.$1`}],[/'([^']*)'/,{token:`attribute.value`,switchTo:`@scriptWithCustomType.$1`}],[/>/,{token:`delimiter`,next:`@scriptEmbedded`,nextEmbedded:`text/javascript`}],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:`@rematch`,next:`@pop`}]],scriptWithCustomType:[[/>/,{token:`delimiter`,next:`@scriptEmbedded.$S2`,nextEmbedded:`$S2`}],[/"([^"]*)"/,`attribute.value`],[/'([^']*)'/,`attribute.value`],[/[\w\-]+/,`attribute.name`],[/=/,`delimiter`],[/[ \t\r\n]+/],[/<\/script\s*>/,{token:`@rematch`,next:`@pop`}]],scriptEmbedded:[[/<\/script/,{token:`@rematch`,next:`@pop`,nextEmbedded:`@pop`}],[/[^<]+/,``]],style:[[/type/,`attribute.name`,`@styleAfterType`],[/"([^"]*)"/,`attribute.value`],[/'([^']*)'/,`attribute.value`],[/[\w\-]+/,`attribute.name`],[/=/,`delimiter`],[/>/,{token:`delimiter`,next:`@styleEmbedded`,nextEmbedded:`text/css`}],[/[ \t\r\n]+/],[/(<\/)(style\s*)(>)/,[`delimiter`,`tag`,{token:`delimiter`,next:`@pop`}]]],styleAfterType:[[/=/,`delimiter`,`@styleAfterTypeEquals`],[/>/,{token:`delimiter`,next:`@styleEmbedded`,nextEmbedded:`text/css`}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:`@rematch`,next:`@pop`}]],styleAfterTypeEquals:[[/"([^"]*)"/,{token:`attribute.value`,switchTo:`@styleWithCustomType.$1`}],[/'([^']*)'/,{token:`attribute.value`,switchTo:`@styleWithCustomType.$1`}],[/>/,{token:`delimiter`,next:`@styleEmbedded`,nextEmbedded:`text/css`}],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:`@rematch`,next:`@pop`}]],styleWithCustomType:[[/>/,{token:`delimiter`,next:`@styleEmbedded.$S2`,nextEmbedded:`$S2`}],[/"([^"]*)"/,`attribute.value`],[/'([^']*)'/,`attribute.value`],[/[\w\-]+/,`attribute.name`],[/=/,`delimiter`],[/[ \t\r\n]+/],[/<\/style\s*>/,{token:`@rematch`,next:`@pop`}]],styleEmbedded:[[/<\/style/,{token:`@rematch`,next:`@pop`,nextEmbedded:`@pop`}],[/[^<]+/,``]]}};export{n as conf,r as language};
+1
View File
@@ -0,0 +1 @@
import{p as e,s as t}from"./initMonaco-x1oyshyc.js";import{_ as n,a as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v,v as y}from"./lspLanguageFeatures-BA8ehupj.js";var b=120*1e3,x=class{constructor(e){this._defaults=e,this._worker=null,this._client=null,this._idleCheckInterval=window.setInterval(()=>this._checkIfIdle(),30*1e3),this._lastUsedTime=0,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker())}_stopWorker(){this._worker&&=(this._worker.dispose(),null),this._client=null}dispose(){clearInterval(this._idleCheckInterval),this._configChangeListener.dispose(),this._stopWorker()}_checkIfIdle(){this._worker&&Date.now()-this._lastUsedTime>b&&this._stopWorker()}_getClient(){return this._lastUsedTime=Date.now(),this._client||=(this._worker=t({moduleId:`vs/language/html/htmlWorker`,createWorker:()=>new Worker(new URL(`/app/assets/html.worker-BO6WuOEO.js`,``+import.meta.url),{type:`module`}),createData:{languageSettings:this._defaults.options,languageId:this._defaults.languageId},label:this._defaults.languageId}),this._worker.getProxy()),this._client}getLanguageServiceWorker(...e){let t;return this._getClient().then(e=>{t=e}).then(t=>{if(this._worker)return this._worker.withSyncedResources(e)}).then(e=>t)}},S=class extends _{constructor(e){super(e,[`.`,`:`,`<`,`"`,`=`,`/`])}};function C(t){let n=new x(t),o=(...e)=>n.getLanguageServiceWorker(...e),s=t.languageId;e.registerCompletionItemProvider(s,new S(o)),e.registerHoverProvider(s,new a(o)),e.registerDocumentHighlightProvider(s,new p(o)),e.registerLinkProvider(s,new g(o)),e.registerFoldingRangeProvider(s,new v(o)),e.registerDocumentSymbolProvider(s,new u(o)),e.registerSelectionRangeProvider(s,new d(o)),e.registerRenameProvider(s,new m(o)),s===`html`&&(e.registerDocumentFormattingEditProvider(s,new r(o)),e.registerDocumentRangeFormattingEditProvider(s,new i(o)))}function w(t){let n=[],o=[],s=new x(t);n.push(s);let c=(...e)=>s.getLanguageServiceWorker(...e);function l(){let{languageId:n,modeConfiguration:s}=t;E(o),s.completionItems&&o.push(e.registerCompletionItemProvider(n,new S(c))),s.hovers&&o.push(e.registerHoverProvider(n,new a(c))),s.documentHighlights&&o.push(e.registerDocumentHighlightProvider(n,new p(c))),s.links&&o.push(e.registerLinkProvider(n,new g(c))),s.documentSymbols&&o.push(e.registerDocumentSymbolProvider(n,new u(c))),s.rename&&o.push(e.registerRenameProvider(n,new m(c))),s.foldingRanges&&o.push(e.registerFoldingRangeProvider(n,new v(c))),s.selectionRanges&&o.push(e.registerSelectionRangeProvider(n,new d(c))),s.documentFormattingEdits&&o.push(e.registerDocumentFormattingEditProvider(n,new r(c))),s.documentRangeFormattingEdits&&o.push(e.registerDocumentRangeFormattingEditProvider(n,new i(c)))}return l(),n.push(T(o)),T(n)}function T(e){return{dispose:()=>E(e)}}function E(e){for(;e.length;)e.pop().dispose()}export{_ as CompletionAdapter,f as DefinitionAdapter,h as DiagnosticsAdapter,l as DocumentColorAdapter,r as DocumentFormattingEditProvider,p as DocumentHighlightAdapter,g as DocumentLinkAdapter,i as DocumentRangeFormattingEditProvider,u as DocumentSymbolAdapter,v as FoldingRangeAdapter,a as HoverAdapter,o as ReferenceAdapter,m as RenameAdapter,d as SelectionRangeAdapter,x as WorkerManager,c as fromPosition,s as fromRange,w as setupMode,C as setupMode1,n as toRange,y as toTextEdit};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{conf as e,language as t}from"./typescript-CY0CmdDM.js";var n=e,r={defaultToken:`invalid`,tokenPostfix:`.js`,keywords:`break.case.catch.class.continue.const.constructor.debugger.default.delete.do.else.export.extends.false.finally.for.from.function.get.if.import.in.instanceof.let.new.null.return.set.static.super.switch.symbol.this.throw.true.try.typeof.undefined.var.void.while.with.yield.async.await.of`.split(`.`),typeKeywords:[],operators:t.operators,symbols:t.symbols,escapes:t.escapes,digits:t.digits,octaldigits:t.octaldigits,binarydigits:t.binarydigits,hexdigits:t.hexdigits,regexpctl:t.regexpctl,regexpesc:t.regexpesc,tokenizer:t.tokenizer};export{n as conf,r as language};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t=[`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`keygen`,`link`,`menuitem`,`meta`,`param`,`source`,`track`,`wbr`],n={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,brackets:[[`<!--`,`-->`],[`<`,`>`],[`{{`,`}}`],[`{%`,`%}`],[`{`,`}`],[`(`,`)`]],autoClosingPairs:[{open:`{`,close:`}`},{open:`%`,close:`%`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],surroundingPairs:[{open:`<`,close:`>`},{open:`"`,close:`"`},{open:`'`,close:`'`}],onEnterRules:[{beforeText:RegExp(`<(?!(?:${t.join(`|`)}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),afterText:/^<\/(\w[\w\d]*)\s*>$/i,action:{indentAction:e.IndentAction.IndentOutdent}},{beforeText:RegExp(`<(?!(?:${t.join(`|`)}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),action:{indentAction:e.IndentAction.Indent}}]},r={defaultToken:``,tokenPostfix:``,builtinTags:`if.else.elseif.endif.render.assign.capture.endcapture.case.endcase.comment.endcomment.cycle.decrement.for.endfor.include.increment.layout.raw.endraw.render.tablerow.endtablerow.unless.endunless`.split(`.`),builtinFilters:`abs.append.at_least.at_most.capitalize.ceil.compact.date.default.divided_by.downcase.escape.escape_once.first.floor.join.json.last.lstrip.map.minus.modulo.newline_to_br.plus.prepend.remove.remove_first.replace.replace_first.reverse.round.rstrip.size.slice.sort.sort_natural.split.strip.strip_html.strip_newlines.times.truncate.truncatewords.uniq.upcase.url_decode.url_encode.where`.split(`.`),constants:[`true`,`false`],operators:[`==`,`!=`,`>`,`<`,`>=`,`<=`],symbol:/[=><!]+/,identifier:/[a-zA-Z_][\w]*/,tokenizer:{root:[[/\{\%\s*comment\s*\%\}/,`comment.start.liquid`,`@comment`],[/\{\{/,{token:`@rematch`,switchTo:`@liquidState.root`}],[/\{\%/,{token:`@rematch`,switchTo:`@liquidState.root`}],[/(<)([\w\-]+)(\/>)/,[`delimiter.html`,`tag.html`,`delimiter.html`]],[/(<)([:\w]+)/,[`delimiter.html`,{token:`tag.html`,next:`@otherTag`}]],[/(<\/)([\w\-]+)/,[`delimiter.html`,{token:`tag.html`,next:`@otherTag`}]],[/</,`delimiter.html`],[/\{/,`delimiter.html`],[/[^<{]+/]],comment:[[/\{\%\s*endcomment\s*\%\}/,`comment.end.liquid`,`@pop`],[/./,`comment.content.liquid`]],otherTag:[[/\{\{/,{token:`@rematch`,switchTo:`@liquidState.otherTag`}],[/\{\%/,{token:`@rematch`,switchTo:`@liquidState.otherTag`}],[/\/?>/,`delimiter.html`,`@pop`],[/"([^"]*)"/,`attribute.value`],[/'([^']*)'/,`attribute.value`],[/[\w\-]+/,`attribute.name`],[/=/,`delimiter`],[/[ \t\r\n]+/]],liquidState:[[/\{\{/,`delimiter.output.liquid`],[/\}\}/,{token:`delimiter.output.liquid`,switchTo:`@$S2.$S3`}],[/\{\%/,`delimiter.tag.liquid`],[/raw\s*\%\}/,`delimiter.tag.liquid`,`@liquidRaw`],[/\%\}/,{token:`delimiter.tag.liquid`,switchTo:`@$S2.$S3`}],{include:`liquidRoot`}],liquidRaw:[[/^(?!\{\%\s*endraw\s*\%\}).+/],[/\{\%/,`delimiter.tag.liquid`],[/@identifier/],[/\%\}/,{token:`delimiter.tag.liquid`,next:`@root`}]],liquidRoot:[[/\d+(\.\d+)?/,`number.liquid`],[/"[^"]*"/,`string.liquid`],[/'[^']*'/,`string.liquid`],[/\s+/],[/@symbol/,{cases:{"@operators":`operator.liquid`,"@default":``}}],[/\./],[/@identifier/,{cases:{"@constants":`keyword.liquid`,"@builtinFilters":`predefined.liquid`,"@builtinTags":`predefined.liquid`,"@default":`variable.liquid`}}],[/[^}|%]/,`variable.liquid`]]}};export{n as conf,r as language};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t={comments:{blockComment:[`{/*`,`*/}`]},brackets:[[`{`,`}`]],autoClosingPairs:[{open:`"`,close:`"`},{open:`'`,close:`'`},{open:``,close:``},{open:``,close:``},{open:"`",close:"`"},{open:`{`,close:`}`},{open:`(`,close:`)`},{open:`_`,close:`_`},{open:`**`,close:`**`},{open:`<`,close:`>`}],onEnterRules:[{beforeText:/^\s*- .+/,action:{indentAction:e.IndentAction.None,appendText:`- `}},{beforeText:/^\s*\+ .+/,action:{indentAction:e.IndentAction.None,appendText:`+ `}},{beforeText:/^\s*\* .+/,action:{indentAction:e.IndentAction.None,appendText:`* `}},{beforeText:/^> /,action:{indentAction:e.IndentAction.None,appendText:`> `}},{beforeText:/<\w+/,action:{indentAction:e.IndentAction.Indent}},{beforeText:/\s+>\s*$/,action:{indentAction:e.IndentAction.Indent}},{beforeText:/<\/\w+>/,action:{indentAction:e.IndentAction.Outdent}},...Array.from({length:100},(t,n)=>({beforeText:RegExp(`^${n}\\. .+`),action:{indentAction:e.IndentAction.None,appendText:`${n+1}. `}}))]},n={defaultToken:``,tokenPostfix:`.mdx`,control:/[!#()*+.[\\\]_`{}\-]/,escapes:/\\@control/,tokenizer:{root:[[/^---$/,{token:`meta.content`,next:`@frontmatter`,nextEmbedded:`yaml`}],[/^\s*import/,{token:`keyword`,next:`@import`,nextEmbedded:`js`}],[/^\s*export/,{token:`keyword`,next:`@export`,nextEmbedded:`js`}],[/<\w+/,{token:`type.identifier`,next:`@jsx`}],[/<\/?\w+>/,`type.identifier`],[/^(\s*)(>*\s*)(#{1,6}\s)/,[{token:`white`},{token:`comment`},{token:`keyword`,next:`@header`}]],[/^(\s*)(>*\s*)([*+-])(\s+)/,[`white`,`comment`,`keyword`,`white`]],[/^(\s*)(>*\s*)(\d{1,9}\.)(\s+)/,[`white`,`comment`,`number`,`white`]],[/^(\s*)(>*\s*)(\d{1,9}\.)(\s+)/,[`white`,`comment`,`number`,`white`]],[/^(\s*)(>*\s*)(-{3,}|\*{3,}|_{3,})$/,[`white`,`comment`,`keyword`]],[/`{3,}(\s.*)?$/,{token:`string`,next:`@codeblock_backtick`}],[/~{3,}(\s.*)?$/,{token:`string`,next:`@codeblock_tilde`}],[/`{3,}(\S+).*$/,{token:`string`,next:`@codeblock_highlight_backtick`,nextEmbedded:`$1`}],[/~{3,}(\S+).*$/,{token:`string`,next:`@codeblock_highlight_tilde`,nextEmbedded:`$1`}],[/^(\s*)(-{4,})$/,[`white`,`comment`]],[/^(\s*)(>+)/,[`white`,`comment`]],{include:`content`}],content:[[/(\[)(.+)(]\()(.+)(\s+".*")(\))/,[``,`string.link`,``,`type.identifier`,`string.link`,``]],[/(\[)(.+)(]\()(.+)(\))/,[``,`type.identifier`,``,`string.link`,``]],[/(\[)(.+)(]\[)(.+)(])/,[``,`type.identifier`,``,`type.identifier`,``]],[/(\[)(.+)(]:\s+)(\S*)/,[``,`type.identifier`,``,`string.link`]],[/(\[)(.+)(])/,[``,`type.identifier`,``]],[/`.*`/,`variable.source`],[/_/,{token:`emphasis`,next:`@emphasis_underscore`}],[/\*(?!\*)/,{token:`emphasis`,next:`@emphasis_asterisk`}],[/\*\*/,{token:`strong`,next:`@strong`}],[/{/,{token:`delimiter.bracket`,next:`@expression`,nextEmbedded:`js`}]],import:[[/'\s*(;|$)/,{token:`string`,next:`@pop`,nextEmbedded:`@pop`}]],expression:[[/{/,{token:`delimiter.bracket`,next:`@expression`}],[/}/,{token:`delimiter.bracket`,next:`@pop`,nextEmbedded:`@pop`}]],export:[[/^\s*$/,{token:`delimiter.bracket`,next:`@pop`,nextEmbedded:`@pop`}]],jsx:[[/\s+/,``],[/(\w+)(=)("(?:[^"\\]|\\.)*")/,[`attribute.name`,`operator`,`string`]],[/(\w+)(=)('(?:[^'\\]|\\.)*')/,[`attribute.name`,`operator`,`string`]],[/(\w+(?=\s|>|={|$))/,[`attribute.name`]],[/={/,{token:`delimiter.bracket`,next:`@expression`,nextEmbedded:`js`}],[/>/,{token:`type.identifier`,next:`@pop`}]],header:[[/.$/,{token:`keyword`,next:`@pop`}],{include:`content`},[/./,{token:`keyword`}]],strong:[[/\*\*/,{token:`strong`,next:`@pop`}],{include:`content`},[/./,{token:`strong`}]],emphasis_underscore:[[/_/,{token:`emphasis`,next:`@pop`}],{include:`content`},[/./,{token:`emphasis`}]],emphasis_asterisk:[[/\*(?!\*)/,{token:`emphasis`,next:`@pop`}],{include:`content`},[/./,{token:`emphasis`}]],frontmatter:[[/^---$/,{token:`meta.content`,nextEmbedded:`@pop`,next:`@pop`}]],codeblock_highlight_backtick:[[/\s*`{3,}\s*$/,{token:`string`,next:`@pop`,nextEmbedded:`@pop`}],[/.*$/,`variable.source`]],codeblock_highlight_tilde:[[/\s*~{3,}\s*$/,{token:`string`,next:`@pop`,nextEmbedded:`@pop`}],[/.*$/,`variable.source`]],codeblock_backtick:[[/\s*`{3,}\s*$/,{token:`string`,next:`@pop`}],[/.*$/,`variable.source`]],codeblock_tilde:[[/\s*~{3,}\s*$/,{token:`string`,next:`@pop`}],[/.*$/,`variable.source`]]}};export{t as conf,n as language};
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t={comments:{lineComment:`#`,blockComment:[`'''`,`'''`]},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`,notIn:[`string`]},{open:`'`,close:`'`,notIn:[`string`,`comment`]}],surroundingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],onEnterRules:[{beforeText:RegExp(`^\\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async|match|case).*?:\\s*$`),action:{indentAction:e.IndentAction.Indent}}],folding:{offSide:!0,markers:{start:RegExp(`^\\s*#region\\b`),end:RegExp(`^\\s*#endregion\\b`)}}},n={defaultToken:``,tokenPostfix:`.python`,keywords:`False.None.True._.and.as.assert.async.await.break.case.class.continue.def.del.elif.else.except.exec.finally.for.from.global.if.import.in.is.lambda.match.nonlocal.not.or.pass.print.raise.return.try.type.while.with.yield.int.float.long.complex.hex.abs.all.any.apply.basestring.bin.bool.buffer.bytearray.callable.chr.classmethod.cmp.coerce.compile.complex.delattr.dict.dir.divmod.enumerate.eval.execfile.file.filter.format.frozenset.getattr.globals.hasattr.hash.help.id.input.intern.isinstance.issubclass.iter.len.locals.list.map.max.memoryview.min.next.object.oct.open.ord.pow.print.property.reversed.range.raw_input.reduce.reload.repr.reversed.round.self.set.setattr.slice.sorted.staticmethod.str.sum.super.tuple.type.unichr.unicode.vars.xrange.zip.__dict__.__methods__.__members__.__class__.__bases__.__name__.__mro__.__subclasses__.__init__.__import__`.split(`.`),brackets:[{open:`{`,close:`}`,token:`delimiter.curly`},{open:`[`,close:`]`,token:`delimiter.bracket`},{open:`(`,close:`)`,token:`delimiter.parenthesis`}],tokenizer:{root:[{include:`@whitespace`},{include:`@numbers`},{include:`@strings`},[/[,:;]/,`delimiter`],[/[{}\[\]()]/,`@brackets`],[/@[a-zA-Z_]\w*/,`tag`],[/[a-zA-Z_]\w*/,{cases:{"@keywords":`keyword`,"@default":`identifier`}}]],whitespace:[[/\s+/,`white`],[/(^#.*$)/,`comment`],[/'''/,`string`,`@endDocString`],[/"""/,`string`,`@endDblDocString`]],endDocString:[[/[^']+/,`string`],[/\\'/,`string`],[/'''/,`string`,`@popall`],[/'/,`string`]],endDblDocString:[[/[^"]+/,`string`],[/\\"/,`string`],[/"""/,`string`,`@popall`],[/"/,`string`]],numbers:[[/-?0x([abcdef]|[ABCDEF]|\d)+[lL]?/,`number.hex`],[/-?(\d*\.)?\d+([eE][+\-]?\d+)?[jJ]?[lL]?/,`number`]],strings:[[/'$/,`string.escape`,`@popall`],[/f'{1,3}/,`string.escape`,`@fStringBody`],[/'/,`string.escape`,`@stringBody`],[/"$/,`string.escape`,`@popall`],[/f"{1,3}/,`string.escape`,`@fDblStringBody`],[/"/,`string.escape`,`@dblStringBody`]],fStringBody:[[/[^\\'\{\}]+$/,`string`,`@popall`],[/[^\\'\{\}]+/,`string`],[/\{[^\}':!=]+/,`identifier`,`@fStringDetail`],[/\\./,`string`],[/'/,`string.escape`,`@popall`],[/\\$/,`string`]],stringBody:[[/[^\\']+$/,`string`,`@popall`],[/[^\\']+/,`string`],[/\\./,`string`],[/'/,`string.escape`,`@popall`],[/\\$/,`string`]],fDblStringBody:[[/[^\\"\{\}]+$/,`string`,`@popall`],[/[^\\"\{\}]+/,`string`],[/\{[^\}':!=]+/,`identifier`,`@fStringDetail`],[/\\./,`string`],[/"/,`string.escape`,`@popall`],[/\\$/,`string`]],dblStringBody:[[/[^\\"]+$/,`string`,`@popall`],[/[^\\"]+/,`string`],[/\\./,`string`],[/"/,`string.escape`,`@popall`],[/\\$/,`string`]],fStringDetail:[[/[:][^}]+/,`string`],[/[!][ars]/,`string`],[/=/,`string`],[/\}/,`identifier`,`@pop`]]}};export{t as conf,n as language};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:`//`,blockComment:[`/*`,`*/`]},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],onEnterRules:[{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,afterText:/^\s*\*\/$/,action:{indentAction:e.IndentAction.IndentOutdent,appendText:` * `}},{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,action:{indentAction:e.IndentAction.None,appendText:` * `}},{beforeText:/^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,action:{indentAction:e.IndentAction.None,appendText:`* `}},{beforeText:/^(\t|(\ \ ))*\ \*\/\s*$/,action:{indentAction:e.IndentAction.None,removeText:1}}],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`,notIn:[`string`]},{open:`'`,close:`'`,notIn:[`string`,`comment`]},{open:"`",close:"`",notIn:[`string`,`comment`]},{open:`/**`,close:` */`,notIn:[`string`]}],folding:{markers:{start:RegExp(`^\\s*//\\s*#?region\\b`),end:RegExp(`^\\s*//\\s*#?endregion\\b`)}}},n={defaultToken:`invalid`,tokenPostfix:`.ts`,keywords:`abstract.any.as.asserts.bigint.boolean.break.case.catch.class.continue.const.constructor.debugger.declare.default.delete.do.else.enum.export.extends.false.finally.for.from.function.get.if.implements.import.in.infer.instanceof.interface.is.keyof.let.module.namespace.never.new.null.number.object.out.package.private.protected.public.override.readonly.require.global.return.satisfies.set.static.string.super.switch.symbol.this.throw.true.try.type.typeof.undefined.unique.unknown.var.void.while.with.yield.async.await.of`.split(`.`),operators:`<=.>=.==.!=.===.!==.=>.+.-.**.*./.%.++.--.<<.</.>>.>>>.&.|.^.!.~.&&.||.??.?.:.=.+=.-=.*=.**=./=.%=.<<=.>>=.>>>=.&=.|=.^=.@`.split(`.`),symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,regexpctl:/[(){}\[\]\$\^|\-*+?\.]/,regexpesc:/\\(?:[bBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/,tokenizer:{root:[[/[{}]/,`delimiter.bracket`],{include:`common`}],common:[[/#?[a-z_$][\w$]*/,{cases:{"@keywords":`keyword`,"@default":`identifier`}}],[/[A-Z][\w\$]*/,`type.identifier`],{include:`@whitespace`},[/\/(?=([^\\\/]|\\.)+\/([dgimsuy]*)(\s*)(\.|;|,|\)|\]|\}|$))/,{token:`regexp`,bracket:`@open`,next:`@regexp`}],[/[()\[\]]/,`@brackets`],[/[<>](?!@symbols)/,`@brackets`],[/!(?=([^=]|$))/,`delimiter`],[/@symbols/,{cases:{"@operators":`delimiter`,"@default":``}}],[/(@digits)[eE]([\-+]?(@digits))?/,`number.float`],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?/,`number.float`],[/0[xX](@hexdigits)n?/,`number.hex`],[/0[oO]?(@octaldigits)n?/,`number.octal`],[/0[bB](@binarydigits)n?/,`number.binary`],[/(@digits)n?/,`number`],[/[;,.]/,`delimiter`],[/"([^"\\]|\\.)*$/,`string.invalid`],[/'([^'\\]|\\.)*$/,`string.invalid`],[/"/,`string`,`@string_double`],[/'/,`string`,`@string_single`],[/`/,`string`,`@string_backtick`]],whitespace:[[/[ \t\r\n]+/,``],[/\/\*\*(?!\/)/,`comment.doc`,`@jsdoc`],[/\/\*/,`comment`,`@comment`],[/\/\/.*$/,`comment`]],comment:[[/[^\/*]+/,`comment`],[/\*\//,`comment`,`@pop`],[/[\/*]/,`comment`]],jsdoc:[[/[^\/*]+/,`comment.doc`],[/\*\//,`comment.doc`,`@pop`],[/[\/*]/,`comment.doc`]],regexp:[[/(\{)(\d+(?:,\d*)?)(\})/,[`regexp.escape.control`,`regexp.escape.control`,`regexp.escape.control`]],[/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/,[`regexp.escape.control`,{token:`regexp.escape.control`,next:`@regexrange`}]],[/(\()(\?:|\?=|\?!)/,[`regexp.escape.control`,`regexp.escape.control`]],[/[()]/,`regexp.escape.control`],[/@regexpctl/,`regexp.escape.control`],[/[^\\\/]/,`regexp`],[/@regexpesc/,`regexp.escape`],[/\\\./,`regexp.invalid`],[/(\/)([dgimsuy]*)/,[{token:`regexp`,bracket:`@close`,next:`@pop`},`keyword.other`]]],regexrange:[[/-/,`regexp.escape.control`],[/\^/,`regexp.invalid`],[/@regexpesc/,`regexp.escape`],[/[^\]]/,`regexp`],[/\]/,{token:`regexp.escape.control`,next:`@pop`,bracket:`@close`}]],string_double:[[/[^\\"]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/"/,`string`,`@pop`]],string_single:[[/[^\\']+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/'/,`string`,`@pop`]],string_backtick:[[/\$\{/,{token:`delimiter.bracket`,next:`@bracketCounting`}],[/[^\\`$]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/`/,`string`,`@pop`]],bracketCounting:[[/\{/,`delimiter.bracket`,`@bracketCounting`],[/\}/,`delimiter.bracket`,`@pop`],{include:`common`}]}};export{t as conf,n as language};
+1
View File
@@ -0,0 +1 @@
import{jr as e,zt as t}from"./index-AmyXDl4i.js";import{o as n}from"./VContainer-Dqw80qLq.js";import{t as r}from"./apiError-CvOGzIYs.js";function i(){let i=e([]),a=e(!1),o=n();async function s(e){a.value=!0;try{i.value=(await t.getList(`/servers/`,{per_page:e?.perPage??200})).items}catch(e){i.value=[],o(r(e,`加载服务器列表失败`),`error`)}finally{a.value=!1}}return{servers:i,loading:a,loadServers:s}}export{i as t};
@@ -0,0 +1,2 @@
import{$n as e,br as t,dr as n,gr as r,jr as i,nr as a,rr as o,sr as s,tr as c,zr as l,zt as u}from"./index-AmyXDl4i.js";import{t as d}from"./_plugin-vue_export-helper-BDNMzG2s.js";var f=new Set(`if.then.else.elif.fi.for.while.do.done.case.esac.in.function.return.break.continue.select.until.cd.ls.grep.egrep.fgrep.find.cat.chmod.chown.docker.podman.kubectl.apt.apt-get.yum.dnf.apk.pip.pip3.npm.npx.ssh.scp.rsync.curl.wget.tar.gzip.gunzip.kill.ps.top.htop.nano.vim.vi.journalctl.systemctl.service.supervisorctl.crontab.nginx.df.du.free.mount.uname.hostname.whoami.id.pwd.head.tail.wc.sort.uniq.awk.sed.cut.tr.xargs.tee.netstat.ss.ip.ping.dig.git.make.nohup.timeout.watch`.split(`.`)),p=new Set([`echo`,`printf`,`test`,`read`,`pushd`,`popd`,`exit`,`set`,`unset`,`export`,`source`,`alias`,`type`,`command`,`hash`,`help`,`history`]);function m(e){return e===`sudo`?`sudo`:f.has(e)?`keyword`:p.has(e)?`builtin`:/^[/~]/.test(e)||e.startsWith(`./`)||e.startsWith(`../`)?`path`:/^\d+(?:\.\d+)?$/.test(e)?`number`:`text`}function h(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(r===`#`){let r=n+1;for(;r<e.length&&e[r]!==`
`;)r++;t.push({type:`comment`,value:e.slice(n,r)}),n=r;continue}if(r===`'`||r===`"`){let i=r,a=n+1;for(;a<e.length;){if(e[a]===`\\`&&i===`"`){a+=2;continue}if(e[a]===i){a++;break}a++}t.push({type:`string`,value:e.slice(n,a)}),n=a;continue}if(r==="`"){let r=n+1;for(;r<e.length&&e[r]!=="`";)r++;r<e.length&&r++,t.push({type:`backtick`,value:e.slice(n,r)}),n=r;continue}if(r===`$`){let r=n+1;if(e[r]===`{`){for(;r<e.length&&e[r]!==`}`;)r++;r<e.length&&r++}else if(e[r]===`(`)r++;else for(;r<e.length&&/[\w]/.test(e[r]);)r++;t.push({type:`variable`,value:e.slice(n,r)}),n=r;continue}if(r===`|`||r===`&`||r===`;`){let r=n;e[r]===`|`&&e[r+1]===`|`||e[r]===`&`&&e[r+1]===`&`?r+=2:r+=1;let i=e.slice(n,r);t.push({type:i===`|`||i===`||`?`pipe`:`operator`,value:i}),n=r;continue}if(r===`>`||r===`<`){let r=n;e[r]===`>`&&e[r+1]===`>`||e[r]===`<`&&e[r+1]===`<`?r+=2:r+=1,e[r]===`&`&&r++,t.push({type:`redirect`,value:e.slice(n,r)}),n=r;continue}if(/\s/.test(r)){let r=n;for(;r<e.length&&/\s/.test(e[r]);)r++;t.push({type:`text`,value:e.slice(n,r)}),n=r;continue}if(r===`-`&&e[n+1]===`-`){let r=n+2;for(;r<e.length&&/[\w-]/.test(e[r]);)r++;t.push({type:`flag`,value:e.slice(n,r)}),n=r;continue}if(r===`-`&&/[a-zA-Z]/.test(e[n+1]||``)){let r=n+1;for(;r<e.length&&/[a-zA-Z]/.test(e[r]);)r++;t.push({type:`flag`,value:e.slice(n,r)}),n=r;continue}let i=n;for(;i<e.length&&!/[\s#"'`$|;&<>]/.test(e[i]);)i++;let a=e.slice(n,i);t.push({type:m(a),value:a}),n=i}return t}function g(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}var _={keyword:`sh-keyword`,builtin:`sh-builtin`,sudo:`sh-sudo`,pipe:`sh-pipe`,operator:`sh-operator`,redirect:`sh-redirect`,string:`sh-string`,flag:`sh-flag`,variable:`sh-variable`,backtick:`sh-backtick`,comment:`sh-comment`,number:`sh-number`,path:`sh-path`,text:`sh-text`};function v(e){return e?h(e).map(e=>`<span class="${_[e.type]}">${g(e.value)}</span>`).join(``):``}var y=[`innerHTML`],b=d(s({__name:`ShellHighlightField`,props:{modelValue:{},placeholder:{default:``},disabled:{type:Boolean,default:!1},multiline:{type:Boolean,default:!1},rows:{default:3},size:{default:`default`}},emits:[`update:modelValue`,`keydown`],setup(s,{expose:u,emit:d}){let f=i(null),p=s,m=d,h=e(()=>v(p.modelValue));function g(e){let t=e.target;m(`update:modelValue`,t.value)}function _(e){m(`keydown`,e)}function b(){return f.value}function x(){f.value?.focus()}function S(){let e=f.value;return e?e.value.substring(e.selectionStart??0,e.selectionEnd??0):``}function C(){let e=f.value;e&&(e.focus(),e.select())}async function w(e){let t=f.value;if(!t)return;let r=t.selectionStart??t.value.length,i=t.selectionEnd??r;m(`update:modelValue`,t.value.slice(0,r)+e+t.value.slice(i)),await n(),t.focus();let a=r+e.length;t.setSelectionRange(a,a)}return u({getInputEl:b,focusInput:x,getSelectionText:S,selectAllInput:C,insertAtSelection:w}),(e,n)=>(r(),o(`div`,{class:l([`sh-field position-relative`,{"sh-field--disabled":s.disabled,"sh-field--empty":!s.modelValue,"sh-field--large":s.size===`large`}])},[s.modelValue?(r(),o(`div`,{key:0,class:l([`sh-field__highlight font-mono`,s.multiline?`sh-field__highlight--multi`:`sh-field__highlight--single`]),"aria-hidden":`true`,innerHTML:h.value},null,10,y)):a(``,!0),(r(),c(t(s.multiline?`textarea`:`input`),{ref_key:`inputRef`,ref:f,value:s.modelValue,placeholder:s.placeholder,disabled:s.disabled,rows:s.multiline?s.rows:void 0,class:l([`sh-field__input font-mono`,s.multiline?`sh-field__input--multi`:`sh-field__input--single`]),spellcheck:`false`,autocomplete:`off`,onInput:g,onKeydown:_},null,40,[`value`,`placeholder`,`disabled`,`rows`,`class`]))],2))}}),[[`__scopeId`,`data-v-b73e3452`]]);function x(e){return[...e].sort((e,t)=>e.is_builtin===t.is_builtin?e.sort_order===t.sort_order?e.id-t.id:e.sort_order-t.sort_order:e.is_builtin?1:-1)}function S(){let e=i([]),t=i(!1);async function n(){t.value=!0;try{e.value=x(await u.get(`/terminal/quick-commands`)||[])}catch{throw e.value=[],Error(``)}finally{t.value=!1}}async function r(e,t){await u.post(`/terminal/quick-commands`,{name:e.trim(),cmd:t.trim()}),await n()}async function a(e,t,r){await u.put(`/terminal/quick-commands/${e}`,{name:t.trim(),cmd:r.trim()}),await n()}async function o(e){await u.delete(`/terminal/quick-commands/${e}`),await n()}async function s(t){e.value=x((await u.put(`/terminal/quick-commands/reorder`,{ids:t})).items||[])}return{commands:e,loading:t,load:n,create:r,update:a,remove:o,reorder:s,customCommands:()=>e.value.filter(e=>!e.is_builtin),builtinCommands:()=>e.value.filter(e=>e.is_builtin)}}export{S as n,b as r,x as t};
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t={comments:{blockComment:[`<!--`,`-->`]},brackets:[[`<`,`>`]],autoClosingPairs:[{open:`<`,close:`>`},{open:`'`,close:`'`},{open:`"`,close:`"`}],surroundingPairs:[{open:`<`,close:`>`},{open:`'`,close:`'`},{open:`"`,close:`"`}],onEnterRules:[{beforeText:RegExp(`<([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:e.IndentAction.IndentOutdent}},{beforeText:RegExp(`<(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),action:{indentAction:e.IndentAction.Indent}}]},n={defaultToken:``,tokenPostfix:`.xml`,ignoreCase:!0,qualifiedName:/(?:[\w\.\-]+:)?[\w\.\-]+/,tokenizer:{root:[[/[^<&]+/,``],{include:`@whitespace`},[/(<)(@qualifiedName)/,[{token:`delimiter`},{token:`tag`,next:`@tag`}]],[/(<\/)(@qualifiedName)(\s*)(>)/,[{token:`delimiter`},{token:`tag`},``,{token:`delimiter`}]],[/(<\?)(@qualifiedName)/,[{token:`delimiter`},{token:`metatag`,next:`@tag`}]],[/(<\!)(@qualifiedName)/,[{token:`delimiter`},{token:`metatag`,next:`@tag`}]],[/<\!\[CDATA\[/,{token:`delimiter.cdata`,next:`@cdata`}],[/&\w+;/,`string.escape`]],cdata:[[/[^\]]+/,``],[/\]\]>/,{token:`delimiter.cdata`,next:`@pop`}],[/\]/,``]],tag:[[/[ \t\r\n]+/,``],[/(@qualifiedName)(\s*=\s*)("[^"]*"|'[^']*')/,[`attribute.name`,``,`attribute.value`]],[/(@qualifiedName)(\s*=\s*)("[^">?\/]*|'[^'>?\/]*)(?=[\?\/]\>)/,[`attribute.name`,``,`attribute.value`]],[/(@qualifiedName)(\s*=\s*)("[^">]*|'[^'>]*)/,[`attribute.name`,``,`attribute.value`]],[/@qualifiedName/,`attribute.name`],[/\?>/,{token:`delimiter`,next:`@pop`}],[/(\/)(>)/,[{token:`tag`},{token:`delimiter`,next:`@pop`}]],[/>/,{token:`delimiter`,next:`@pop`}]],whitespace:[[/[ \t\r\n]+/,``],[/<!--/,{token:`comment`,next:`@comment`}]],comment:[[/[^<\-]+/,`comment.content`],[/-->/,{token:`comment`,next:`@pop`}],[/<!--/,`comment.content.invalid`],[/[<\-]/,`comment.content`]]}};export{t as conf,n as language};
+1
View File
@@ -0,0 +1 @@
import{p as e}from"./initMonaco-x1oyshyc.js";var t={comments:{lineComment:`#`},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],surroundingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],folding:{offSide:!0},onEnterRules:[{beforeText:/:\s*$/,action:{indentAction:e.IndentAction.Indent}}]},n={tokenPostfix:`.yaml`,brackets:[{token:`delimiter.bracket`,open:`{`,close:`}`},{token:`delimiter.square`,open:`[`,close:`]`}],keywords:[`true`,`True`,`TRUE`,`false`,`False`,`FALSE`,`null`,`Null`,`Null`,`~`],numberInteger:/(?:0|[+-]?[0-9]+)/,numberFloat:/(?:0|[+-]?[0-9]+)(?:\.[0-9]+)?(?:e[-+][1-9][0-9]*)?/,numberOctal:/0o[0-7]+/,numberHex:/0x[0-9a-fA-F]+/,numberInfinity:/[+-]?\.(?:inf|Inf|INF)/,numberNaN:/\.(?:nan|Nan|NAN)/,numberDate:/\d{4}-\d\d-\d\d([Tt ]\d\d:\d\d:\d\d(\.\d+)?(( ?[+-]\d\d?(:\d\d)?)|Z)?)?/,escapes:/\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,tokenizer:{root:[{include:`@whitespace`},{include:`@comment`},[/%[^ ]+.*$/,`meta.directive`],[/---/,`operators.directivesEnd`],[/\.{3}/,`operators.documentEnd`],[/[-?:](?= )/,`operators`],{include:`@anchor`},{include:`@tagHandle`},{include:`@flowCollections`},{include:`@blockStyle`},[/@numberInteger(?![ \t]*\S+)/,`number`],[/@numberFloat(?![ \t]*\S+)/,`number.float`],[/@numberOctal(?![ \t]*\S+)/,`number.octal`],[/@numberHex(?![ \t]*\S+)/,`number.hex`],[/@numberInfinity(?![ \t]*\S+)/,`number.infinity`],[/@numberNaN(?![ \t]*\S+)/,`number.nan`],[/@numberDate(?![ \t]*\S+)/,`number.date`],[/(".*?"|'.*?'|[^#'"]*?)([ \t]*)(:)( |$)/,[`type`,`white`,`operators`,`white`]],{include:`@flowScalars`},[/.+?(?=(\s+#|$))/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],object:[{include:`@whitespace`},{include:`@comment`},[/\}/,`@brackets`,`@pop`],[/,/,`delimiter.comma`],[/:(?= )/,`operators`],[/(?:".*?"|'.*?'|[^,\{\[]+?)(?=: )/,`type`],{include:`@flowCollections`},{include:`@flowScalars`},{include:`@tagHandle`},{include:`@anchor`},{include:`@flowNumber`},[/[^\},]+/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],array:[{include:`@whitespace`},{include:`@comment`},[/\]/,`@brackets`,`@pop`],[/,/,`delimiter.comma`],{include:`@flowCollections`},{include:`@flowScalars`},{include:`@tagHandle`},{include:`@anchor`},{include:`@flowNumber`},[/[^\],]+/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],multiString:[[/^( +).+$/,`string`,`@multiStringContinued.$1`]],multiStringContinued:[[/^( *).+$/,{cases:{"$1==$S2":`string`,"@default":{token:`@rematch`,next:`@popall`}}}]],whitespace:[[/[ \t\r\n]+/,`white`]],comment:[[/#.*$/,`comment`]],flowCollections:[[/\[/,`@brackets`,`@array`],[/\{/,`@brackets`,`@object`]],flowScalars:[[/"([^"\\]|\\.)*$/,`string.invalid`],[/'([^'\\]|\\.)*$/,`string.invalid`],[/'[^']*'/,`string`],[/"/,`string`,`@doubleQuotedString`]],doubleQuotedString:[[/[^\\"]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/"/,`string`,`@pop`]],blockStyle:[[/[>|][0-9]*[+-]?$/,`operators`,`@multiString`]],flowNumber:[[/@numberInteger(?=[ \t]*[,\]\}])/,`number`],[/@numberFloat(?=[ \t]*[,\]\}])/,`number.float`],[/@numberOctal(?=[ \t]*[,\]\}])/,`number.octal`],[/@numberHex(?=[ \t]*[,\]\}])/,`number.hex`],[/@numberInfinity(?=[ \t]*[,\]\}])/,`number.infinity`],[/@numberNaN(?=[ \t]*[,\]\}])/,`number.nan`],[/@numberDate(?=[ \t]*[,\]\}])/,`number.date`]],tagHandle:[[/\![^ ]*/,`tag`]],anchor:[[/[&*][^ ]+/,`namespace`]]}};export{t as conf,n as language};
+1 -1
View File
@@ -5,7 +5,7 @@
<link rel="icon" href="/app/favicon.ico"> <link rel="icon" href="/app/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nexus</title> <title>Nexus</title>
<script type="module" crossorigin src="/app/assets/index-DNlvHxBC.js"></script> <script type="module" crossorigin src="/app/assets/index-AmyXDl4i.js"></script>
<link rel="stylesheet" crossorigin href="/app/assets/index-BGzIPEZO.css"> <link rel="stylesheet" crossorigin href="/app/assets/index-BGzIPEZO.css">
</head> </head>
<body> <body>
+2
View File
@@ -0,0 +1,2 @@
名称,地址,SSH端口,用户名,认证方式,密码,密钥路径,私钥内容,分类,目标路径,备注
web-01,192.168.1.10,22,root,password,your-password,,,商城,/www/wwwroot,Web服务器
1 名称 地址 SSH端口 用户名 认证方式 密码 密钥路径 私钥内容 分类 目标路径 备注
2 web-01 192.168.1.10 22 root password your-password 商城 /www/wwwroot Web服务器