diff --git a/Makefile b/Makefile index 92c503b..8f4f445 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: test vet check build package +.PHONY: test vet shell-check check build package ui-check test: (cd plugins/plugin-admin && go test -race ./... -count=1) @@ -8,11 +8,18 @@ vet: (cd plugins/plugin-admin && go vet ./...) (cd plugins/subscription-admin && go vet ./...) -check: test vet +shell-check: + bash -n deploy/install.sh deploy/uninstall.sh scripts/install-local.sh tests/deploy-path-safety.sh + sh -n plugins/plugin-admin/build.sh plugins/plugin-admin/build-ui.sh plugins/plugin-admin/test/run-browser-check.sh + sh -n plugins/subscription-admin/build.sh plugins/subscription-admin/package.sh plugins/subscription-admin/test/run-browser-check.sh + bash tests/deploy-path-safety.sh + +ui-check: + (cd plugins/plugin-admin/ui-vue && npm ci --ignore-scripts && npm run typecheck && npm run build) + +check: test vet shell-check ui-check node --check plugins/plugin-admin/ui/app.js node --check plugins/subscription-admin/ui/app.js - sh -n plugins/plugin-admin/build.sh plugins/plugin-admin/test/run-browser-check.sh - sh -n plugins/subscription-admin/build.sh plugins/subscription-admin/package.sh plugins/subscription-admin/test/run-browser-check.sh (cd plugins/subscription-admin && go run ./tools/manifestcheck) git diff --check diff --git a/README.md b/README.md index 72361cf..0854d97 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ HTTP API、管理员鉴权和 `custom_menu_items` 接入 Core;插件不导入 ## 目录 -- `plugins/plugin-admin`:通用插件管理控制面,负责清单、签名、插件市场、 +- `plugins/plugin-admin`:通用插件管理控制面,负责清单、业务包签名校验、插件市场、 下载入库、启用、停用、升级、回滚、删除、配置、健康检查、审计和菜单注入。 - `plugins/subscription-admin`:可选的订阅管理业务模块后端。它不是插件管理 控制面;只有安装并启用后才会挂载到 Plugin Admin 的统一导航中。 @@ -19,8 +19,10 @@ TypeScript/Vite 构建,并把本地打包的 TDesign、线性图标和 ECharts Go 服务;官方 Core 的 `frontend/` 不参与构建。 控制面和业务模块后端可以独立构建和发布,但浏览器端只有一个 Plugin Admin -登录入口。生产环境应使用独立的 -低权限服务账号、HTTPS 反向代理、签名包和稳定的 Core API 兼容基线。 +登录入口。生产环境应使用独立的低权限服务账号、HTTPS 反向代理和稳定的 +Core API 兼容基线。业务 `.s2plugin` 归档必须使用受信发布者签名;Plugin +Admin 本身是独立的控制面服务,使用 immutable commit checkout 后本地编译, +不通过 `.s2plugin` 发布。 ## 推荐部署顺序 @@ -44,7 +46,7 @@ Core 仓库,也不要让插件连接 Core PostgreSQL/Redis。 (cd plugins/subscription-admin && go run ./tools/manifestcheck) ``` -生成订阅插件包: +生成订阅业务插件包(Plugin Admin 本身不生成 `.s2plugin`): ```sh (cd plugins/subscription-admin && ./package.sh) @@ -57,7 +59,10 @@ Core 仓库,也不要让插件连接 Core PostgreSQL/Redis。 1. 启动 `plugin-admin` 和需要的业务模块后端,各自监听独立端口。 2. 使用 Core 管理员账号登录 Plugin Admin 一次;普通账号被拒绝,业务模块不再单独登录。 3. 在 `plugin-admin` 上传或从插件市场下载并校验业务插件包;包只进入“已入库,待启用”状态。 -4. 配置 loopback `service_url`,点击启用并完成健康检查后,插件才会启动。 +4. 对托管 command 插件,点击启用后由控制面启动进程并完成健康检查;对 + `subscription-admin` 这类 external 插件,必须先由部署者或 systemd 启动 + 后端,再配置 loopback `service_url`,启用只负责探测和挂载,不会替外部服务 + 创建进程。 5. 预览、确认并应用插件声明的管理员菜单;停用后可删除插件。 订阅模块进入统一控制面后使用 `/modules/subscription/*` 路由。Plugin Admin @@ -74,15 +79,29 @@ Linux + systemd 环境可直接使用仓库内的安装脚本: ```sh RELEASE_SHA=COMMIT_SHA_40_HEX curl -fsSL "https://git.awaioi.com/awaioi/sub2api-add/raw/commit/${RELEASE_SHA}/deploy/install.sh" \ - | sudo env PLUGIN_REF=v1.1.0 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin all + | sudo env PLUGIN_REF=v1.1.1 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin all ``` 生产安装必须提供发布提交的 `PLUGIN_COMMIT_SHA`;上面的 `RELEASE_SHA` 应从受信任的发布记录中复制,并与 `PLUGIN_REF` 对应。脚本默认使用 -`v1.1.0` tag,但 tag 本身不作为完整性证明。可变分支和未 pin 的 tag +`v1.1.1` tag,但 tag 本身不作为完整性证明。可变分支和未 pin 的 tag 仅能在开发环境分别显式开启 `PLUGIN_ALLOW_MUTABLE_REF=true` 或 `PLUGIN_ALLOW_UNPINNED_TAG=true`。 +控制面回滚(保留旧 revision): + +在插件详情的“版本”页选择目标 revision 执行回滚。等价 API 请求为: + +```text +POST /api/plugins/{plugin_id}/rollback +X-CSRF-Token: +Idempotency-Key: +{"revision":""} +``` + +回滚会先健康检查目标 revision,成功后切换活动版本并更新菜单;失败时保留 +当前活动版本。external 插件回滚前仍须确保其 `service_url` 对应服务已运行。 + 默认卸载并保留配置/数据: ```sh diff --git a/deploy/README.md b/deploy/README.md index e8bed6c..663d76e 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -24,7 +24,7 @@ docker compose -f docker-compose.yml up -d ```sh RELEASE_SHA=COMMIT_SHA_40_HEX curl -fsSL "https://git.awaioi.com/awaioi/sub2api-add/raw/commit/${RELEASE_SHA}/deploy/install.sh" \ - | sudo env PLUGIN_REF=v1.1.0 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin all + | sudo env PLUGIN_REF=v1.1.1 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin all ``` 生产安装必须固定 `PLUGIN_COMMIT_SHA`,并从受信任的发布记录复制 @@ -42,7 +42,7 @@ curl -fsSL https://git.awaioi.com/awaioi/sub2api-add/raw/branch/main/deploy/inst ```sh RELEASE_SHA=COMMIT_SHA_40_HEX curl -fsSL "https://git.awaioi.com/awaioi/sub2api-add/raw/commit/${RELEASE_SHA}/deploy/install.sh" \ - | sudo env PLUGIN_REF=v1.1.0 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin plugin-admin + | sudo env PLUGIN_REF=v1.1.1 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin plugin-admin ``` 安装订阅插件: @@ -50,7 +50,7 @@ curl -fsSL "https://git.awaioi.com/awaioi/sub2api-add/raw/commit/${RELEASE_SHA}/ ```sh RELEASE_SHA=COMMIT_SHA_40_HEX curl -fsSL "https://git.awaioi.com/awaioi/sub2api-add/raw/commit/${RELEASE_SHA}/deploy/install.sh" \ - | sudo env PLUGIN_REF=v1.1.0 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin subscription-admin + | sudo env PLUGIN_REF=v1.1.1 PLUGIN_COMMIT_SHA="$RELEASE_SHA" bash -s -- --plugin subscription-admin ``` 默认安装位置: @@ -85,11 +85,28 @@ sudo systemctl restart sub2api-plugin-admin sub2api-subscription-admin 与 `127.0.0.1:8091`。 2. 登录 plugin-admin,上传业务插件包,或在插件市场选择目录版本。 3. 控制面完成签名、哈希和 Core 兼容性校验后,仅将包登记为“已入库,待启用”,不会启动进程。 -4. 配置业务插件的 loopback `service_url`,再点击启用;健康检查通过后才算安装完成。 +4. 对 external 业务插件,先由部署者启动对应后端,再配置 loopback `service_url`; + 对 command 插件,点击启用时控制面才会启动进程。两种模式都必须通过健康和 + 就绪检查后才算安装完成。 5. 预览、确认并应用插件声明的管理员菜单。 订阅插件是可选项;未安装或未应用菜单时,Core 管理员菜单不会出现“订阅管理”。 +## 版本回滚 + +Plugin Admin 会在升级时保留旧 revision。生产回滚建议在插件详情的“版本”页 +选择目标 revision;也可以调用下面的受保护 API(需要 Plugin Admin 会话的 +CSRF token 和唯一 `Idempotency-Key`): + +```text +POST /api/plugins/{plugin_id}/rollback +{"revision":""} +``` + +控制面会先启动并探测目标 revision,健康后再停止当前版本并原子切换注册表。 +探测失败不会替换当前活动版本。external 插件回滚前必须先确保目标版本的 +独立服务已经监听 `service_url`;command 插件由控制面负责启动和停止。 + ## 一键卸载 默认卸载服务和二进制,但保留配置与插件数据,便于重新安装: @@ -121,4 +138,6 @@ sudo ./deploy/uninstall.sh --plugin subscription-admin ``` 再次运行安装脚本会重新构建并重启选定插件。安装脚本发现源码有未提交修改 -时会中止,避免升级覆盖本地改动。 +时会中止,避免升级覆盖本地改动。该脚本从 pinned commit 构建控制面和示例 +业务后端;业务 `.s2plugin` 的生产签名由 `plugins/subscription-admin/package.sh` +和受信发布者密钥负责,Plugin Admin 不以 `.s2plugin` 归档交付。 diff --git a/deploy/install.sh b/deploy/install.sh index 4c929e8..3faba63 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -3,7 +3,7 @@ set -Eeuo pipefail REPO_URL=${PLUGIN_REPO_URL:-https://git.awaioi.com/awaioi/sub2api-add.git} SOURCE_DIR=${PLUGIN_SOURCE_DIR:-/opt/sub2api-add} -REF=${PLUGIN_REF:-v1.1.0} +REF=${PLUGIN_REF:-v1.1.1} EXPECTED_SHA=${PLUGIN_COMMIT_SHA:-} ALLOW_MUTABLE_REF=${PLUGIN_ALLOW_MUTABLE_REF:-false} DEPLOY_ENV=${PLUGIN_ENV:-production} @@ -22,10 +22,18 @@ validate_path_components() { [[ "$component" != "." && "$component" != ".." ]] || die "$label 不能包含 . 或 .. 路径组件" current="$current/$component" [[ ! -L "$current" ]] || die "$label 的路径组件不能是符号链接:$current" + [[ ! -e "$current" || -d "$current" ]] || die "$label 的路径组件不是目录:$current" done } +ensure_real_parent() { + local path=$1 label=$2 parent + parent=$(dirname -- "$path") + [[ -d "$parent" && ! -L "$parent" ]] || die "$label 的父目录必须是已存在的真实目录:$parent" +} + validate_path_components "$SOURCE_DIR" PLUGIN_SOURCE_DIR +ensure_real_parent "$SOURCE_DIR" PLUGIN_SOURCE_DIR if [[ "$SOURCE_DIR" != */sub2api-add && "${PLUGIN_ALLOW_CUSTOM_PATHS:-false}" != "true" ]]; then die "PLUGIN_SOURCE_DIR 必须以 sub2api-add 结尾;如确需自定义路径请显式设置 PLUGIN_ALLOW_CUSTOM_PATHS=true" fi @@ -57,6 +65,10 @@ if [[ -e "$SOURCE_DIR" && ! -d "$SOURCE_DIR/.git" ]]; then die "$SOURCE_DIR 已存在但不是本插件仓库;请设置 PLUGIN_SOURCE_DIR" fi +if [[ ! -e "$SOURCE_DIR" ]]; then + ensure_real_parent "$SOURCE_DIR" PLUGIN_SOURCE_DIR +fi + if [[ -d "$SOURCE_DIR/.git" ]]; then if [[ -n "$(git -C "$SOURCE_DIR" status --porcelain)" ]]; then die "$SOURCE_DIR 有未提交修改,先清理后再升级" diff --git a/deploy/uninstall.sh b/deploy/uninstall.sh index e4561a1..06ece84 100755 --- a/deploy/uninstall.sh +++ b/deploy/uninstall.sh @@ -22,12 +22,40 @@ validate_managed_root() { [[ "$component" != "." && "$component" != ".." ]] || die "$label 不能包含 . 或 .. 路径组件" current="$current/$component" [[ ! -L "$current" ]] || die "$label 的路径组件不能是符号链接:$current" + [[ ! -e "$current" || -d "$current" ]] || die "$label 的路径组件不是目录:$current" done if [[ "$value" != */sub2api-add && "${PLUGIN_ALLOW_CUSTOM_PATHS:-false}" != "true" ]]; then die "$label 必须位于受管的 sub2api-add 目录;如确需自定义路径请显式设置 PLUGIN_ALLOW_CUSTOM_PATHS=true" fi } +ensure_real_parent() { + local path=$1 label=$2 parent component current="" parts=() + parent=$(dirname -- "$path") + IFS='/' read -r -a parts <<< "${parent#/}" + for component in "${parts[@]}"; do + [[ -z "$component" ]] && continue + current="$current/$component" + [[ -d "$current" && ! -L "$current" ]] || die "$label 的父目录必须是已存在的真实目录:$current" + done +} + +ensure_real_dir() { + local path=$1 label=$2 component current="" parts=() + [[ -n "$path" && "$path" = /* ]] || die "$label 路径无效" + IFS='/' read -r -a parts <<< "${path#/}" + for component in "${parts[@]}"; do + [[ -z "$component" ]] && continue + current="$current/$component" + [[ -d "$current" && ! -L "$current" ]] || die "$label 必须是已存在的真实目录:$current" + done +} + +ensure_regular_target() { + local path=$1 label=$2 + [[ ! -L "$path" ]] || die "$label 不能是符号链接:$path" +} + die() { printf '错误:%s\n' "$*" >&2; exit 1; } [[ $EUID -eq 0 ]] || die "请使用 root 或 sudo 运行" command -v systemctl >/dev/null 2>&1 || die "缺少 systemd/systemctl" @@ -52,6 +80,11 @@ validate_managed_root "$ETC_DIR" PLUGIN_ETC_DIR validate_managed_root "$VAR_DIR" PLUGIN_VAR_DIR validate_managed_root "$PREFIX" PLUGIN_INSTALL_PREFIX validate_managed_root "$SOURCE_DIR" PLUGIN_SOURCE_DIR +ensure_real_parent "$ETC_DIR" PLUGIN_ETC_DIR +ensure_real_parent "$VAR_DIR" PLUGIN_VAR_DIR +ensure_real_parent "$PREFIX" PLUGIN_INSTALL_PREFIX +ensure_real_parent "$SOURCE_DIR" PLUGIN_SOURCE_DIR +ensure_real_dir /etc/systemd/system SYSTEMD_UNIT_DIR if $PURGE && [[ "${PLUGIN_PURGE_SOURCE:-true}" == "true" && "$SOURCE_DIR" != "$PREFIX" && "${PLUGIN_ALLOW_CUSTOM_PATHS:-false}" != "true" ]]; then die "为避免误删,--purge 默认要求 PLUGIN_SOURCE_DIR 与 PLUGIN_INSTALL_PREFIX 相同" fi @@ -64,28 +97,37 @@ fi for plugin in "${PLUGINS[@]}"; do unit="sub2api-$plugin.service" + unit_path="/etc/systemd/system/$unit" + if [[ -e "$unit_path" || -L "$unit_path" ]]; then + ensure_regular_target "$unit_path" SYSTEMD_UNIT + fi systemctl disable --now "$unit" 2>/dev/null || true - rm -f -- "/etc/systemd/system/$unit" + rm -f -- "$unit_path" # Keep the checked-out source clean so a later install can fast-forward it. # Only generated binaries are removed unless --purge is explicitly used. - rm -f -- "$PREFIX/$plugin/bin/$plugin" + if [[ -e "$PREFIX/$plugin/bin/$plugin" || -L "$PREFIX/$plugin/bin/$plugin" ]]; then + ensure_real_parent "$PREFIX/$plugin/bin/$plugin" PLUGIN_INSTALL_PREFIX + rm -f -- "$PREFIX/$plugin/bin/$plugin" + fi if $PURGE; then plugin_root="$PREFIX/$plugin" if [[ -d "$plugin_root" && ! -L "$plugin_root" ]]; then + ensure_real_parent "$plugin_root" PLUGIN_INSTALL_PREFIX rm -rf -- "${plugin_root:?}" fi rm -f -- "$ETC_DIR/$plugin.env" plugin_data="$VAR_DIR/$plugin" if [[ -d "$plugin_data" && ! -L "$plugin_data" ]]; then + ensure_real_parent "$plugin_data" PLUGIN_VAR_DIR rm -rf -- "${plugin_data:?}" fi fi done systemctl daemon-reload -if $PURGE && [[ -d "$ETC_DIR" ]]; then rmdir "$ETC_DIR" 2>/dev/null || true; fi -if $PURGE && [[ -d "$VAR_DIR" ]]; then rmdir "$VAR_DIR" 2>/dev/null || true; fi -if $PURGE && [[ "${PLUGIN_PURGE_SOURCE:-true}" == "true" && "$SOURCE_DIR" == "$PREFIX" && -d "$SOURCE_DIR" && ! -L "$SOURCE_DIR" ]]; then rm -rf -- "$SOURCE_DIR"; fi +if $PURGE && [[ -d "$ETC_DIR" && ! -L "$ETC_DIR" ]]; then rmdir "$ETC_DIR" 2>/dev/null || true; fi +if $PURGE && [[ -d "$VAR_DIR" && ! -L "$VAR_DIR" ]]; then rmdir "$VAR_DIR" 2>/dev/null || true; fi +if $PURGE && [[ "${PLUGIN_PURGE_SOURCE:-true}" == "true" && "$SOURCE_DIR" == "$PREFIX" && -d "$SOURCE_DIR" && ! -L "$SOURCE_DIR" ]]; then ensure_real_parent "$SOURCE_DIR" PLUGIN_SOURCE_DIR; rm -rf -- "$SOURCE_DIR"; fi if $PURGE; then userdel "$RUN_USER" 2>/dev/null || true diff --git a/docs/BUSINESS_PLUGIN_ACCEPTANCE.md b/docs/BUSINESS_PLUGIN_ACCEPTANCE.md index 1c45798..3e71655 100644 --- a/docs/BUSINESS_PLUGIN_ACCEPTANCE.md +++ b/docs/BUSINESS_PLUGIN_ACCEPTANCE.md @@ -12,7 +12,7 @@ | SEC-02 | 出站 | Core URL、重定向、代理和 SSRF | `TestHealthProbeRejectsRedirectAndRequiresReadiness`;loopback URL 校验 | passed | | SEC-02A | 市场出站 | 索引/归档 HTTPS、精确主机 allowlist、DNS 私网拒绝、体积和重定向门禁 | `main_test.go:TestRemoteMarketplaceRequiresAllowlistAndExpiry`;`marketplace.go` 出站策略 | passed | | SEC-03 | 脱敏 | Core 响应和错误 | token/password/secret/cookie 不出现在响应和日志 | passed | -| DEPLOY-01 | 发布完整性 | 生产安装提交 pin | `deploy/install.sh` 对 tag 要求 `PLUGIN_COMMIT_SHA`,并校验检出 commit;脚本可从 immutable commit URL 获取 | passed | +| DEPLOY-01 | 发布完整性 | 安装提交 pin | `deploy/install.sh` 对 tag 要求 `PLUGIN_COMMIT_SHA`,并校验检出 commit;脚本可从 immutable commit URL 获取 | passed (local) | | DEPLOY-02 | 路径安全 | 安装/卸载根目录与父路径 | 安装路径拒绝根目录、`.`/`..` 和任一级符号链接父路径 | passed | | MAN-01 | 清单 | 未知字段、尾随 JSON、路径跳转 | `plugins/plugin-admin/internal/manifest/manifest_test.go`;包上传 smoke | passed | | MAN-02 | 签名 | Ed25519、key ID、哈希 | `manifest_test.go:TestSignatureAndKeyID`;生产不受信发布者路径 | passed | @@ -41,7 +41,7 @@ go test ./... -count=1 go vet ./... node --check -production build +release build (signed `.s2plugin` for business packages) manifest verification bash -n git diff --check @@ -51,10 +51,10 @@ git diff --check ## 本轮证据 -- `plugins/plugin-admin` 和 `plugins/subscription-admin`:`go test -race ./...`、`go vet ./...`、`node --check ui/app.js` 均通过。 +- `plugins/plugin-admin` 和 `plugins/subscription-admin`:`go test -race ./...`、`go vet ./...`、`node --check ui/app.js` 均通过;`make check` 还覆盖 UI typecheck/build、全部 shell 语法和部署路径安全回归。 - `plugins/subscription-admin/package.sh` 生成的 `.s2plugin` 已通过 `unzip -t`,并通过控制面真实上传接口进入 `disabled` 状态。 - 本地浏览器登录后,控制面首页、插件市场和操作记录可访问;普通登录与 Turnstile 模拟登录在 425、900、1440 视口均通过,无横向溢出或敏感响应字段。 -- 仍需部署环境追加:真实生产签名密钥、跨实例共享会话、真实 Core iframe 刷新和跨节点升级演练;这些属于部署级验证,不改变本地 V1 控制面契约。 +- 仍需部署环境追加:真实生产签名密钥、发布归档/市场索引、跨实例共享会话、真实 Core iframe 刷新和跨节点升级演练;这些属于部署级门禁,不宣称已在本地完成,也不改变本地 V1 控制面契约。 浏览器脚本通过 `PLUGIN_SCREENSHOT_DIR` 输出 425px、900px、1440px 截图;本轮使用系统 Chrome 运行普通控制面、Turnstile fixture 和订阅模块三套验收,截图保留在本机临时证据目录。 @@ -65,4 +65,6 @@ git diff --check - `plugins/plugin-admin/main_test.go:TestPluginLockSerializesLifecycleMutations` 验证同一插件生命周期互斥。 - `plugins/plugin-admin/main_test.go:TestIdempotencyKeyRejectsDifferentOperationHash` 和 `TestIdempotencyKeyReplaysSameBodyAndRetainsFailedOperation` 验证服务端请求体指纹、失败终态保留与冲突拒绝。 - `plugins/plugin-admin/main_test.go:TestUpgradeDoesNotCarryEndpointAcrossServiceModes` 验证 command/external 模式不继承错误端点。 +- `tests/deploy-path-safety.sh` 验证安装、卸载和本地安装器拒绝符号链接父路径及缺失父目录,避免 root 操作越界。 +- `plugins/plugin-admin/main_test.go:TestRecoverCommandPluginAfterRestart` 使用有界 5 秒启动窗口,验证解释器型 command 插件在慢启动环境下仍可恢复,超时会清理进程。 - `go test -race ./... -count=1`、`go vet ./...`、全部 UI/测试脚本 `node --check`、包构建、`manifestcheck`、`unzip -t` 和 `git diff --check` 已通过。 diff --git a/plugins/plugin-admin/README.md b/plugins/plugin-admin/README.md index 920059e..a4dc289 100644 --- a/plugins/plugin-admin/README.md +++ b/plugins/plugin-admin/README.md @@ -24,12 +24,14 @@ PLUGIN_CONFIG_KEY=local-development-secret-at-least-32-chars \ go run . ``` -`PLUGIN_ALLOW_UNSIGNED=true` is a development-only switch. Production -packages must contain `signature.json`, use Ed25519, and match a trusted key -from `PLUGIN_TRUSTED_PUBLISHERS` (a JSON object of key ID to base64 public -key). `PLUGIN_CONFIG_KEY` is required in every environment; use a randomly -generated secret in production and keep it stable across restarts so encrypted -plugin configuration remains decryptable. +`PLUGIN_ALLOW_UNSIGNED=true` is a development-only switch for business package +uploads. Production `.s2plugin` packages must contain `signature.json`, use +Ed25519, and match a trusted key from `PLUGIN_TRUSTED_PUBLISHERS` (a JSON +object of key ID to base64 public key). Plugin Admin itself is deployed as a +pinned source checkout and binary, not as a `.s2plugin` package. `PLUGIN_CONFIG_KEY` +is required in every environment; use a randomly generated secret in production +and keep it stable across restarts so encrypted plugin configuration remains +decryptable. When the optional subscription module is enabled, set `PLUGIN_PUBLIC_URL` to the externally reachable Plugin Admin base URL (without `/admin`), for example diff --git a/plugins/plugin-admin/business-plugin-manifest.v1.json b/plugins/plugin-admin/business-plugin-manifest.v1.json index 1a1d6d1..b3d80b9 100644 --- a/plugins/plugin-admin/business-plugin-manifest.v1.json +++ b/plugins/plugin-admin/business-plugin-manifest.v1.json @@ -2,7 +2,7 @@ "schema_version": 1, "plugin_id": "qiu.plugin-admin", "name": "Business Plugin Control Plane", - "version": "1.1.0", + "version": "1.1.1", "core_api_baseline": "sub2api-0.1.183", "tested_core_versions": ["0.1.183"], "capabilities": ["plugin.admin.v1"], diff --git a/plugins/plugin-admin/main.go b/plugins/plugin-admin/main.go index e0ef4d4..62ee6c3 100644 --- a/plugins/plugin-admin/main.go +++ b/plugins/plugin-admin/main.go @@ -44,7 +44,7 @@ import ( const ( pluginID = "qiu.plugin-admin" subscriptionPluginID = "qiu.subscription-admin" - pluginVersion = "1.1.0" + pluginVersion = "1.1.1" sessionCookieName = "plugin_admin_session" maxJSONBytes = 2 << 20 maxPackageBytes = 128 << 20 @@ -2668,18 +2668,25 @@ func (a *app) startRevision(p *pluginRecord, revisionID, processKey string) (str probe.Endpoint = endpoint var probeErr error attempts := 1 + probeDelay := 50 * time.Millisecond + var startupDeadline time.Time if pluginManifest.Backend.Command != "" { - // A freshly spawned process can need a short interval before binding its - // port. Retry the probe within the bounded startup window. - attempts = 20 + // A freshly spawned interpreter-backed process can need several seconds + // before binding its port (notably on macOS under concurrent test load). + // Keep the window bounded while avoiding a fixed one-second flake. + attempts = 100 + startupDeadline = time.Now().Add(5 * time.Second) } for attempt := 0; attempt < attempts; attempt++ { + if !startupDeadline.IsZero() && time.Now().After(startupDeadline) { + break + } probeErr = a.checkPluginHealth(&probe) if probeErr == nil { break } - if attempt+1 < attempts { - time.Sleep(50 * time.Millisecond) + if attempt+1 < attempts && (startupDeadline.IsZero() || time.Now().Add(probeDelay).Before(startupDeadline)) { + time.Sleep(probeDelay) } } if probeErr != nil { diff --git a/plugins/plugin-admin/ui-vue/package-lock.json b/plugins/plugin-admin/ui-vue/package-lock.json index 8973dea..361fcc6 100644 --- a/plugins/plugin-admin/ui-vue/package-lock.json +++ b/plugins/plugin-admin/ui-vue/package-lock.json @@ -1,12 +1,12 @@ { "name": "@awaioi/plugin-admin-ui", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@awaioi/plugin-admin-ui", - "version": "1.1.0", + "version": "1.1.1", "dependencies": { "echarts": "^6.1.0", "pinia": "^3.0.4", diff --git a/plugins/plugin-admin/ui-vue/package.json b/plugins/plugin-admin/ui-vue/package.json index e7110ca..27a35d1 100644 --- a/plugins/plugin-admin/ui-vue/package.json +++ b/plugins/plugin-admin/ui-vue/package.json @@ -1,7 +1,7 @@ { "name": "@awaioi/plugin-admin-ui", "private": true, - "version": "1.1.0", + "version": "1.1.1", "type": "module", "scripts": { "dev": "vite --host 127.0.0.1 --port 3002", diff --git a/plugins/plugin-admin/ui-vue/src/layouts/Shell.vue b/plugins/plugin-admin/ui-vue/src/layouts/Shell.vue index 80aef1a..5390065 100644 --- a/plugins/plugin-admin/ui-vue/src/layouts/Shell.vue +++ b/plugins/plugin-admin/ui-vue/src/layouts/Shell.vue @@ -25,7 +25,7 @@ diff --git a/plugins/plugin-admin/ui/app.js b/plugins/plugin-admin/ui/app.js index 79e2525..ca32745 100644 --- a/plugins/plugin-admin/ui/app.js +++ b/plugins/plugin-admin/ui/app.js @@ -44,7 +44,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho ${M} ${e.mode===`push`?``:`width: calc(100% - ${t}px);`} } - `},N=function(){e.mode===`push`&&dn(function(){D.value&&(D.value.style.cssText=M)})},P=function(){if(!(!D.value||e.mode!==`push`)){var t={left:{name:`margin-left`,value:w.value},right:{name:`margin-left`,value:`-${w.value}`},top:{name:`margin-top`,value:w.value},bottom:{name:`margin-top`,value:`-${w.value}`}}[e.placement];r.value?D.value.style.setProperty(t.name,t.value):D.value.style.removeProperty(t.name)}},F=function(){var t=b({confirmBtn:e.confirmBtn,globalConfirm:o.value.confirm,className:`${u.value}__confirm`}),n=x({cancelBtn:e.cancelBtn,globalCancel:o.value.cancel,className:`${u.value}__cancel`});return V(`div`,{style:k.value},[e.placement===`right`?t:null,n,e.placement===`right`?null:t])},te=jm(`drawer`,{visible:g}).isTopInteractivePopup;R(O,N,{immediate:!0});var ne=function(t){if(t&&(_.value=!0),e.destroyOnClose){t?(n.value=!1,setTimeout(function(){return r.value=!0})):(r.value=!1,n.value&&=!1,_.value?setTimeout(function(){return n.value=!0},300):n.value=!0);return}if(n.value&&t){n.value=!1,setTimeout(function(){return r.value=!0});return}setTimeout(function(){return r.value=t})},re=function(){!e.showInAttachedElement&&e.preventScrollThrough&&r.value&&(_.value||!e.lazy)&&(i.value||ee(),i.value&&!document.head.contains(i.value)&&document.head.appendChild(i.value))};R(function(){return e.visible},function(t){if(!sp){if(t){var n;re(),(n=e.onBeforeOpen)==null||n.call(e)}else{var r;j(),(r=e.onBeforeClose)==null||r.call(e)}ne(t)}},{immediate:!0});var ie=function(t){var n;(n=e.onCloseBtnClick)==null||n.call(e,{e:t}),oe({trigger:`close-btn`,e:t})},ae=function(t){var n;(n=e.onOverlayClick)==null||n.call(e,{e:t}),(e.closeOnOverlayClick??o.value.closeOnOverlayClick)&&oe({trigger:`overlay`,e:t})},oe=function(n){var r;(r=e.onClose)==null||r.call(e,n),t.emit(`update:visible`,!1)};gr(P),mr(function(){re(),window.addEventListener(`keydown`,A)}),_r(function(){j(),window.removeEventListener(`keydown`,A)});var se=U(function(){return _.value?r.value||!n.value:e.destroyOnClose&&n.value?!1:!e.lazy});return function(){if(se.value){var n=l(`body`,`default`),r=c(`header`),i=F();return V(Ln,{disabled:!e.attach||!v.value,to:v.value},{default:function(){return[V(`div`,H({ref:S,class:C.value,style:{zIndex:e.zIndex},onKeydown:A,tabindex:0},t.attrs),[e.showOverlay&&V(`div`,{class:`${u.value}__mask`,onClick:ae},null),V(`div`,{class:E.value,style:VL(VL({},T.value),h.value)},[r&&V(`div`,{class:`${u.value}__header`},[r]),e.closeBtn&&V(`div`,{class:`${u.value}__close-btn`,onClick:ie},[c(`closeBtn`,V(s,null,null))]),V(`div`,{class:[`${u.value}__body`,`narrow-scrollbar`]},[n]),e.footer&&V(`div`,{class:`${u.value}__footer`},[c(`footer`,i)]),e.sizeDraggable&&V(`div`,{style:m.value,onMousedown:p},null)])])]}})}}}});function WL(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function GL(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:document.body,n=Sp(),r=n.scrollTop,i=n.scrollLeft,a=e.getBoundingClientRect(),o=a.top,s=a.left,c=t.getBoundingClientRect(),l=c.top,u=c.left,d=bp(t,`position`);return t.tagName.toLowerCase()!==`body`&&d===`relative`||d===`sticky`?{top:o-l,left:s-u}:xp(e)?{top:o,left:s}:{top:o+r,left:s+i}}function $L(e){if(e){var t,n=null;if(Rd(e))n=document.querySelector(e);else if(q(e))n=e();else throw Error(`elm should be string or function`);if(n)return n;if(((t=process)==null||(t=t.env)==null?void 0:t.NODE_ENV)!==`test`)throw Error(`There is no element with given.`)}else return document.body}function eR(e){var t=e.getBoundingClientRect();if(!yp(e)){var n=uoe().height;_p(t.top-(n/2-t.height/2),{})}}var tR=X(z({name:`TGuide`,props:YL,setup:function(e,t){var n=pm(),r=Q(`guide`),i=Q(`guide--lock`),a=Rp(`guide`).globalConfig,o=Wt(e),s=o.current,c=o.modelValue,l=o.hideCounter,u=o.hidePrev,d=o.hideSkip,f=o.steps,p=o.zIndex,m=Y(Rm(s,c,e.defaultCurrent,e.onChange,`current`),2),h=m[0],g=m[1],_=I(),v=I(),y=I(),b=I(),x=I(),S=I(),C=I(),w=I(!1),T=U(function(){return f.value.length}),E=U(function(){return f.value[h.value]}),D=U(function(){return k(`mode`)===`popup`}),O=U(function(){return xp(b.value||document.body)}),k=function(t){return E.value[t]??e[t]},A=U(function(){var e=E.value.highlightContent,n=e;return q(e)?n=e(ee()):t.slots.highlightContent?n=t.slots.highlightContent(ee()):t.slots[`highlight-content`]?n=t.slots[`highlight-content`](ee()):e&&(n=V(n,null,null)),n&&(n.props||={},n.props.class=n.props.class||``),n}),j=U(function(){return!!(A.value&&D.value)}),M=I(!1),ee=function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{currentStepInfo:E.value},t=Function(`return `+sa.toString())();return Object.assign({},t,e)},N=function(e){var t=arguments.length>1&&arguments[1]!==void 0&&arguments[1],n=QL(b.value),r=n.top,i=n.left,a=b.value.getBoundingClientRect(),o=a.width,s=a.height,c=k(`highlightPadding`);if(D.value)o+=c*2,s+=c*2,r-=c,i-=c;else{var l=Sp(),u=l.scrollTop,d=l.scrollLeft;r+=u,i+=d}var f={top:`${r}px`,left:`${i}px`};if(j.value)if(t){var p=v.value.getBoundingClientRect(),m=p.width,h=p.height;Object.assign(f,{width:`${m}px`,height:`${h}px`})}else Object.assign(f,{width:`auto`,height:`auto`});else Object.assign(f,{width:`${o}px`,height:`${s}px`});Pm(e,f)},P=function(){dn(function(){var e;b.value=$L(E.value.element),b.value&&(ZL(b.value),N(v.value),N(y.value,!0),eR(b.value),(e=C.value)==null||e.update())})},F=function(){var e;(e=y.value)==null||e.parentNode.removeChild(y.value)},te=function(){dn(function(){b.value=S.value,ZL(b.value),N(v.value),eR(b.value)})},ne=function(){var e,t;(e=S.value)==null||e.parentNode.removeChild(S.value),(t=x.value)==null||t.parentNode.removeChild(x.value)},re=function(){D.value?(ne(),P()):(F(),te()),M.value=!0};Om(function(){M.value&&re()},!sp&&document.body);var ie=function(){var e,t;F(),ne(),(e=v.value)==null||e.parentNode.removeChild(v.value),(t=_.value)==null||t.parentNode.removeChild(_.value),fp(document.body,i.value)},ae=function(t){var n,r=T.value;w.value=!1,g(-1,{e:t,total:r}),(n=e.onSkip)==null||n.call(e,{e:t,current:h.value,total:r})},oe=function(t){var n,r=T.value;g(h.value-1,{e:t,total:r}),(n=e.onPrevStepClick)==null||n.call(e,{e:t,prev:h.value-1,current:h.value,total:r})},se=function(t){var n,r=T.value;g(h.value+1,{e:t,total:r}),(n=e.onNextStepClick)==null||n.call(e,{e:t,next:h.value+1,current:h.value,total:r})},ce=function(t){var n,r=T.value;w.value=!1,g(-1,{e:t,total:r}),(n=e.onFinish)==null||n.call(e,{e:t,current:h.value,total:r})},le=function(){h.value>=0&&h.value=0&&e-1}}},setup:function(e,t){var n=t.expose,r=Q(`notification-list`),i=e.placement,a=e.offset,o=I([]),s=I([]),c=U(function(){var e=_R({zIndex:iR},oR[i]);if(Array.isArray(a)&&a.length===2){var t=i.includes(`left`)?`left`:`right`,n=i.includes(`top`)?`top`:`bottom`;e[t]=f(a[0])??e[t],e[n]=f(a[1])??e[n]}return e}),l=function(e){return o.value.push(e),o.value.length-1},u=function(e){o.value.splice(e,1)},d=function(){o.value=[]},f=function(e){if(e)return isNaN(Number(e))?e:`${e}px`},p=function(e){var t={marginBottom:aR};return e.zIndex&&(t[`z-index`]=e.zIndex),t},m=function(e,t){return _R(_R({},t),{},{onCloseBtnClick:function(n){return t.onCloseBtnClick&&t.onCloseBtnClick(n),u(e)},onDurationEnd:function(){return t.onDurationEnd&&t.onDurationEnd(),u(e)},onClose:function(){return t.onClose&&t.onClose(),u(e)}})},h=function(e){e&&s.value.push(e)};return n({add:l,remove:u,removeAll:d,list:o,notificationList:s}),function(){if(o.value.length)return V(`div`,{class:`${r.value}__show`,style:c.value},[o.value.map(function(e,t){return V(hR,H({ref:h,key:e.id,style:p(e)},m(t,e)),null)})])}}});function yR(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function bR(e){for(var t=1;t1?`${m}[${t}]`:m;k[n]=e.raw}),C.length===1?k[m]=C[0].raw:k[m]=C.map(function(e){return e.raw}),k.length=C.length,y&&(k=y(k));var j=new FormData;return Object.keys(k).forEach(function(e){var t=k[e];Array.isArray(t)?t.forEach(function(t){j.append(e,t)}):j.append(e,t)}),T.open(n,r,!0),Object.keys(s).forEach(function(e){T.setRequestHeader(e,s[e])}),T.onerror=function(e){b({event:e,file:u,files:C,XMLHttpRequest:T}),clearInterval(E),clearTimeout(D)},T.ontimeout=function(e){b({event:e,file:u,files:C,XMLHttpRequest:T})},T.upload&&(T.upload.onprogress=function(e){var t=0;if(e.total>0&&(t=Math.round(e.loaded/e.total*100)),w=Math.max(t,w),w!==t&&C[0]?.percent!==w){var n=C.map(function(e){return ez(ez({},e),{},{percent:w})});x({event:e,percent:w,file:u||n[0],files:n,type:`real`,XMLHttpRequest:T})}}),T.onload=function(e){var t={};if(t.XMLHttpRequest=T,T.status<200||T.status>=300)return b({event:e,file:u,files:C,response:t,XMLHttpRequest:T});var n=T.responseText||T.response;try{t=JSON.parse(n)}catch{t=n,Vp.error(`Upload`,`response does not a valid json`)}clearInterval(E),clearTimeout(D),C.forEach(function(e){e.percent=100,e.status=`success`,e.uploadTime=t?.uploadTime||Gp()}),so(t)===`object`&&(t.XMLHttpRequest=T),S({event:e,file:u||C[0],files:W(C),XMLHttpRequest:T,response:t})},T.send(j),T.upload.requestParams=k,T.upload.requestHeaders=s,T}function nz(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function rz(e){for(var t=1;t=0?rz(rz({},e[a]),r):r;n.push(o)},i=0,a=t.length;i2&&arguments[2]!==void 0?arguments[2]:void 0,r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0;return e.map(function(e){var i=e;return q(t)&&(i=t(e)),rz({raw:e,lastModified:e.lastModified,name:e.name,size:e.size,type:e.type,percent:r,status:n},i)})}function fz(e){var t=e.files,n=e.uploadValue,r=e.max,i=e.allowUploadDuplicateFile,a=e.capture,o=a===void 0?``:a;return new Promise(function(a){var s=t.filter(function(e){return i||o?!0:!n.find(function(t){return t.name===e.name})}),c=!1;if(s.lengthr&&(u=!0)}var f=dz(s,e.format,e.autoUpload?`progress`:`waiting`),p;if(e.beforeAllFilesUpload){var m=e.beforeAllFilesUpload?.call(e,f);p=m instanceof Promise?m:new Promise(function(e){e(m)})}var h=f.map(function(t){return new Promise(function(n){iz(t,{beforeUpload:e.beforeUpload,sizeLimit:e.sizeLimit}).then(function(e){var r=Y(e,2),i=r[0],a=r[1];i?n({file:t,validateResult:{type:`FILE_OVER_SIZE_LIMIT`,extra:i}}):a===!1&&n({file:t,validateResult:{type:`CUSTOM_BEFORE_UPLOAD`}}),n({file:t})})})});Promise.all([p].concat(h)).then(function(e){var t=yF(e),n=t[0],r=t.slice(1);a(n===!1?{lengthOverLimit:u,hasSameNameFile:c,validateResult:{type:`BEFORE_ALL_FILES_UPLOAD`},files:f}:{lengthOverLimit:u,hasSameNameFile:c,fileValidateList:r,files:f})})})}function pz(e,t){var n=[],r=[],i=[];return e.forEach(function(e){if(e.validateResult?.type===`CUSTOM_BEFORE_UPLOAD`){r.push(e.file);return}if(e.validateResult?.type===`FILE_OVER_SIZE_LIMIT`){e.file.response||(e.file.response={}),e.file.response.error=e.file.response.error||t(e.validateResult.extra),n.push(e);return}i.push(e.file)}),{sizeLimitErrors:n,beforeUploadErrorFiles:r,toFiles:i}}function mz(e){return e.isBatchUpload&&e.status||e.status===`fail`?`reupload`:e.status===`progress`?`uploading`:e.status===`success`||!e.autoUpload&&e.status===`waiting`?e.multiple?`continueUpload`:`reupload`:`fileInput`}function hz(e){var t=e.multiple,n=e.uploadValue,r=e.toUploadFiles,i=e.autoUpload,a=i?r:r.filter(function(e){return e.status!==`success`});return t&&!e.isBatchUpload?i?(a.length?n.concat(a):n)||[]:n:(a.length?a:n)||[]}function gz(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _z(e){for(var t=1;t{},Mz=Array.isArray;function Nz(e,t){let n={};for(let r in e)n[r]=r in t?t[r]:e[r];return n}var Pz=Symbol(``);function Fz(e,t){return kz(Error(),{type:e,[Pz]:!0},t)}function Iz(e,t){return e instanceof Error&&Pz in e&&(t==null||!!(e.type&t))}var Lz=Symbol(``),Rz=Symbol(``),zz=Symbol(``),Bz=Symbol(``),Vz=Symbol(``);function Hz(){return wn(zz)}function Uz(e){return wn(Bz)}var Wz=/#/g,Gz=/&/g,Kz=/\//g,qz=/=/g,Jz=/\?/g,Yz=/\+/g,Xz=/%5B/g,Zz=/%5D/g,Qz=/%5E/g,$z=/%60/g,eB=/%7B/g,tB=/%7C/g,nB=/%7D/g,rB=/%20/g;function iB(e){return e==null?``:encodeURI(``+e).replace(tB,`|`).replace(Xz,`[`).replace(Zz,`]`)}function aB(e){return iB(e).replace(eB,`{`).replace(nB,`}`).replace(Qz,`^`)}function oB(e){return iB(e).replace(Yz,`%2B`).replace(rB,`+`).replace(Wz,`%23`).replace(Gz,`%26`).replace($z,"`").replace(eB,`{`).replace(nB,`}`).replace(Qz,`^`)}function sB(e){return oB(e).replace(qz,`%3D`)}function cB(e){return iB(e).replace(Wz,`%23`).replace(Jz,`%3F`)}function lB(e){return cB(e).replace(Kz,`%2F`)}function uB(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var dB=/\/$/,fB=e=>e.replace(dB,``);function pB(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=xB(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:uB(o)}}function mB(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function hB(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function gB(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&_B(t.matched[r],n.matched[i])&&vB(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function _B(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function vB(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!yB(e[n],t[n]))return!1;return!0}function yB(e,t){return Mz(e)?bB(e,t):Mz(t)?bB(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function bB(e,t){return Mz(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function xB(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var SB={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function CB(e){if(!e)if(Ez){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),fB(e)}var wB=/^[^#]+#/;function TB(e,t){return e.replace(wB,`#`)+t}function EB(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var DB=()=>({left:window.scrollX,top:window.scrollY});function OB(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=EB(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function kB(e,t){return(history.state?history.state.position-t:-1)+e}var AB=new Map;function jB(e,t){AB.set(e,t)}function MB(e){let t=AB.get(e);return AB.delete(e),t}function NB(e){return typeof e==`string`||e&&typeof e==`object`}function PB(e){return typeof e==`string`||typeof e==`symbol`}function FB(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;ee&&oB(e)):[r&&oB(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function LB(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=Mz(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function RB(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function zB(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(Fz(4,{from:n,to:t})):e instanceof Error?c(e):NB(e)?c(Fz(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function BB(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(Dz(s)){let c=(s.__vccOpts||s)[t];c&&a.push(zB(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=Oz(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&zB(c,n,r,o,e,i)()}))}}return a}function VB(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o_B(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>_B(e,s))||i.push(s))}return[n,r,i]}var HB=()=>location.protocol+`//`+location.host;function UB(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),hB(n,``)}return hB(n,e)+r+i}function WB(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=UB(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(kz({},e.state,{scroll:DB()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function GB(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?DB():null}}function KB(e){let{history:t,location:n}=window,r={value:UB(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:HB()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,kz({},t.state,GB(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=kz({},i.value,t.state,{forward:e,scroll:DB()});a(o.current,o,!0),a(e,kz({},GB(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function qB(e){e=CB(e);let t=KB(e),n=WB(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=kz({location:``,base:e,go:r,createHref:TB.bind(null,e)},t,n);return Object.defineProperty(i,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,"state",{enumerable:!0,get:()=>t.state.value}),i}function JB(e){return e=location.host?e||location.pathname+location.search:``,e.includes(`#`)||(e+=`#`),qB(e)}var YB={type:0,value:``},XB=/[a-zA-Z0-9_]/;function ZB(e){if(!e)return[[]];if(e===`/`)return[[YB]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;st.length?t.length===1&&t[0]===80?1:-1:0}function rV(e,t){let n=0,r=e.score,i=t.score;for(;n0&&t[t.length-1]<0}var aV={strict:!1,end:!0,sensitive:!1};function oV(e,t,n){let r=kz(tV(ZB(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function sV(e,t){let n=[],r=new Map;t=Nz(aV,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=lV(e);s.aliasOf=r&&r.record;let l=Nz(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(lV(kz({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=oV(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!dV(d)&&o(e.name)),hV(d)&&c(d),s.children){let e=s.children;for(let t=0;t{o(f)}:jz}function o(e){if(PB(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=pV(e,n);n.splice(t,0,e),e.record.name&&!dV(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw Fz(1,{location:e});s=i.record.name,a=kz(cV(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&cV(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw Fz(1,{location:e,currentLocation:t});s=i.record.name,a=kz({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:fV(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function cV(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function lV(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:uV(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function uV(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function dV(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function fV(e){return e.reduce((e,t)=>kz(e,t.meta),{})}function pV(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;rV(e,t[i])<0?r=i:n=i+1}let i=mV(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function mV(e){let t=e;for(;t=t.parent;)if(hV(t)&&rV(e,t)===0)return t}function hV({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function gV(e){let t=wn(zz),n=wn(Bz),r=U(()=>{let n=Ht(e.to);return t.resolve(n)}),i=U(()=>{let{matched:e}=r.value,{length:t}=e,i=e[t-1],a=n.matched;if(!i||!a.length)return-1;let o=a.findIndex(_B.bind(null,i));if(o>-1)return o;let s=xV(e[t-2]);return t>1&&xV(i)===s&&a[a.length-1].path!==s?a.findIndex(_B.bind(null,e[t-2])):o}),a=U(()=>i.value>-1&&bV(n.params,r.value.params)),o=U(()=>i.value>-1&&i.value===n.matched.length-1&&vB(n.params,r.value.params));function s(n={}){if(yV(n)){let n=t[Ht(e.replace)?`replace`:`push`](Ht(e.to)).catch(jz);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:r,href:U(()=>r.value.href),isActive:a,isExactActive:o,navigate:s}}function _V(e){return e.length===1?e[0]:e}var vV=z({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:gV,setup(e,{slots:t}){let n=Dt(gV(e)),{options:r}=wn(zz),i=U(()=>({[SV(e.activeClass,r.linkActiveClass,`router-link-active`)]:n.isActive,[SV(e.exactActiveClass,r.linkExactActiveClass,`router-link-exact-active`)]:n.isExactActive}));return()=>{let r=t.default&&_V(t.default(n));return e.custom?r:sa(`a`,{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:i.value},r)}}});function yV(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function bV(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!Mz(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function xV(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var SV=(e,t,n)=>e??t??n,CV=z({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){let r=wn(Vz),i=U(()=>e.route||r.value),a=wn(Rz,0),o=U(()=>{let e=Ht(a),{matched:t}=i.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),s=U(()=>i.value.matched[o.value]);Cn(Rz,U(()=>o.value+1)),Cn(Lz,s),Cn(Vz,i);let c=I();return R(()=>[c.value,s.value,e.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!_B(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let r=i.value,a=e.name,o=s.value,l=o&&o.components[a];if(!l)return wV(n.default,{Component:l,route:r});let u=o.props[a],d=sa(l,kz({},u?u===!0?r.params:typeof u==`function`?u(r):u:null,t,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(o.instances[a]=null)},ref:c}));return wV(n.default,{Component:d,route:r})||d}}});function wV(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var TV=CV;function EV(e){let t=sV(e.routes,e),n=e.parseQuery||FB,r=e.stringifyQuery||IB,i=e.history,a=RB(),o=RB(),s=RB(),c=Bt(SB),l=SB;Ez&&e.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let u=Az.bind(null,e=>``+e),d=Az.bind(null,lB),f=Az.bind(null,uB);function p(e,n){let r,i;return PB(e)?(r=t.getRecordMatcher(e),i=n):i=e,t.addRoute(i,r)}function m(e){let n=t.getRecordMatcher(e);n&&t.removeRoute(n)}function h(){return t.getRoutes().map(e=>e.record)}function g(e){return!!t.getRecordMatcher(e)}function _(e,a){if(a=kz({},a||c.value),typeof e==`string`){let r=pB(n,e,a.path),o=t.resolve({path:r.path},a),s=i.createHref(r.fullPath);return kz(r,o,{params:f(o.params),redirectedFrom:void 0,href:s})}let o;if(e.path!=null)o=kz({},e,{path:pB(n,e.path,a.path).path});else{let t=kz({},e.params);for(let e in t)t[e]??delete t[e];o=kz({},e,{params:d(t)}),a.params=d(a.params)}let s=t.resolve(o,a),l=e.hash||``;s.params=u(f(s.params));let p=mB(r,kz({},e,{hash:aB(l),path:s.path})),m=i.createHref(p);return kz({fullPath:p,hash:l,query:r===IB?LB(e.query):e.query||{}},s,{redirectedFrom:void 0,href:m})}function v(e){return typeof e==`string`?pB(n,e,c.value.path):kz({},e)}function y(e,t){if(l!==e)return Fz(8,{from:t,to:e})}function b(e){return C(e)}function x(e){return b(kz(v(e),{replace:!0}))}function S(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=v(i):{path:i},i.params={}),kz({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function C(e,t){let n=l=_(e),i=c.value,a=e.state,o=e.force,s=e.replace===!0,u=S(n,i);if(u)return C(kz(v(u),{state:typeof u==`object`?kz({},a,u.state):a,force:o,replace:s}),t||n);let d=n;d.redirectedFrom=t;let f;return!o&&gB(r,i,n)&&(f=Fz(16,{to:d,from:i}),te(i,i,!0,!1)),(f?Promise.resolve(f):E(d,i)).catch(e=>Iz(e)?Iz(e,2)?e:F(e):N(e,d,i)).then(e=>{if(e){if(Iz(e,2))return C(kz({replace:s},v(e.to),{state:typeof e.to==`object`?kz({},a,e.to.state):a,force:o}),t||d)}else e=O(d,i,!0,s,a);return D(d,i,e),e})}function w(e,t){let n=y(e,t);return n?Promise.reject(n):Promise.resolve()}function T(e){let t=ie.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function E(e,t){let n,[r,i,s]=VB(e,t);n=BB(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push(zB(r,e,t))});let c=w.bind(null,e,t);return n.push(c),oe(n).then(()=>{n=[];for(let r of a.list())n.push(zB(r,e,t));return n.push(c),oe(n)}).then(()=>{n=BB(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push(zB(r,e,t))});return n.push(c),oe(n)}).then(()=>{n=[];for(let r of s)if(r.beforeEnter)if(Mz(r.beforeEnter))for(let i of r.beforeEnter)n.push(zB(i,e,t));else n.push(zB(r.beforeEnter,e,t));return n.push(c),oe(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=BB(s,`beforeRouteEnter`,e,t,T),n.push(c),oe(n))).then(()=>{n=[];for(let r of o.list())n.push(zB(r,e,t));return n.push(c),oe(n)}).catch(e=>Iz(e,8)?e:Promise.reject(e))}function D(e,t,n){s.list().forEach(r=>T(()=>r(e,t,n)))}function O(e,t,n,r,a){let o=y(e,t);if(o)return o;let s=t===SB,l=Ez?history.state:{};n&&(r||s?i.replace(e.fullPath,kz({scroll:s&&l&&l.scroll},a)):i.push(e.fullPath,a)),c.value=e,te(e,t,n,s),F()}let k;function A(){k||=i.listen((e,t,n)=>{if(!ae.listening)return;let r=_(e),a=S(r,ae.currentRoute.value);if(a){C(kz(a,{replace:!0,force:!0}),r).catch(jz);return}l=r;let o=c.value;Ez&&jB(kB(o.fullPath,n.delta),DB()),E(r,o).catch(e=>Iz(e,12)?e:Iz(e,2)?(C(kz(v(e.to),{force:!0}),r).then(e=>{Iz(e,20)&&!n.delta&&n.type===`pop`&&i.go(-1,!1)}).catch(jz),Promise.reject()):(n.delta&&i.go(-n.delta,!1),N(e,r,o))).then(e=>{e||=O(r,o,!1),e&&(n.delta&&!Iz(e,8)?i.go(-n.delta,!1):n.type===`pop`&&Iz(e,20)&&i.go(-1,!1)),D(r,o,e)}).catch(jz)})}let j=RB(),M=RB(),ee;function N(e,t,n){F(e);let r=M.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function P(){return ee&&c.value!==SB?Promise.resolve():new Promise((e,t)=>{j.add([e,t])})}function F(e){return ee||(ee=!e,A(),j.list().forEach(([t,n])=>e?n(e):t()),j.reset()),e}function te(t,n,r,i){let{scrollBehavior:a}=e;if(!Ez||!a)return Promise.resolve();let o=!r&&MB(kB(t.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return dn().then(()=>a(t,n,o)).then(e=>e&&OB(e)).catch(e=>N(e,t,n))}let ne=e=>i.go(e),re,ie=new Set,ae={currentRoute:c,listening:!0,addRoute:p,removeRoute:m,clearRoutes:t.clearRoutes,hasRoute:g,getRoutes:h,resolve:_,options:e,push:b,replace:x,go:ne,back:()=>ne(-1),forward:()=>ne(1),beforeEach:a.add,beforeResolve:o.add,afterEach:s.add,onError:M.add,isReady:P,install(e){e.component(`RouterLink`,vV),e.component(`RouterView`,TV),e.config.globalProperties.$router=ae,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>Ht(c)}),Ez&&!re&&c.value===SB&&(re=!0,b(i.location).catch(e=>{}));let t={};for(let e in SB)Object.defineProperty(t,e,{get:()=>c.value[e],enumerable:!0});e.provide(zz,ae),e.provide(Bz,Ot(t)),e.provide(Vz,c);let n=e.unmount;ie.add(e),e.unmount=function(){ie.delete(e),ie.size<1&&(l=SB,k&&k(),k=null,c.value=SB,re=!1,ee=!1),n()}}};function oe(e){return e.reduce((e,t)=>e.then(()=>T(t)),Promise.resolve())}return ae}var DV=Dt({ready:!1,user:null,csrf:``,pendingToken:``}),OV=Dt({subscriptionEnabled:!1,loaded:!1,loading:!1}),kV=()=>(document.querySelector(`meta[name="plugin-base-path"]`)?.getAttribute(`content`)||``).replace(/\/$/,``),AV=class extends Error{status;constructor(e,t=0){super(e),this.name=`ApiError`,this.status=t}};async function jV(e,t={}){let n=new Headers(t.headers||{});n.set(`Accept`,`application/json`);let r=(t.method||`GET`).toUpperCase();t.body&&!(t.body instanceof FormData)&&n.set(`Content-Type`,`application/json`),DV.csrf&&r!==`GET`&&n.set(`X-CSRF-Token`,DV.csrf);let i=await fetch(`${kV()}${e}`,{...t,method:r,headers:n,credentials:`same-origin`}),a=await i.json().catch(()=>({}));if(!i.ok)throw i.status===401&&!e.startsWith(`/login`)&&(DV.user=null,DV.csrf=``),new AV(a?.error||`请求失败 (${i.status})`,i.status);return a}async function MV(){try{let e=await jV(`/api/me`);DV.user=e.user||null,DV.csrf=e.csrf_token||``}catch{DV.user=null,DV.csrf=``,OV.loaded=!1,OV.subscriptionEnabled=!1}finally{DV.ready=!0}}async function NV(){let e=await jV(`/api/captcha-config`);return{enabled:e.enabled===!0,provider:e.provider||``,turnstile_enabled:e.turnstile_enabled===!0,turnstile_site_key:String(e.turnstile_site_key||``),tencent_captcha_enabled:e.tencent_captcha_enabled===!0,tencent_captcha_app_id:String(e.tencent_captcha_app_id||``),tencent_captcha_region:String(e.tencent_captcha_region||`cn`),aliyun_captcha_enabled:e.aliyun_captcha_enabled===!0,aliyun_captcha_scene_id:String(e.aliyun_captcha_scene_id||``),aliyun_captcha_prefix:String(e.aliyun_captcha_prefix||``),aliyun_captcha_region:String(e.aliyun_captcha_region||`cn`)}}async function PV(e=!1){if(OV.loaded&&!e)return OV.subscriptionEnabled;if(OV.loading)return await new Promise(e=>{let t=window.setInterval(()=>{OV.loading||(window.clearInterval(t),e())},20)}),OV.subscriptionEnabled;OV.loading=!0;try{OV.subscriptionEnabled=(RV(await jV(`/api/subscription/status`))||{}).enabled===!0}catch{OV.subscriptionEnabled=!1}finally{OV.loaded=!0,OV.loading=!1}return OV.subscriptionEnabled}async function FV(e,t,n={}){let r=await jV(`/login`,{method:`POST`,body:JSON.stringify({email:e,password:t,...n})});return r.requires_2fa?(DV.pendingToken=r.pending_token||``,{requires2fa:!0}):(DV.pendingToken=``,DV.user=r.user||null,DV.csrf=r.csrf_token||``,OV.loaded=!1,{requires2fa:!1})}async function IV(e){let t=await jV(`/login/2fa`,{method:`POST`,body:JSON.stringify({pending_token:DV.pendingToken,totp_code:e})});DV.pendingToken=``,DV.user=t.user||null,DV.csrf=t.csrf_token||``,OV.loaded=!1}async function LV(){try{await jV(`/logout`,{method:`POST`})}finally{DV.user=null,DV.csrf=``,DV.pendingToken=``,OV.loaded=!1,OV.subscriptionEnabled=!1}}function RV(e){return e&&Object.prototype.hasOwnProperty.call(e,`data`)&&(`code`in e||`message`in e)?e.data:e}function zV(e){let t=RV(e);return Array.isArray(t)?t:Array.isArray(t?.items)?t.items:Array.isArray(t?.list)?t.list:Array.isArray(t?.rows)?t.rows:[]}function BV(e){if(!e)return`-`;let t=new Date(String(e));return Number.isNaN(t.getTime())?String(e):t.toLocaleString(`zh-CN`,{hour12:!1})}function VV(e){return{healthy:`运行中`,enabled:`运行中`,disabled:`已停用`,incompatible:`Core 不兼容`,error:`启用失败`,starting:`启动中`,draining:`停用中`,upgrading:`升级中`,rollback_pending:`等待回滚`}[String(e)]||String(e||`未知`)}function HV(e){return[`completed`,`success`,`succeeded`].includes(String(e||``).toLowerCase())}function UV(e){let t=String(e||``).toLowerCase();return HV(t)?`success`:t===`failed`||t===`error`?`danger`:`warning`}function WV(e,t=``){return`${e}-${t}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var GV={class:`brand`},KV={class:`brand-mark`},qV={class:`aside-footer`},JV={class:`header-left`},YV={class:`breadcrumbs`},XV={class:`header-right`},ZV={class:`user-name`},QV=z({__name:`Shell`,setup(e){let t=Uz(),n=Hz(),r=I(!1),i=U(()=>OV.subscriptionEnabled),a=U(()=>String(t.meta.title||(t.path.startsWith(`/modules/subscription`)?`订阅管理`:`概览`))),o=U(()=>t.path.startsWith(`/plugins`)?`/plugins`:t.path.startsWith(`/modules/subscription`)?`/modules/subscription/overview`:t.path),s=U(()=>String(DV.user?.email||DV.user?.username||`管理员`)),c=[{content:`退出登录`,value:`logout`}];async function l(){await PV(!0)}function u(e){let t=String(e);if(t===`/modules/subscription/overview`&&!i.value){eb.warning(`请先安装并启用订阅模块`);return}n.push(t),r.value=!1}async function d(e){String(e?.value||``)===`logout`&&(await LV(),n.push(`/login`))}return mr(l),(e,t)=>{let n=br(`t-menu-item`),l=br(`t-divider`),f=br(`t-menu`),p=br(`t-tag`),m=br(`t-aside`),h=br(`t-button`),g=br(`t-dropdown`),_=br(`t-header`),v=br(`router-view`),y=br(`t-content`),b=br(`t-layout`);return Ei(),ji(b,{class:`app-shell`},{default:L(()=>[r.value?(Ei(),Ai(`div`,{key:0,class:`mobile-scrim`,onClick:t[0]||=e=>r.value=!1})):Bi(``,!0),V(m,{class:de([`app-aside`,{"app-aside-mobile-open":r.value}]),width:`252px`},{default:L(()=>[B(`div`,GV,[B(`div`,KV,[V(Ht(Pg),{size:`22px`})]),t[2]||=B(`div`,null,[B(`div`,{class:`brand-title`},`Sub2API`),B(`div`,{class:`brand-subtitle`},`插件控制面`)],-1)]),t[11]||=B(`div`,{class:`nav-caption`},`控制台`,-1),V(f,{value:o.value,class:`main-menu`,onChange:u},{default:L(()=>[V(n,{value:`/overview`},{icon:L(()=>[V(Ht(pce))]),default:L(()=>[t[3]||=zi(`概览`,-1)]),_:1}),V(n,{value:`/plugins`},{icon:L(()=>[V(Ht(Oh))]),default:L(()=>[t[4]||=zi(`已安装插件`,-1)]),_:1}),V(n,{value:`/marketplace`},{icon:L(()=>[V(Ht(Sle))]),default:L(()=>[t[5]||=zi(`插件市场`,-1)]),_:1}),V(n,{value:`/operations`},{icon:L(()=>[V(Ht(x_))]),default:L(()=>[t[6]||=zi(`操作记录`,-1)]),_:1}),i.value?(Ei(),Ai(bi,{key:0},[V(l,{class:`nav-divider`}),t[7]||=B(`div`,{class:`nav-caption nav-caption-module`},`业务模块`,-1)],64)):Bi(``,!0),i.value?(Ei(),ji(n,{key:1,value:`/modules/subscription/overview`},{icon:L(()=>[V(Ht(Yh))]),default:L(()=>[t[8]||=zi(`订阅管理 `,-1)]),_:1})):Bi(``,!0)]),_:1},8,[`value`]),B(`div`,qV,[V(p,{theme:`success`,variant:`light`,class:`status-tag`},{default:L(()=>[V(Ht(tg),{size:`14px`}),t[9]||=zi(` Core 会话正常`,-1)]),_:1}),t[10]||=B(`span`,{class:`version-text`},`Plugin Admin v1.1.0`,-1)])]),_:1},8,[`class`]),V(b,{class:`main-layout`},{default:L(()=>[V(_,{class:`app-header`},{default:L(()=>[B(`div`,JV,[V(h,{class:`mobile-menu-button`,variant:`text`,shape:`square`,"aria-label":`打开导航`,onClick:t[1]||=e=>r.value=!0},{icon:L(()=>[V(Ht(Jce))]),_:1}),B(`div`,YV,[t[12]||=B(`span`,null,`插件管理`,-1),V(Ht(yg),{size:`15px`}),B(`strong`,null,ve(a.value),1)])]),B(`div`,XV,[V(p,{theme:`success`,variant:`light`,class:`secure-tag`},{default:L(()=>[V(Ht(tg),{size:`14px`}),t[13]||=zi(` 安全会话`,-1)]),_:1}),V(g,{options:c,trigger:`click`,onClick:d},{default:L(()=>[V(h,{variant:`text`,class:`user-button`},{icon:L(()=>[V(Ht(Nv))]),default:L(()=>[B(`span`,ZV,ve(s.value),1),V(Ht(sg),{size:`15px`})]),_:1})]),_:1})])]),_:1}),V(y,{class:`app-content`},{default:L(()=>[V(v)]),_:1})]),_:1})]),_:1})}}}),$V={key:0,class:`captcha-turnstile`},eH=z({__name:`TurnstileWidget`,props:{siteKey:{},theme:{default:`auto`},size:{default:`flexible`}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=I(null),o=null,s=null;function c(){return window.turnstile?Promise.resolve():s||(s=new Promise((e,t)=>{let n=document.querySelector(`script[src*="challenges.cloudflare.com/turnstile"]`);if(n){n.addEventListener(`load`,()=>window.turnstile?e():t(Error(`Turnstile SDK unavailable`)),{once:!0}),window.turnstile&&e();return}let r=document.createElement(`script`);r.src=`https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit`,r.async=!0,r.defer=!0,r.onload=()=>window.turnstile?e():t(Error(`Turnstile SDK unavailable`)),r.onerror=()=>t(Error(`Failed to load Turnstile SDK`)),document.head.appendChild(r)}).catch(e=>{throw s=null,e}),s)}function l(){if(!(!window.turnstile||!a.value||!r.siteKey)){if(o){try{window.turnstile.remove(o)}catch{}o=null}a.value.innerHTML=``,o=window.turnstile.render(a.value,{sitekey:r.siteKey,theme:r.theme,size:r.size,callback:e=>i(`verify`,e),"expired-callback":()=>i(`expire`),"error-callback":()=>i(`error`)})}}function u(){if(window.turnstile&&o)try{window.turnstile.reset(o)}catch{}}return t({reset:u}),mr(async()=>{if(r.siteKey)try{await c(),l()}catch(e){console.error(`Failed to initialize Turnstile:`,e),i(`error`)}}),R(()=>r.siteKey,e=>{e&&window.turnstile&&l()}),vr(()=>{if(window.turnstile&&o)try{window.turnstile.remove(o)}catch{}o=null}),(t,n)=>e.siteKey?(Ei(),Ai(`div`,$V,[B(`div`,{ref_key:`containerRef`,ref:a,class:`captcha-turnstile__container`},null,512)])):Bi(``,!0)}}),tH=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},nH=tH(eH,[[`__scopeId`,`data-v-dcfbd1a5`]]),rH={cn:`https://turing.captcha.qcloud.com/TJCaptcha.js`,intl:`https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js`},iH=null,aH=null;function oH(e){return e===`intl`?`intl`:`cn`}function sH(){return window.TCaptchaGlobal===!0?`intl`:`cn`}function cH(e=`cn`){return window.TencentCaptcha&&(aH===e||sH()===e)?Promise.resolve(window.TencentCaptcha):window.TencentCaptcha&&aH!==null&&aH!==e?Promise.reject(Error(`Tencent Captcha region changed; reload the page to apply it`)):iH&&aH===e?iH:(aH=e,iH=new Promise((t,n)=>{let r=document.querySelector(`script[src="${rH[e]}"]`);if(r){let i=()=>window.TencentCaptcha&&sH()===e?t(window.TencentCaptcha):n(Error(`Tencent Captcha SDK unavailable`));window.TencentCaptcha?i():r.addEventListener(`load`,i,{once:!0}),r.addEventListener(`error`,()=>n(Error(`Failed to load Tencent Captcha SDK`)),{once:!0});return}let i=document.createElement(`script`);i.src=rH[e],i.async=!0,i.onload=()=>{window.TencentCaptcha&&sH()===e?t(window.TencentCaptcha):n(Error(`Tencent Captcha SDK unavailable`))},i.onerror=()=>n(Error(`Failed to load Tencent Captcha SDK`)),document.head.appendChild(i)}).catch(e=>{throw iH=null,aH=null,e}),iH)}var lH={class:`captcha-action`},uH=[`disabled`],dH=tH(z({__name:`TencentCaptchaGate`,props:{appId:{},region:{default:`cn`}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=U(()=>oH(r.region)===`intl`),o=I(null),s=I(`idle`),c=null,l=null,u=null,d=null;function f(e){if(e.ret===2){s.value=`idle`,u?.(null),u=null,l=null;return}let t=e.ticket?.trim()||``,n=e.randstr?.trim()||``;if(!t||!n||t.startsWith(`trerror_`)||e.errorCode!==void 0){s.value=`idle`,u?.(null),u=null,l=null,i(`error`);return}let r={ticket:t,randstr:n};d=r,s.value=`verified`,i(`verify`,r),u?.(r),u=null,l=null}async function p(){let e=await cH(oH(r.region));if(!c)if(a.value){if(!o.value)throw Error(`Tencent Captcha container unavailable`);c=new e(o.value,r.appId,f,{enableAutoCheck:!1,type:`popup`})}else c=new e(r.appId,f,{userLanguage:`zh-cn`})}function m(){s.value===`verified`||s.value===`verifying`||(s.value=`verifying`,h())}async function h(){if(d){let e=d;return d=null,e}if(l)return l;let e=new Promise(e=>{u=e});l=e;try{await p(),c?.show()}catch(e){throw s.value=`idle`,u?.(null),u=null,l=null,i(`error`),e}return e}function g(){c?.destroy(),c=null,d=null,s.value=`idle`,u?.(null),u=null,l=null,i(`expire`)}return t({verify:h,reset:g}),mr(()=>{r.appId&&a.value&&p().catch(()=>i(`error`))}),_r(g),(e,t)=>(Ei(),Ai(`div`,lH,[a.value?(Ei(),Ai(`div`,{key:0,ref_key:`internationalContainerRef`,ref:o,class:`captcha-action__international`},null,512)):(Ei(),Ai(`button`,{key:1,type:`button`,class:`captcha-action__trigger`,disabled:s.value===`verified`||s.value===`verifying`,onClick:m},[B(`span`,{class:de([`captcha-action__dot`,{"is-verified":s.value===`verified`}])},null,2),zi(` `+ve(s.value===`verified`?`验证通过`:s.value===`verifying`?`验证中...`:`点击完成安全验证`),1)],8,uH))]))}}),[[`__scopeId`,`data-v-7fd83f77`]]),fH={key:0,class:`captcha-action`},pH=[`disabled`],mH=`https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js`,hH=tH(z({__name:`AliyunCaptchaWidget`,props:{sceneId:{},prefix:{},region:{default:`cn`}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=Math.random().toString(36).slice(2,10),o=`plugin-aliyun-captcha-button-${a}`,s=`plugin-aliyun-captcha-element-${a}`,c=I(`idle`),l=null,u=null,d=null,f=null,p=!1;function m(){return window.initAliyunCaptcha?Promise.resolve():l||(window.AliyunCaptchaConfig={region:r.region||`cn`,prefix:r.prefix},l=new Promise((e,t)=>{let n=document.querySelector(`script[src*="aliyunCaptcha/AliyunCaptcha"]`);if(n){n.addEventListener(`load`,()=>window.initAliyunCaptcha?e():t(Error(`Aliyun Captcha SDK unavailable`)),{once:!0}),n.addEventListener(`error`,()=>t(Error(`Failed to load Aliyun Captcha SDK`)),{once:!0});return}let r=document.createElement(`script`);r.src=mH,r.async=!0,r.onload=()=>window.initAliyunCaptcha?e():t(Error(`Aliyun Captcha SDK unavailable`)),r.onerror=()=>t(Error(`Failed to load Aliyun Captcha SDK`)),document.head.appendChild(r)}).catch(e=>{throw l=null,e}),l)}function h(e){f!==null&&(window.clearTimeout(f),f=null);let t=e.trim();if(!t){c.value=`idle`,d?.resolve(null),d=null,i(`error`);return}u=t,c.value=`verified`,i(`verify`,t),d?.resolve(t),d=null}function g(){if(!p){if(!window.initAliyunCaptcha)throw Error(`Aliyun Captcha SDK unavailable`);window.initAliyunCaptcha({SceneId:r.sceneId,prefix:r.prefix,mode:`popup`,element:`#${s}`,button:`#${o}`,captchaVerifyCallback:e=>(h(e),{captchaResult:!0}),onBizResultCallback:()=>void 0,getInstance:()=>void 0,slideStyle:{width:360,height:40},language:`cn`}),p=!0}}function _(){c.value===`verified`||c.value===`verifying`||(c.value=`verifying`,v().catch(()=>{c.value=`idle`,i(`error`)}))}async function v(){if(u){let e=u;return u=null,e}if(await m(),!window.initAliyunCaptcha)throw Error(`Aliyun Captcha SDK unavailable`);return g(),new Promise(e=>{d={resolve:e},f!==null&&window.clearTimeout(f),f=window.setTimeout(()=>{f=null,c.value=`idle`,d?.resolve(null),d=null},15e3),document.getElementById(o)?.click()})}function y(){f!==null&&(window.clearTimeout(f),f=null),u=null,c.value=`idle`,d?.resolve(null),d=null,document.getElementById(`aliyunCaptcha-mask`)?.remove(),document.getElementById(`aliyunCaptcha-window-popup`)?.remove(),i(`expire`)}return t({verify:v,reset:y}),mr(()=>{!r.sceneId||!r.prefix||m().then(g).catch(()=>i(`error`))}),vr(()=>{f!==null&&(window.clearTimeout(f),f=null),d?.resolve(null),d=null,document.getElementById(`aliyunCaptcha-mask`)?.remove(),document.getElementById(`aliyunCaptcha-window-popup`)?.remove()}),(t,n)=>e.sceneId&&e.prefix?(Ei(),Ai(`div`,fH,[B(`button`,{id:o,type:`button`,class:de([`captcha-action__trigger`,{"is-verified":c.value===`verified`}]),disabled:c.value===`verified`||c.value===`verifying`,onClick:_},[B(`span`,{class:de([`captcha-action__dot`,{"is-verified":c.value===`verified`}])},null,2),zi(` `+ve(c.value===`verified`?`验证通过`:c.value===`verifying`?`验证中...`:`点击完成安全验证`),1)],10,pH),B(`div`,{id:s})])):Bi(``,!0)}}),[[`__scopeId`,`data-v-8a1336a6`]]),gH={key:0,class:`captcha-challenge`,"aria-live":`polite`},_H={key:3,class:`captcha-challenge__missing`},vH=tH(z({__name:`CaptchaChallenge`,props:{enabled:{type:Boolean},provider:{},turnstileSiteKey:{},tencentAppId:{},tencentRegion:{},aliyunSceneId:{},aliyunPrefix:{},aliyunRegion:{}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=I(null),o=I(null),s=I(null),c=I(``),l=I(null),u=I(``),d=U(()=>r.provider);function f(e){c.value=e,i(`verify`,{token:e,randstr:``,provider:`turnstile`})}function p(e){l.value=e,i(`verify`,{token:e.ticket,randstr:e.randstr,provider:`tencent`})}function m(e){u.value=e,i(`verify`,{token:e,randstr:``,provider:`aliyun`})}function h(){c.value=``,l.value=null,u.value=``,i(`expire`)}function g(){h(),i(`error`)}async function _(){if(!r.enabled)return null;if(d.value===`turnstile`)return c.value?{token:c.value,randstr:``,provider:`turnstile`}:null;if(d.value===`tencent`){let e=l.value||await o.value?.verify()||null;return e?{token:e.ticket,randstr:e.randstr,provider:`tencent`}:null}if(d.value===`aliyun`){let e=u.value||await s.value?.verify()||``;return e?{token:e,randstr:``,provider:`aliyun`}:null}return null}function v(){c.value=``,l.value=null,u.value=``,a.value?.reset(),o.value?.reset(),s.value?.reset()}return t({verifyAction:_,reset:v}),(t,n)=>e.enabled?(Ei(),Ai(`div`,gH,[d.value===`turnstile`&&e.turnstileSiteKey?(Ei(),ji(nH,{key:0,ref_key:`turnstileRef`,ref:a,"site-key":e.turnstileSiteKey,onVerify:f,onExpire:h,onError:g},null,8,[`site-key`])):d.value===`tencent`&&e.tencentAppId?(Ei(),ji(dH,{key:1,ref_key:`tencentRef`,ref:o,"app-id":e.tencentAppId,region:e.tencentRegion,onVerify:p,onExpire:h,onError:g},null,8,[`app-id`,`region`])):d.value===`aliyun`&&e.aliyunSceneId&&e.aliyunPrefix?(Ei(),ji(hH,{key:2,ref_key:`aliyunRef`,ref:s,"scene-id":e.aliyunSceneId,prefix:e.aliyunPrefix,region:e.aliyunRegion,onVerify:m,onExpire:h,onError:g},null,8,[`scene-id`,`prefix`,`region`])):(Ei(),Ai(`div`,_H,`验证码配置不完整,请联系管理员`))])):Bi(``,!0)}}),[[`__scopeId`,`data-v-be35acfe`]]),yH={class:`login-page`},bH={class:`login-layout`},xH={class:`login-intro`},SH={class:`brand brand-login`},CH={class:`brand-mark`},wH={class:`login-points`},TH={class:`login-card-heading`},EH={class:`login-security`},DH=z({__name:`Login`,setup(e){let t=Hz(),n=I(!1),r=I(!1),i=I(``),a=I(!1),o=I(``),s=I(null),c=I(null),l=Dt({enabled:!1,provider:``,turnstile_enabled:!1,turnstile_site_key:``,tencent_captcha_enabled:!1,tencent_captcha_app_id:``,tencent_captcha_region:`cn`,aliyun_captcha_enabled:!1,aliyun_captcha_scene_id:``,aliyun_captcha_prefix:``,aliyun_captcha_region:`cn`}),u=Dt({email:``,password:``}),d=Dt({totp_code:``}),f={email:[{required:!0,message:`请输入管理员邮箱`,type:`error`}],password:[{required:!0,message:`请输入密码`,type:`error`}]};async function p(){if(!u.email.trim()||!u.password){i.value=`请输入邮箱和密码`;return}n.value=!0,i.value=``;try{let e=l.enabled&&await s.value?.verifyAction()||null;if(l.enabled&&!e){i.value=`请先完成安全验证`;return}c.value=e;let n=e?.provider===`tencent`?{tencent_captcha_ticket:e.token,tencent_captcha_randstr:e.randstr}:e?.provider===`aliyun`||e?.provider===`turnstile`?{turnstile_token:e.token}:{};(await FV(u.email.trim(),u.password,n)).requires2fa?r.value=!0:(eb.success(`登录成功`),t.push(`/overview`))}catch(e){i.value=e instanceof Error?e.message:`登录失败,请稍后重试`}finally{s.value?.reset(),c.value=null,n.value=!1}}async function m(){if(!/^\d{6}$/.test(d.totp_code)){i.value=`请输入 6 位数字验证码`;return}n.value=!0,i.value=``;try{await IV(d.totp_code),eb.success(`登录成功`),t.push(`/overview`)}catch(e){i.value=e instanceof Error?e.message:`验证码校验失败`}finally{n.value=!1}}function h(){r.value=!1,d.totp_code=``,i.value=``}function g(e){c.value=e,i.value=``}function _(){c.value=null}function v(){c.value=null,i.value=`安全验证加载失败,请刷新页面重试`}return mr(async()=>{o.value=``;try{let e=await NV();Object.assign(l,e),[e.turnstile_enabled,e.tencent_captcha_enabled,e.aliyun_captcha_enabled].filter(Boolean).length>1?o.value=`Core 同时启用了多个验证码服务,请保留一个服务商后重试`:e.enabled&&!e.provider&&(o.value=`验证码配置不完整,请联系管理员`)}catch(e){o.value=e instanceof Error?`验证码配置加载失败:${e.message}`:`验证码配置加载失败,请刷新页面重试`}finally{a.value=!0}}),(e,t)=>{let c=br(`t-tag`),y=br(`t-alert`),b=br(`t-input`),x=br(`t-form-item`),S=br(`t-button`),C=br(`t-form`),w=br(`t-card`);return Ei(),Ai(`main`,yH,[t[18]||=B(`div`,{class:`login-accent`},null,-1),B(`section`,bH,[B(`div`,xH,[B(`div`,SH,[B(`div`,CH,[V(Ht(Pg),{size:`24px`})]),t[3]||=B(`div`,null,[B(`div`,{class:`brand-title`},`Sub2API`),B(`div`,{class:`brand-subtitle`},`插件控制面`)],-1)]),t[7]||=B(`p`,{class:`eyebrow`},`BUSINESS PLUGIN CONTROL PLANE`,-1),t[8]||=B(`h1`,null,`统一管理你的业务插件`,-1),t[9]||=B(`p`,{class:`login-lead`},`使用 Core 管理员会话进入插件市场、生命周期和业务模块。所有插件操作都在同一安全控制面完成。`,-1),B(`div`,wH,[B(`div`,null,[V(Ht(tg),{size:`18px`}),t[4]||=B(`span`,null,`一次登录,访问已启用业务模块`,-1)]),B(`div`,null,[V(Ht(tg),{size:`18px`}),t[5]||=B(`span`,null,`凭据仅保存在服务端会话`,-1)]),B(`div`,null,[V(Ht(tg),{size:`18px`}),t[6]||=B(`span`,null,`每次变更都有可追溯操作记录`,-1)])])]),V(w,{class:`login-card`,bordered:!0},{default:L(()=>[B(`div`,TH,[t[11]||=B(`div`,null,[B(`p`,{class:`eyebrow`},`ADMIN ACCESS`),B(`h2`,null,`管理员登录`)],-1),V(c,{theme:`primary`,variant:`light`},{default:L(()=>[...t[10]||=[zi(`仅管理员`,-1)]]),_:1})]),t[17]||=B(`p`,{class:`muted`},`使用 Sub2API Core 的管理员账号登录,普通账号没有访问权限。`,-1),o.value?(Ei(),ji(y,{key:0,class:`login-error`,theme:`warning`,message:o.value},null,8,[`message`])):Bi(``,!0),r.value?(Ei(),ji(C,{key:2,class:`login-form`,data:d,onSubmit:m},{default:L(()=>[V(y,{theme:`info`,title:`需要二次验证`},{default:L(()=>[...t[13]||=[zi(`请输入 Core 返回的 6 位验证码。`,-1)]]),_:1}),V(x,{label:`验证码`,name:`totp_code`},{default:L(()=>[V(b,{modelValue:d.totp_code,"onUpdate:modelValue":t[2]||=e=>d.totp_code=e,inputmode:`numeric`,maxlength:`6`,placeholder:`000000`},null,8,[`modelValue`])]),_:1}),V(S,{theme:`primary`,type:`submit`,block:``,loading:n.value},{icon:L(()=>[V(Ht(tg))]),default:L(()=>[t[14]||=zi(`验证并继续`,-1)]),_:1},8,[`loading`]),V(S,{variant:`text`,block:``,onClick:h},{default:L(()=>[...t[15]||=[zi(`返回账号登录`,-1)]]),_:1})]),_:1},8,[`data`])):(Ei(),ji(C,{key:1,ref:`loginForm`,class:`login-form`,data:u,rules:f,onSubmit:p},{default:L(()=>[V(x,{label:`邮箱`,name:`email`},{default:L(()=>[V(b,{modelValue:u.email,"onUpdate:modelValue":t[0]||=e=>u.email=e,type:`text`,"aria-label":`邮箱`,autocomplete:`username`,placeholder:`admin@example.com`},null,8,[`modelValue`])]),_:1}),V(x,{label:`密码`,name:`password`},{default:L(()=>[V(b,{modelValue:u.password,"onUpdate:modelValue":t[1]||=e=>u.password=e,type:`password`,"aria-label":`密码`,autocomplete:`current-password`,placeholder:`输入管理员密码`},null,8,[`modelValue`])]),_:1}),a.value&&l.enabled?(Ei(),ji(vH,{key:0,ref_key:`captchaRef`,ref:s,enabled:l.enabled,provider:l.provider,"turnstile-site-key":l.turnstile_site_key,"tencent-app-id":l.tencent_captcha_app_id,"tencent-region":l.tencent_captcha_region,"aliyun-scene-id":l.aliyun_captcha_scene_id,"aliyun-prefix":l.aliyun_captcha_prefix,"aliyun-region":l.aliyun_captcha_region,onVerify:g,onExpire:_,onError:v},null,8,[`enabled`,`provider`,`turnstile-site-key`,`tencent-app-id`,`tencent-region`,`aliyun-scene-id`,`aliyun-prefix`,`aliyun-region`])):Bi(``,!0),V(S,{theme:`primary`,type:`submit`,block:``,loading:n.value,disabled:!a.value||!!o.value},{icon:L(()=>[V(Ht(Nv))]),default:L(()=>[t[12]||=zi(`登录`,-1)]),_:1},8,[`loading`,`disabled`])]),_:1},8,[`data`])),i.value?(Ei(),ji(y,{key:3,class:`login-error`,theme:`error`,message:i.value},null,8,[`message`])):Bi(``,!0),B(`div`,EH,[V(Ht(F_),{size:`15px`}),t[16]||=zi(` HttpOnly 会话 · CSRF 保护 · 8 小时绝对有效期`,-1)])]),_:1})])])}}}),OH={class:`page-header`},kH={class:`eyebrow`},AH={class:`page-subtitle`},jH={class:`page-actions`},MH=z({__name:`PageHeader`,props:{eyebrow:{},title:{},subtitle:{}},setup(e){return(t,n)=>(Ei(),Ai(`header`,OH,[B(`div`,null,[B(`p`,kH,ve(e.eyebrow),1),B(`h1`,null,ve(e.title),1),B(`p`,AH,ve(e.subtitle),1)]),B(`div`,jH,[Dee(t.$slots,`actions`)])]))}}),NH=function(e,t){return NH=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},NH(e,t)};function PH(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);NH(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var FH=`12px sans-serif`,IH=20,LH=100,RH=`007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N`;function zH(e){var t={};if(typeof JSON>`u`)return t;for(var n=0;n=0)s=o*n.length;else for(var c=0;c=eU&&($H=0),$H++}function nU(){var e=[...arguments];typeof console<`u`&&console.error.apply(console,e)}function rU(e){if(typeof e!=`object`||!e)return e;var t=e,n=WH.call(e);if(n===`[object Array]`){if(!VU(e)){t=[];for(var r=0,i=e.length;r`u`&&typeof self<`u`?eW.worker=!0:!eW.hasGlobalWindow||`Deno`in window||typeof navigator<`u`&&typeof navigator.userAgent==`string`&&navigator.userAgent.indexOf(`Node.js`)>-1?(eW.node=!0,eW.svgSupported=!0):tW(navigator.userAgent,eW);function tW(e,t){var n=t.browser,r=e.match(/Firefox\/([\d.]+)/),i=e.match(/MSIE\s([\d.]+)/)||e.match(/Trident\/.+?rv:(([\d.]+))/),a=e.match(/Edge?\/([\d.]+)/),o=/micromessenger/i.test(e);if(r&&(n.firefox=!0,n.version=r[1]),i&&(n.ie=!0,n.version=i[1]),a&&(n.edge=!0,n.version=a[1],n.newEdge=+a[1].split(`.`)[0]>18),o&&(n.weChat=!0),t.svgSupported=typeof SVGRect<`u`,t.touchEventsSupported=`ontouchstart`in window&&!n.ie&&!n.edge,t.pointerEventsSupported=`onpointerdown`in window&&(n.edge||n.ie&&+n.version>=11),t.domSupported=typeof document<`u`){var s=document.documentElement.style;t.transform3dSupported=(n.ie&&`transition`in s||n.edge||`WebKitCSSMatrix`in window&&`m11`in new WebKitCSSMatrix||`MozPerspective`in s)&&!(`OTransition`in s),t.transformSupported=t.transform3dSupported||n.ie&&+n.version>=9}}var nW=`.`,rW=`___EC__COMPONENT__CONTAINER___`,iW=`___EC__EXTENDED_CLASS___`;function aW(e){var t={main:``,sub:``};if(e){var n=e.split(nW);t.main=n[0]||``,t.sub=n[1]||``}return t}function oW(e){LU(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(e),`componentType "`+e+`" illegal`)}function sW(e){return!!(e&&e[iW])}function cW(e,t){e.$constructor=e,e.extend=function(e){var t=this,n;return lW(t)?n=function(e){PH(t,e);function t(){return e.apply(this,arguments)||this}return t}(t):(n=function(){(e.$constructor||t).apply(this,arguments)},lU(n,this)),aU(n.prototype,e),n[iW]=!0,n.extend=this.extend,n.superCall=pW,n.superApply=mW,n.superClass=t,n}}function lW(e){return xU(e)&&/^class\s/.test(Function.prototype.toString.call(e))}function uW(e,t){e.extend=t.extend}var dW=Math.round(Math.random()*10);function fW(e){var t=[`__\0is_clz`,dW++].join(`_`);e.prototype[t]=!0,e.isInstance=function(e){return!!(e&&e[t])}}function pW(e,t){var n=[...arguments].slice(2);return this.superClass.prototype[t].apply(e,n)}function mW(e,t,n){return this.superClass.prototype[t].apply(e,n)}function hW(e){var t={};e.registerClass=function(e){var r=e.type||e.prototype.type;if(r){oW(r),e.prototype.type=r;var i=aW(r);if(!i.sub)t[i.main]=e;else if(i.sub!==rW){var a=n(i);a[i.sub]=e}}return e},e.getClass=function(e,n,r){var i=t[e];if(i&&i[rW]&&(i=n?i[n]:null),r&&!i)throw Error(n?`Component `+e+`.`+(n||``)+` is used but not imported.`:e+`.type should be specified.`);return i},e.getClassesByMainType=function(e){var n=aW(e),r=[],i=t[n.main];return i&&i[rW]?$(i,function(e,t){t!==rW&&r.push(e)}):r.push(i),r},e.hasClass=function(e){return!!t[aW(e).main]},e.getAllClassMainTypes=function(){var e=[];return $(t,function(t,n){e.push(n)}),e},e.hasSubTypes=function(e){var n=t[aW(e).main];return n&&n[rW]};function n(e){var n=t[e.main];return(!n||!n[rW])&&(n=t[e.main]={},n[rW]=!0),n}}function gW(e,t){for(var n=0;n=0||i&&cU(i,s)<0)){var c=n.getShallow(s,t);c!=null&&(a[e[o][0]]=c)}}return a}}var _W=gW([[`fill`,`color`],[`shadowBlur`],[`shadowOffsetX`],[`shadowOffsetY`],[`opacity`],[`shadowColor`]]),vW=function(){function e(){}return e.prototype.getAreaStyle=function(e,t){return _W(this,e,t)},e}(),yW=function(e,t){return yW=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},yW(e,t)};function bW(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);yW(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var xW=function(){function e(e){this.value=e}return e}(),SW=function(){function e(){this._len=0}return e.prototype.insert=function(e){var t=new xW(e);return this.insertEntry(t),t},e.prototype.insertEntry=function(e){this.head?(this.tail.next=e,e.prev=this.tail,e.next=null,this.tail=e):this.head=this.tail=e,this._len++},e.prototype.remove=function(e){var t=e.prev,n=e.next;t?t.next=n:this.head=n,n?n.prev=t:this.tail=t,e.next=e.prev=null,this._len--},e.prototype.len=function(){return this._len},e.prototype.clear=function(){this.head=this.tail=null,this._len=0},e}(),CW=function(){function e(e){this._list=new SW,this._maxSize=10,this._map={},this._maxSize=e}return e.prototype.put=function(e,t){var n=this._list,r=this._map,i=null;if(r[e]==null){var a=n.len(),o=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=n.head;n.remove(s),delete r[s.key],i=s.value,this._lastRemovedEntry=s}o?o.value=t:o=new xW(t),o.key=e,n.insertEntry(o),r[e]=o}return i},e.prototype.get=function(e){var t=this._map[e],n=this._list;if(t!=null)return t!==n.tail&&(n.remove(t),n.insertEntry(t)),t.value},e.prototype.clear=function(){this._list.clear(),this._map={}},e.prototype.len=function(){return this._list.len()},e}(),wW=new CW(50);function TW(e){if(typeof e==`string`){var t=wW.get(e);return t&&t.image}else return e}function EW(e,t,n,r,i){if(!e)return t;if(typeof e==`string`){if(t&&t.__zrImageSrc===e||!n)return t;var a=wW.get(e),o={hostEl:n,cb:r,cbPayload:i};return a?(t=a.image,!OW(t)&&a.pending.push(o)):(t=VH.loadImage(e,DW,DW),t.__zrImageSrc=e,wW.put(e,t.__cachedImgObj={image:t,pending:[o]})),t}else return e}function DW(){var e=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var t=0;tu||d>f||p>m||h>g)return!1;var _=!(u=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height},e.prototype.contain=function(t,n){return e.contain(this,t,n)},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e.prototype.copy=function(e){oG(this,e)},e.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},e.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},e.prototype.isZero=function(){return this.width===0||this.height===0},e.create=function(t){return new e(t?t.x:0,t?t.y:0,t?t.width:0,t?t.height:0)},e.copy=function(e,t){return e.x=t.x,e.y=t.y,e.width=t.width,e.height=t.height,e},e.applyTransform=function(e,t,n){if(!n){e!==t&&oG(e,t);return}if(n[1]<1e-5&&n[1]>-1e-5&&n[2]<1e-5&&n[2]>-1e-5){var r=n[0],i=n[3],a=n[4],o=n[5];e.x=t.x*r+a,e.y=t.y*i+o,e.width=t.width*r,e.height=t.height*i,e.width<0&&(e.x+=e.width,e.width=-e.width),e.height<0&&(e.y+=e.height,e.height=-e.height);return}XW.x=QW.x=t.x,XW.y=$W.y=t.y,ZW.x=$W.x=t.x+t.width,ZW.y=QW.y=t.y+t.height,XW.transform(n),$W.transform(n),ZW.transform(n),QW.transform(n),e.x=KW(XW.x,ZW.x,QW.x,$W.x),e.y=KW(XW.y,ZW.y,QW.y,$W.y);var s=qW(XW.x,ZW.x,QW.x,$W.x),c=qW(XW.y,ZW.y,QW.y,$W.y);e.width=s-e.x,e.height=c-e.y},e.calculateTransform=function(e,t,n){var r=n.width/t.width,i=n.height/t.height;return e=AW(e||[]),NW(e,e,LW(sG,-t.x,-t.y)),kye(e,e,LW(sG,r,i)),NW(e,e,LW(sG,n.x,n.y)),e},e}();iG.create;var aG=iG.set,oG=iG.copy,Rye=iG.calculateTransform;iG.applyTransform,iG.contain;var zye=new iG(0,0,0,0),Bye=new iG(0,0,0,0),sG=[];function cG(e,t,n,r,i,a,o,s){var c=JW(t-n),l=JW(r-e),u=KW(c,l),d=YW[i],f=YW[1-i],p=Lye[i];t=l||!eG.bidirectional)&&(tG[d]=-l,tG[f]=0,eG.useDir&&eG.calcDirMTV())))}function lG(){var e=0,t=new GW,n=new GW,r={minTv:new GW,maxTv:new GW,useDir:!1,dirMinTv:new GW,touchThreshold:0,bidirectional:!0,negativeSize:!1,reset:function(i,a){r.touchThreshold=0,i&&i.touchThreshold!=null&&(r.touchThreshold=qW(0,i.touchThreshold)),r.negativeSize=!1,a&&(r.minTv.set(1/0,1/0),r.maxTv.set(0,0),r.useDir=!1,i&&i.direction!=null&&(r.useDir=!0,r.dirMinTv.copy(r.minTv),n.copy(r.minTv),e=i.direction,r.bidirectional=i.bidirectional==null||!!i.bidirectional,r.bidirectional||t.set(Math.cos(e),Math.sin(e))))},calcDirMTV:function(){var a=r.minTv,o=r.dirMinTv,s=a.y*a.y+a.x*a.x,c=Math.sin(e),l=Math.cos(e),u=c*a.y+l*a.x;if(i(u)){i(a.x)&&i(a.y)&&o.set(0,0);return}if(n.x=s*l/u,n.y=s*c/u,i(n.x)&&i(n.y)){o.set(0,0);return}(r.bidirectional||t.dot(n)>0)&&n.len()=pG)){e||=`12px sans-serif`;for(var t=[],n=+new Date,r=0;r<=127;r++)t[r]=VH.measureText(String.fromCharCode(r),e).width;var i=+new Date-n;return i>16?fG=pG:i>2&&fG++,t}}var fG=0,pG=5;function mG(e,t){return e.asciiWidthMapTried||=(e.asciiWidthMap=Vye(e.font),!0),0<=t&&t<=127?e.asciiWidthMap==null?e.asciiCharWidth:e.asciiWidthMap[t]:e.stWideCharWidth}function hG(e,t){var n=e.strWidthCache,r=n.get(t);return r??(r=VH.measureText(t,e.font).width,n.put(t,r)),r}function gG(e,t,n,r){var i=hG(uG(t),e),a=bG(t);return new iG(vG(0,i,n),yG(0,a,r),i,a)}function _G(e,t,n,r){var i=((e||``)+``).split(` + `},N=function(){e.mode===`push`&&dn(function(){D.value&&(D.value.style.cssText=M)})},P=function(){if(!(!D.value||e.mode!==`push`)){var t={left:{name:`margin-left`,value:w.value},right:{name:`margin-left`,value:`-${w.value}`},top:{name:`margin-top`,value:w.value},bottom:{name:`margin-top`,value:`-${w.value}`}}[e.placement];r.value?D.value.style.setProperty(t.name,t.value):D.value.style.removeProperty(t.name)}},F=function(){var t=b({confirmBtn:e.confirmBtn,globalConfirm:o.value.confirm,className:`${u.value}__confirm`}),n=x({cancelBtn:e.cancelBtn,globalCancel:o.value.cancel,className:`${u.value}__cancel`});return V(`div`,{style:k.value},[e.placement===`right`?t:null,n,e.placement===`right`?null:t])},te=jm(`drawer`,{visible:g}).isTopInteractivePopup;R(O,N,{immediate:!0});var ne=function(t){if(t&&(_.value=!0),e.destroyOnClose){t?(n.value=!1,setTimeout(function(){return r.value=!0})):(r.value=!1,n.value&&=!1,_.value?setTimeout(function(){return n.value=!0},300):n.value=!0);return}if(n.value&&t){n.value=!1,setTimeout(function(){return r.value=!0});return}setTimeout(function(){return r.value=t})},re=function(){!e.showInAttachedElement&&e.preventScrollThrough&&r.value&&(_.value||!e.lazy)&&(i.value||ee(),i.value&&!document.head.contains(i.value)&&document.head.appendChild(i.value))};R(function(){return e.visible},function(t){if(!sp){if(t){var n;re(),(n=e.onBeforeOpen)==null||n.call(e)}else{var r;j(),(r=e.onBeforeClose)==null||r.call(e)}ne(t)}},{immediate:!0});var ie=function(t){var n;(n=e.onCloseBtnClick)==null||n.call(e,{e:t}),oe({trigger:`close-btn`,e:t})},ae=function(t){var n;(n=e.onOverlayClick)==null||n.call(e,{e:t}),(e.closeOnOverlayClick??o.value.closeOnOverlayClick)&&oe({trigger:`overlay`,e:t})},oe=function(n){var r;(r=e.onClose)==null||r.call(e,n),t.emit(`update:visible`,!1)};gr(P),mr(function(){re(),window.addEventListener(`keydown`,A)}),_r(function(){j(),window.removeEventListener(`keydown`,A)});var se=U(function(){return _.value?r.value||!n.value:e.destroyOnClose&&n.value?!1:!e.lazy});return function(){if(se.value){var n=l(`body`,`default`),r=c(`header`),i=F();return V(Ln,{disabled:!e.attach||!v.value,to:v.value},{default:function(){return[V(`div`,H({ref:S,class:C.value,style:{zIndex:e.zIndex},onKeydown:A,tabindex:0},t.attrs),[e.showOverlay&&V(`div`,{class:`${u.value}__mask`,onClick:ae},null),V(`div`,{class:E.value,style:VL(VL({},T.value),h.value)},[r&&V(`div`,{class:`${u.value}__header`},[r]),e.closeBtn&&V(`div`,{class:`${u.value}__close-btn`,onClick:ie},[c(`closeBtn`,V(s,null,null))]),V(`div`,{class:[`${u.value}__body`,`narrow-scrollbar`]},[n]),e.footer&&V(`div`,{class:`${u.value}__footer`},[c(`footer`,i)]),e.sizeDraggable&&V(`div`,{style:m.value,onMousedown:p},null)])])]}})}}}});function WL(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function GL(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:document.body,n=Sp(),r=n.scrollTop,i=n.scrollLeft,a=e.getBoundingClientRect(),o=a.top,s=a.left,c=t.getBoundingClientRect(),l=c.top,u=c.left,d=bp(t,`position`);return t.tagName.toLowerCase()!==`body`&&d===`relative`||d===`sticky`?{top:o-l,left:s-u}:xp(e)?{top:o,left:s}:{top:o+r,left:s+i}}function $L(e){if(e){var t,n=null;if(Rd(e))n=document.querySelector(e);else if(q(e))n=e();else throw Error(`elm should be string or function`);if(n)return n;if(((t=process)==null||(t=t.env)==null?void 0:t.NODE_ENV)!==`test`)throw Error(`There is no element with given.`)}else return document.body}function eR(e){var t=e.getBoundingClientRect();if(!yp(e)){var n=uoe().height;_p(t.top-(n/2-t.height/2),{})}}var tR=X(z({name:`TGuide`,props:YL,setup:function(e,t){var n=pm(),r=Q(`guide`),i=Q(`guide--lock`),a=Rp(`guide`).globalConfig,o=Wt(e),s=o.current,c=o.modelValue,l=o.hideCounter,u=o.hidePrev,d=o.hideSkip,f=o.steps,p=o.zIndex,m=Y(Rm(s,c,e.defaultCurrent,e.onChange,`current`),2),h=m[0],g=m[1],_=I(),v=I(),y=I(),b=I(),x=I(),S=I(),C=I(),w=I(!1),T=U(function(){return f.value.length}),E=U(function(){return f.value[h.value]}),D=U(function(){return k(`mode`)===`popup`}),O=U(function(){return xp(b.value||document.body)}),k=function(t){return E.value[t]??e[t]},A=U(function(){var e=E.value.highlightContent,n=e;return q(e)?n=e(ee()):t.slots.highlightContent?n=t.slots.highlightContent(ee()):t.slots[`highlight-content`]?n=t.slots[`highlight-content`](ee()):e&&(n=V(n,null,null)),n&&(n.props||={},n.props.class=n.props.class||``),n}),j=U(function(){return!!(A.value&&D.value)}),M=I(!1),ee=function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{currentStepInfo:E.value},t=Function(`return `+sa.toString())();return Object.assign({},t,e)},N=function(e){var t=arguments.length>1&&arguments[1]!==void 0&&arguments[1],n=QL(b.value),r=n.top,i=n.left,a=b.value.getBoundingClientRect(),o=a.width,s=a.height,c=k(`highlightPadding`);if(D.value)o+=c*2,s+=c*2,r-=c,i-=c;else{var l=Sp(),u=l.scrollTop,d=l.scrollLeft;r+=u,i+=d}var f={top:`${r}px`,left:`${i}px`};if(j.value)if(t){var p=v.value.getBoundingClientRect(),m=p.width,h=p.height;Object.assign(f,{width:`${m}px`,height:`${h}px`})}else Object.assign(f,{width:`auto`,height:`auto`});else Object.assign(f,{width:`${o}px`,height:`${s}px`});Pm(e,f)},P=function(){dn(function(){var e;b.value=$L(E.value.element),b.value&&(ZL(b.value),N(v.value),N(y.value,!0),eR(b.value),(e=C.value)==null||e.update())})},F=function(){var e;(e=y.value)==null||e.parentNode.removeChild(y.value)},te=function(){dn(function(){b.value=S.value,ZL(b.value),N(v.value),eR(b.value)})},ne=function(){var e,t;(e=S.value)==null||e.parentNode.removeChild(S.value),(t=x.value)==null||t.parentNode.removeChild(x.value)},re=function(){D.value?(ne(),P()):(F(),te()),M.value=!0};Om(function(){M.value&&re()},!sp&&document.body);var ie=function(){var e,t;F(),ne(),(e=v.value)==null||e.parentNode.removeChild(v.value),(t=_.value)==null||t.parentNode.removeChild(_.value),fp(document.body,i.value)},ae=function(t){var n,r=T.value;w.value=!1,g(-1,{e:t,total:r}),(n=e.onSkip)==null||n.call(e,{e:t,current:h.value,total:r})},oe=function(t){var n,r=T.value;g(h.value-1,{e:t,total:r}),(n=e.onPrevStepClick)==null||n.call(e,{e:t,prev:h.value-1,current:h.value,total:r})},se=function(t){var n,r=T.value;g(h.value+1,{e:t,total:r}),(n=e.onNextStepClick)==null||n.call(e,{e:t,next:h.value+1,current:h.value,total:r})},ce=function(t){var n,r=T.value;w.value=!1,g(-1,{e:t,total:r}),(n=e.onFinish)==null||n.call(e,{e:t,current:h.value,total:r})},le=function(){h.value>=0&&h.value=0&&e-1}}},setup:function(e,t){var n=t.expose,r=Q(`notification-list`),i=e.placement,a=e.offset,o=I([]),s=I([]),c=U(function(){var e=_R({zIndex:iR},oR[i]);if(Array.isArray(a)&&a.length===2){var t=i.includes(`left`)?`left`:`right`,n=i.includes(`top`)?`top`:`bottom`;e[t]=f(a[0])??e[t],e[n]=f(a[1])??e[n]}return e}),l=function(e){return o.value.push(e),o.value.length-1},u=function(e){o.value.splice(e,1)},d=function(){o.value=[]},f=function(e){if(e)return isNaN(Number(e))?e:`${e}px`},p=function(e){var t={marginBottom:aR};return e.zIndex&&(t[`z-index`]=e.zIndex),t},m=function(e,t){return _R(_R({},t),{},{onCloseBtnClick:function(n){return t.onCloseBtnClick&&t.onCloseBtnClick(n),u(e)},onDurationEnd:function(){return t.onDurationEnd&&t.onDurationEnd(),u(e)},onClose:function(){return t.onClose&&t.onClose(),u(e)}})},h=function(e){e&&s.value.push(e)};return n({add:l,remove:u,removeAll:d,list:o,notificationList:s}),function(){if(o.value.length)return V(`div`,{class:`${r.value}__show`,style:c.value},[o.value.map(function(e,t){return V(hR,H({ref:h,key:e.id,style:p(e)},m(t,e)),null)})])}}});function yR(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function bR(e){for(var t=1;t1?`${m}[${t}]`:m;k[n]=e.raw}),C.length===1?k[m]=C[0].raw:k[m]=C.map(function(e){return e.raw}),k.length=C.length,y&&(k=y(k));var j=new FormData;return Object.keys(k).forEach(function(e){var t=k[e];Array.isArray(t)?t.forEach(function(t){j.append(e,t)}):j.append(e,t)}),T.open(n,r,!0),Object.keys(s).forEach(function(e){T.setRequestHeader(e,s[e])}),T.onerror=function(e){b({event:e,file:u,files:C,XMLHttpRequest:T}),clearInterval(E),clearTimeout(D)},T.ontimeout=function(e){b({event:e,file:u,files:C,XMLHttpRequest:T})},T.upload&&(T.upload.onprogress=function(e){var t=0;if(e.total>0&&(t=Math.round(e.loaded/e.total*100)),w=Math.max(t,w),w!==t&&C[0]?.percent!==w){var n=C.map(function(e){return ez(ez({},e),{},{percent:w})});x({event:e,percent:w,file:u||n[0],files:n,type:`real`,XMLHttpRequest:T})}}),T.onload=function(e){var t={};if(t.XMLHttpRequest=T,T.status<200||T.status>=300)return b({event:e,file:u,files:C,response:t,XMLHttpRequest:T});var n=T.responseText||T.response;try{t=JSON.parse(n)}catch{t=n,Vp.error(`Upload`,`response does not a valid json`)}clearInterval(E),clearTimeout(D),C.forEach(function(e){e.percent=100,e.status=`success`,e.uploadTime=t?.uploadTime||Gp()}),so(t)===`object`&&(t.XMLHttpRequest=T),S({event:e,file:u||C[0],files:W(C),XMLHttpRequest:T,response:t})},T.send(j),T.upload.requestParams=k,T.upload.requestHeaders=s,T}function nz(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function rz(e){for(var t=1;t=0?rz(rz({},e[a]),r):r;n.push(o)},i=0,a=t.length;i2&&arguments[2]!==void 0?arguments[2]:void 0,r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0;return e.map(function(e){var i=e;return q(t)&&(i=t(e)),rz({raw:e,lastModified:e.lastModified,name:e.name,size:e.size,type:e.type,percent:r,status:n},i)})}function fz(e){var t=e.files,n=e.uploadValue,r=e.max,i=e.allowUploadDuplicateFile,a=e.capture,o=a===void 0?``:a;return new Promise(function(a){var s=t.filter(function(e){return i||o?!0:!n.find(function(t){return t.name===e.name})}),c=!1;if(s.lengthr&&(u=!0)}var f=dz(s,e.format,e.autoUpload?`progress`:`waiting`),p;if(e.beforeAllFilesUpload){var m=e.beforeAllFilesUpload?.call(e,f);p=m instanceof Promise?m:new Promise(function(e){e(m)})}var h=f.map(function(t){return new Promise(function(n){iz(t,{beforeUpload:e.beforeUpload,sizeLimit:e.sizeLimit}).then(function(e){var r=Y(e,2),i=r[0],a=r[1];i?n({file:t,validateResult:{type:`FILE_OVER_SIZE_LIMIT`,extra:i}}):a===!1&&n({file:t,validateResult:{type:`CUSTOM_BEFORE_UPLOAD`}}),n({file:t})})})});Promise.all([p].concat(h)).then(function(e){var t=yF(e),n=t[0],r=t.slice(1);a(n===!1?{lengthOverLimit:u,hasSameNameFile:c,validateResult:{type:`BEFORE_ALL_FILES_UPLOAD`},files:f}:{lengthOverLimit:u,hasSameNameFile:c,fileValidateList:r,files:f})})})}function pz(e,t){var n=[],r=[],i=[];return e.forEach(function(e){if(e.validateResult?.type===`CUSTOM_BEFORE_UPLOAD`){r.push(e.file);return}if(e.validateResult?.type===`FILE_OVER_SIZE_LIMIT`){e.file.response||(e.file.response={}),e.file.response.error=e.file.response.error||t(e.validateResult.extra),n.push(e);return}i.push(e.file)}),{sizeLimitErrors:n,beforeUploadErrorFiles:r,toFiles:i}}function mz(e){return e.isBatchUpload&&e.status||e.status===`fail`?`reupload`:e.status===`progress`?`uploading`:e.status===`success`||!e.autoUpload&&e.status===`waiting`?e.multiple?`continueUpload`:`reupload`:`fileInput`}function hz(e){var t=e.multiple,n=e.uploadValue,r=e.toUploadFiles,i=e.autoUpload,a=i?r:r.filter(function(e){return e.status!==`success`});return t&&!e.isBatchUpload?i?(a.length?n.concat(a):n)||[]:n:(a.length?a:n)||[]}function gz(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _z(e){for(var t=1;t{},Mz=Array.isArray;function Nz(e,t){let n={};for(let r in e)n[r]=r in t?t[r]:e[r];return n}var Pz=Symbol(``);function Fz(e,t){return kz(Error(),{type:e,[Pz]:!0},t)}function Iz(e,t){return e instanceof Error&&Pz in e&&(t==null||!!(e.type&t))}var Lz=Symbol(``),Rz=Symbol(``),zz=Symbol(``),Bz=Symbol(``),Vz=Symbol(``);function Hz(){return wn(zz)}function Uz(e){return wn(Bz)}var Wz=/#/g,Gz=/&/g,Kz=/\//g,qz=/=/g,Jz=/\?/g,Yz=/\+/g,Xz=/%5B/g,Zz=/%5D/g,Qz=/%5E/g,$z=/%60/g,eB=/%7B/g,tB=/%7C/g,nB=/%7D/g,rB=/%20/g;function iB(e){return e==null?``:encodeURI(``+e).replace(tB,`|`).replace(Xz,`[`).replace(Zz,`]`)}function aB(e){return iB(e).replace(eB,`{`).replace(nB,`}`).replace(Qz,`^`)}function oB(e){return iB(e).replace(Yz,`%2B`).replace(rB,`+`).replace(Wz,`%23`).replace(Gz,`%26`).replace($z,"`").replace(eB,`{`).replace(nB,`}`).replace(Qz,`^`)}function sB(e){return oB(e).replace(qz,`%3D`)}function cB(e){return iB(e).replace(Wz,`%23`).replace(Jz,`%3F`)}function lB(e){return cB(e).replace(Kz,`%2F`)}function uB(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var dB=/\/$/,fB=e=>e.replace(dB,``);function pB(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=xB(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:uB(o)}}function mB(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function hB(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function gB(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&_B(t.matched[r],n.matched[i])&&vB(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function _B(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function vB(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!yB(e[n],t[n]))return!1;return!0}function yB(e,t){return Mz(e)?bB(e,t):Mz(t)?bB(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function bB(e,t){return Mz(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function xB(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var SB={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function CB(e){if(!e)if(Ez){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),fB(e)}var wB=/^[^#]+#/;function TB(e,t){return e.replace(wB,`#`)+t}function EB(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var DB=()=>({left:window.scrollX,top:window.scrollY});function OB(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=EB(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function kB(e,t){return(history.state?history.state.position-t:-1)+e}var AB=new Map;function jB(e,t){AB.set(e,t)}function MB(e){let t=AB.get(e);return AB.delete(e),t}function NB(e){return typeof e==`string`||e&&typeof e==`object`}function PB(e){return typeof e==`string`||typeof e==`symbol`}function FB(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;ee&&oB(e)):[r&&oB(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function LB(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=Mz(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function RB(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function zB(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(Fz(4,{from:n,to:t})):e instanceof Error?c(e):NB(e)?c(Fz(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function BB(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(Dz(s)){let c=(s.__vccOpts||s)[t];c&&a.push(zB(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=Oz(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&zB(c,n,r,o,e,i)()}))}}return a}function VB(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o_B(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>_B(e,s))||i.push(s))}return[n,r,i]}var HB=()=>location.protocol+`//`+location.host;function UB(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),hB(n,``)}return hB(n,e)+r+i}function WB(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=UB(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(kz({},e.state,{scroll:DB()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function GB(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?DB():null}}function KB(e){let{history:t,location:n}=window,r={value:UB(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:HB()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,kz({},t.state,GB(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=kz({},i.value,t.state,{forward:e,scroll:DB()});a(o.current,o,!0),a(e,kz({},GB(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function qB(e){e=CB(e);let t=KB(e),n=WB(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=kz({location:``,base:e,go:r,createHref:TB.bind(null,e)},t,n);return Object.defineProperty(i,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,"state",{enumerable:!0,get:()=>t.state.value}),i}function JB(e){return e=location.host?e||location.pathname+location.search:``,e.includes(`#`)||(e+=`#`),qB(e)}var YB={type:0,value:``},XB=/[a-zA-Z0-9_]/;function ZB(e){if(!e)return[[]];if(e===`/`)return[[YB]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;st.length?t.length===1&&t[0]===80?1:-1:0}function rV(e,t){let n=0,r=e.score,i=t.score;for(;n0&&t[t.length-1]<0}var aV={strict:!1,end:!0,sensitive:!1};function oV(e,t,n){let r=kz(tV(ZB(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function sV(e,t){let n=[],r=new Map;t=Nz(aV,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=lV(e);s.aliasOf=r&&r.record;let l=Nz(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(lV(kz({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=oV(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!dV(d)&&o(e.name)),hV(d)&&c(d),s.children){let e=s.children;for(let t=0;t{o(f)}:jz}function o(e){if(PB(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=pV(e,n);n.splice(t,0,e),e.record.name&&!dV(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw Fz(1,{location:e});s=i.record.name,a=kz(cV(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&cV(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw Fz(1,{location:e,currentLocation:t});s=i.record.name,a=kz({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:fV(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function cV(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function lV(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:uV(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function uV(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function dV(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function fV(e){return e.reduce((e,t)=>kz(e,t.meta),{})}function pV(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;rV(e,t[i])<0?r=i:n=i+1}let i=mV(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function mV(e){let t=e;for(;t=t.parent;)if(hV(t)&&rV(e,t)===0)return t}function hV({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function gV(e){let t=wn(zz),n=wn(Bz),r=U(()=>{let n=Ht(e.to);return t.resolve(n)}),i=U(()=>{let{matched:e}=r.value,{length:t}=e,i=e[t-1],a=n.matched;if(!i||!a.length)return-1;let o=a.findIndex(_B.bind(null,i));if(o>-1)return o;let s=xV(e[t-2]);return t>1&&xV(i)===s&&a[a.length-1].path!==s?a.findIndex(_B.bind(null,e[t-2])):o}),a=U(()=>i.value>-1&&bV(n.params,r.value.params)),o=U(()=>i.value>-1&&i.value===n.matched.length-1&&vB(n.params,r.value.params));function s(n={}){if(yV(n)){let n=t[Ht(e.replace)?`replace`:`push`](Ht(e.to)).catch(jz);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:r,href:U(()=>r.value.href),isActive:a,isExactActive:o,navigate:s}}function _V(e){return e.length===1?e[0]:e}var vV=z({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:gV,setup(e,{slots:t}){let n=Dt(gV(e)),{options:r}=wn(zz),i=U(()=>({[SV(e.activeClass,r.linkActiveClass,`router-link-active`)]:n.isActive,[SV(e.exactActiveClass,r.linkExactActiveClass,`router-link-exact-active`)]:n.isExactActive}));return()=>{let r=t.default&&_V(t.default(n));return e.custom?r:sa(`a`,{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:i.value},r)}}});function yV(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function bV(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!Mz(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function xV(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var SV=(e,t,n)=>e??t??n,CV=z({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){let r=wn(Vz),i=U(()=>e.route||r.value),a=wn(Rz,0),o=U(()=>{let e=Ht(a),{matched:t}=i.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),s=U(()=>i.value.matched[o.value]);Cn(Rz,U(()=>o.value+1)),Cn(Lz,s),Cn(Vz,i);let c=I();return R(()=>[c.value,s.value,e.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!_B(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let r=i.value,a=e.name,o=s.value,l=o&&o.components[a];if(!l)return wV(n.default,{Component:l,route:r});let u=o.props[a],d=sa(l,kz({},u?u===!0?r.params:typeof u==`function`?u(r):u:null,t,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(o.instances[a]=null)},ref:c}));return wV(n.default,{Component:d,route:r})||d}}});function wV(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var TV=CV;function EV(e){let t=sV(e.routes,e),n=e.parseQuery||FB,r=e.stringifyQuery||IB,i=e.history,a=RB(),o=RB(),s=RB(),c=Bt(SB),l=SB;Ez&&e.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let u=Az.bind(null,e=>``+e),d=Az.bind(null,lB),f=Az.bind(null,uB);function p(e,n){let r,i;return PB(e)?(r=t.getRecordMatcher(e),i=n):i=e,t.addRoute(i,r)}function m(e){let n=t.getRecordMatcher(e);n&&t.removeRoute(n)}function h(){return t.getRoutes().map(e=>e.record)}function g(e){return!!t.getRecordMatcher(e)}function _(e,a){if(a=kz({},a||c.value),typeof e==`string`){let r=pB(n,e,a.path),o=t.resolve({path:r.path},a),s=i.createHref(r.fullPath);return kz(r,o,{params:f(o.params),redirectedFrom:void 0,href:s})}let o;if(e.path!=null)o=kz({},e,{path:pB(n,e.path,a.path).path});else{let t=kz({},e.params);for(let e in t)t[e]??delete t[e];o=kz({},e,{params:d(t)}),a.params=d(a.params)}let s=t.resolve(o,a),l=e.hash||``;s.params=u(f(s.params));let p=mB(r,kz({},e,{hash:aB(l),path:s.path})),m=i.createHref(p);return kz({fullPath:p,hash:l,query:r===IB?LB(e.query):e.query||{}},s,{redirectedFrom:void 0,href:m})}function v(e){return typeof e==`string`?pB(n,e,c.value.path):kz({},e)}function y(e,t){if(l!==e)return Fz(8,{from:t,to:e})}function b(e){return C(e)}function x(e){return b(kz(v(e),{replace:!0}))}function S(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=v(i):{path:i},i.params={}),kz({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function C(e,t){let n=l=_(e),i=c.value,a=e.state,o=e.force,s=e.replace===!0,u=S(n,i);if(u)return C(kz(v(u),{state:typeof u==`object`?kz({},a,u.state):a,force:o,replace:s}),t||n);let d=n;d.redirectedFrom=t;let f;return!o&&gB(r,i,n)&&(f=Fz(16,{to:d,from:i}),te(i,i,!0,!1)),(f?Promise.resolve(f):E(d,i)).catch(e=>Iz(e)?Iz(e,2)?e:F(e):N(e,d,i)).then(e=>{if(e){if(Iz(e,2))return C(kz({replace:s},v(e.to),{state:typeof e.to==`object`?kz({},a,e.to.state):a,force:o}),t||d)}else e=O(d,i,!0,s,a);return D(d,i,e),e})}function w(e,t){let n=y(e,t);return n?Promise.reject(n):Promise.resolve()}function T(e){let t=ie.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function E(e,t){let n,[r,i,s]=VB(e,t);n=BB(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push(zB(r,e,t))});let c=w.bind(null,e,t);return n.push(c),oe(n).then(()=>{n=[];for(let r of a.list())n.push(zB(r,e,t));return n.push(c),oe(n)}).then(()=>{n=BB(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push(zB(r,e,t))});return n.push(c),oe(n)}).then(()=>{n=[];for(let r of s)if(r.beforeEnter)if(Mz(r.beforeEnter))for(let i of r.beforeEnter)n.push(zB(i,e,t));else n.push(zB(r.beforeEnter,e,t));return n.push(c),oe(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=BB(s,`beforeRouteEnter`,e,t,T),n.push(c),oe(n))).then(()=>{n=[];for(let r of o.list())n.push(zB(r,e,t));return n.push(c),oe(n)}).catch(e=>Iz(e,8)?e:Promise.reject(e))}function D(e,t,n){s.list().forEach(r=>T(()=>r(e,t,n)))}function O(e,t,n,r,a){let o=y(e,t);if(o)return o;let s=t===SB,l=Ez?history.state:{};n&&(r||s?i.replace(e.fullPath,kz({scroll:s&&l&&l.scroll},a)):i.push(e.fullPath,a)),c.value=e,te(e,t,n,s),F()}let k;function A(){k||=i.listen((e,t,n)=>{if(!ae.listening)return;let r=_(e),a=S(r,ae.currentRoute.value);if(a){C(kz(a,{replace:!0,force:!0}),r).catch(jz);return}l=r;let o=c.value;Ez&&jB(kB(o.fullPath,n.delta),DB()),E(r,o).catch(e=>Iz(e,12)?e:Iz(e,2)?(C(kz(v(e.to),{force:!0}),r).then(e=>{Iz(e,20)&&!n.delta&&n.type===`pop`&&i.go(-1,!1)}).catch(jz),Promise.reject()):(n.delta&&i.go(-n.delta,!1),N(e,r,o))).then(e=>{e||=O(r,o,!1),e&&(n.delta&&!Iz(e,8)?i.go(-n.delta,!1):n.type===`pop`&&Iz(e,20)&&i.go(-1,!1)),D(r,o,e)}).catch(jz)})}let j=RB(),M=RB(),ee;function N(e,t,n){F(e);let r=M.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function P(){return ee&&c.value!==SB?Promise.resolve():new Promise((e,t)=>{j.add([e,t])})}function F(e){return ee||(ee=!e,A(),j.list().forEach(([t,n])=>e?n(e):t()),j.reset()),e}function te(t,n,r,i){let{scrollBehavior:a}=e;if(!Ez||!a)return Promise.resolve();let o=!r&&MB(kB(t.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return dn().then(()=>a(t,n,o)).then(e=>e&&OB(e)).catch(e=>N(e,t,n))}let ne=e=>i.go(e),re,ie=new Set,ae={currentRoute:c,listening:!0,addRoute:p,removeRoute:m,clearRoutes:t.clearRoutes,hasRoute:g,getRoutes:h,resolve:_,options:e,push:b,replace:x,go:ne,back:()=>ne(-1),forward:()=>ne(1),beforeEach:a.add,beforeResolve:o.add,afterEach:s.add,onError:M.add,isReady:P,install(e){e.component(`RouterLink`,vV),e.component(`RouterView`,TV),e.config.globalProperties.$router=ae,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>Ht(c)}),Ez&&!re&&c.value===SB&&(re=!0,b(i.location).catch(e=>{}));let t={};for(let e in SB)Object.defineProperty(t,e,{get:()=>c.value[e],enumerable:!0});e.provide(zz,ae),e.provide(Bz,Ot(t)),e.provide(Vz,c);let n=e.unmount;ie.add(e),e.unmount=function(){ie.delete(e),ie.size<1&&(l=SB,k&&k(),k=null,c.value=SB,re=!1,ee=!1),n()}}};function oe(e){return e.reduce((e,t)=>e.then(()=>T(t)),Promise.resolve())}return ae}var DV=Dt({ready:!1,user:null,csrf:``,pendingToken:``}),OV=Dt({subscriptionEnabled:!1,loaded:!1,loading:!1}),kV=()=>(document.querySelector(`meta[name="plugin-base-path"]`)?.getAttribute(`content`)||``).replace(/\/$/,``),AV=class extends Error{status;constructor(e,t=0){super(e),this.name=`ApiError`,this.status=t}};async function jV(e,t={}){let n=new Headers(t.headers||{});n.set(`Accept`,`application/json`);let r=(t.method||`GET`).toUpperCase();t.body&&!(t.body instanceof FormData)&&n.set(`Content-Type`,`application/json`),DV.csrf&&r!==`GET`&&n.set(`X-CSRF-Token`,DV.csrf);let i=await fetch(`${kV()}${e}`,{...t,method:r,headers:n,credentials:`same-origin`}),a=await i.json().catch(()=>({}));if(!i.ok)throw i.status===401&&!e.startsWith(`/login`)&&(DV.user=null,DV.csrf=``),new AV(a?.error||`请求失败 (${i.status})`,i.status);return a}async function MV(){try{let e=await jV(`/api/me`);DV.user=e.user||null,DV.csrf=e.csrf_token||``}catch{DV.user=null,DV.csrf=``,OV.loaded=!1,OV.subscriptionEnabled=!1}finally{DV.ready=!0}}async function NV(){let e=await jV(`/api/captcha-config`);return{enabled:e.enabled===!0,provider:e.provider||``,turnstile_enabled:e.turnstile_enabled===!0,turnstile_site_key:String(e.turnstile_site_key||``),tencent_captcha_enabled:e.tencent_captcha_enabled===!0,tencent_captcha_app_id:String(e.tencent_captcha_app_id||``),tencent_captcha_region:String(e.tencent_captcha_region||`cn`),aliyun_captcha_enabled:e.aliyun_captcha_enabled===!0,aliyun_captcha_scene_id:String(e.aliyun_captcha_scene_id||``),aliyun_captcha_prefix:String(e.aliyun_captcha_prefix||``),aliyun_captcha_region:String(e.aliyun_captcha_region||`cn`)}}async function PV(e=!1){if(OV.loaded&&!e)return OV.subscriptionEnabled;if(OV.loading)return await new Promise(e=>{let t=window.setInterval(()=>{OV.loading||(window.clearInterval(t),e())},20)}),OV.subscriptionEnabled;OV.loading=!0;try{OV.subscriptionEnabled=(RV(await jV(`/api/subscription/status`))||{}).enabled===!0}catch{OV.subscriptionEnabled=!1}finally{OV.loaded=!0,OV.loading=!1}return OV.subscriptionEnabled}async function FV(e,t,n={}){let r=await jV(`/login`,{method:`POST`,body:JSON.stringify({email:e,password:t,...n})});return r.requires_2fa?(DV.pendingToken=r.pending_token||``,{requires2fa:!0}):(DV.pendingToken=``,DV.user=r.user||null,DV.csrf=r.csrf_token||``,OV.loaded=!1,{requires2fa:!1})}async function IV(e){let t=await jV(`/login/2fa`,{method:`POST`,body:JSON.stringify({pending_token:DV.pendingToken,totp_code:e})});DV.pendingToken=``,DV.user=t.user||null,DV.csrf=t.csrf_token||``,OV.loaded=!1}async function LV(){try{await jV(`/logout`,{method:`POST`})}finally{DV.user=null,DV.csrf=``,DV.pendingToken=``,OV.loaded=!1,OV.subscriptionEnabled=!1}}function RV(e){return e&&Object.prototype.hasOwnProperty.call(e,`data`)&&(`code`in e||`message`in e)?e.data:e}function zV(e){let t=RV(e);return Array.isArray(t)?t:Array.isArray(t?.items)?t.items:Array.isArray(t?.list)?t.list:Array.isArray(t?.rows)?t.rows:[]}function BV(e){if(!e)return`-`;let t=new Date(String(e));return Number.isNaN(t.getTime())?String(e):t.toLocaleString(`zh-CN`,{hour12:!1})}function VV(e){return{healthy:`运行中`,enabled:`运行中`,disabled:`已停用`,incompatible:`Core 不兼容`,error:`启用失败`,starting:`启动中`,draining:`停用中`,upgrading:`升级中`,rollback_pending:`等待回滚`}[String(e)]||String(e||`未知`)}function HV(e){return[`completed`,`success`,`succeeded`].includes(String(e||``).toLowerCase())}function UV(e){let t=String(e||``).toLowerCase();return HV(t)?`success`:t===`failed`||t===`error`?`danger`:`warning`}function WV(e,t=``){return`${e}-${t}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}var GV={class:`brand`},KV={class:`brand-mark`},qV={class:`aside-footer`},JV={class:`header-left`},YV={class:`breadcrumbs`},XV={class:`header-right`},ZV={class:`user-name`},QV=z({__name:`Shell`,setup(e){let t=Uz(),n=Hz(),r=I(!1),i=U(()=>OV.subscriptionEnabled),a=U(()=>String(t.meta.title||(t.path.startsWith(`/modules/subscription`)?`订阅管理`:`概览`))),o=U(()=>t.path.startsWith(`/plugins`)?`/plugins`:t.path.startsWith(`/modules/subscription`)?`/modules/subscription/overview`:t.path),s=U(()=>String(DV.user?.email||DV.user?.username||`管理员`)),c=[{content:`退出登录`,value:`logout`}];async function l(){await PV(!0)}function u(e){let t=String(e);if(t===`/modules/subscription/overview`&&!i.value){eb.warning(`请先安装并启用订阅模块`);return}n.push(t),r.value=!1}async function d(e){String(e?.value||``)===`logout`&&(await LV(),n.push(`/login`))}return mr(l),(e,t)=>{let n=br(`t-menu-item`),l=br(`t-divider`),f=br(`t-menu`),p=br(`t-tag`),m=br(`t-aside`),h=br(`t-button`),g=br(`t-dropdown`),_=br(`t-header`),v=br(`router-view`),y=br(`t-content`),b=br(`t-layout`);return Ei(),ji(b,{class:`app-shell`},{default:L(()=>[r.value?(Ei(),Ai(`div`,{key:0,class:`mobile-scrim`,onClick:t[0]||=e=>r.value=!1})):Bi(``,!0),V(m,{class:de([`app-aside`,{"app-aside-mobile-open":r.value}]),width:`252px`},{default:L(()=>[B(`div`,GV,[B(`div`,KV,[V(Ht(Pg),{size:`22px`})]),t[2]||=B(`div`,null,[B(`div`,{class:`brand-title`},`Sub2API`),B(`div`,{class:`brand-subtitle`},`插件控制面`)],-1)]),t[11]||=B(`div`,{class:`nav-caption`},`控制台`,-1),V(f,{value:o.value,class:`main-menu`,onChange:u},{default:L(()=>[V(n,{value:`/overview`},{icon:L(()=>[V(Ht(pce))]),default:L(()=>[t[3]||=zi(`概览`,-1)]),_:1}),V(n,{value:`/plugins`},{icon:L(()=>[V(Ht(Oh))]),default:L(()=>[t[4]||=zi(`已安装插件`,-1)]),_:1}),V(n,{value:`/marketplace`},{icon:L(()=>[V(Ht(Sle))]),default:L(()=>[t[5]||=zi(`插件市场`,-1)]),_:1}),V(n,{value:`/operations`},{icon:L(()=>[V(Ht(x_))]),default:L(()=>[t[6]||=zi(`操作记录`,-1)]),_:1}),i.value?(Ei(),Ai(bi,{key:0},[V(l,{class:`nav-divider`}),t[7]||=B(`div`,{class:`nav-caption nav-caption-module`},`业务模块`,-1)],64)):Bi(``,!0),i.value?(Ei(),ji(n,{key:1,value:`/modules/subscription/overview`},{icon:L(()=>[V(Ht(Yh))]),default:L(()=>[t[8]||=zi(`订阅管理 `,-1)]),_:1})):Bi(``,!0)]),_:1},8,[`value`]),B(`div`,qV,[V(p,{theme:`success`,variant:`light`,class:`status-tag`},{default:L(()=>[V(Ht(tg),{size:`14px`}),t[9]||=zi(` Core 会话正常`,-1)]),_:1}),t[10]||=B(`span`,{class:`version-text`},`Plugin Admin v1.1.1`,-1)])]),_:1},8,[`class`]),V(b,{class:`main-layout`},{default:L(()=>[V(_,{class:`app-header`},{default:L(()=>[B(`div`,JV,[V(h,{class:`mobile-menu-button`,variant:`text`,shape:`square`,"aria-label":`打开导航`,onClick:t[1]||=e=>r.value=!0},{icon:L(()=>[V(Ht(Jce))]),_:1}),B(`div`,YV,[t[12]||=B(`span`,null,`插件管理`,-1),V(Ht(yg),{size:`15px`}),B(`strong`,null,ve(a.value),1)])]),B(`div`,XV,[V(p,{theme:`success`,variant:`light`,class:`secure-tag`},{default:L(()=>[V(Ht(tg),{size:`14px`}),t[13]||=zi(` 安全会话`,-1)]),_:1}),V(g,{options:c,trigger:`click`,onClick:d},{default:L(()=>[V(h,{variant:`text`,class:`user-button`},{icon:L(()=>[V(Ht(Nv))]),default:L(()=>[B(`span`,ZV,ve(s.value),1),V(Ht(sg),{size:`15px`})]),_:1})]),_:1})])]),_:1}),V(y,{class:`app-content`},{default:L(()=>[V(v)]),_:1})]),_:1})]),_:1})}}}),$V={key:0,class:`captcha-turnstile`},eH=z({__name:`TurnstileWidget`,props:{siteKey:{},theme:{default:`auto`},size:{default:`flexible`}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=I(null),o=null,s=null;function c(){return window.turnstile?Promise.resolve():s||(s=new Promise((e,t)=>{let n=document.querySelector(`script[src*="challenges.cloudflare.com/turnstile"]`);if(n){n.addEventListener(`load`,()=>window.turnstile?e():t(Error(`Turnstile SDK unavailable`)),{once:!0}),window.turnstile&&e();return}let r=document.createElement(`script`);r.src=`https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit`,r.async=!0,r.defer=!0,r.onload=()=>window.turnstile?e():t(Error(`Turnstile SDK unavailable`)),r.onerror=()=>t(Error(`Failed to load Turnstile SDK`)),document.head.appendChild(r)}).catch(e=>{throw s=null,e}),s)}function l(){if(!(!window.turnstile||!a.value||!r.siteKey)){if(o){try{window.turnstile.remove(o)}catch{}o=null}a.value.innerHTML=``,o=window.turnstile.render(a.value,{sitekey:r.siteKey,theme:r.theme,size:r.size,callback:e=>i(`verify`,e),"expired-callback":()=>i(`expire`),"error-callback":()=>i(`error`)})}}function u(){if(window.turnstile&&o)try{window.turnstile.reset(o)}catch{}}return t({reset:u}),mr(async()=>{if(r.siteKey)try{await c(),l()}catch(e){console.error(`Failed to initialize Turnstile:`,e),i(`error`)}}),R(()=>r.siteKey,e=>{e&&window.turnstile&&l()}),vr(()=>{if(window.turnstile&&o)try{window.turnstile.remove(o)}catch{}o=null}),(t,n)=>e.siteKey?(Ei(),Ai(`div`,$V,[B(`div`,{ref_key:`containerRef`,ref:a,class:`captcha-turnstile__container`},null,512)])):Bi(``,!0)}}),tH=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},nH=tH(eH,[[`__scopeId`,`data-v-dcfbd1a5`]]),rH={cn:`https://turing.captcha.qcloud.com/TJCaptcha.js`,intl:`https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js`},iH=null,aH=null;function oH(e){return e===`intl`?`intl`:`cn`}function sH(){return window.TCaptchaGlobal===!0?`intl`:`cn`}function cH(e=`cn`){return window.TencentCaptcha&&(aH===e||sH()===e)?Promise.resolve(window.TencentCaptcha):window.TencentCaptcha&&aH!==null&&aH!==e?Promise.reject(Error(`Tencent Captcha region changed; reload the page to apply it`)):iH&&aH===e?iH:(aH=e,iH=new Promise((t,n)=>{let r=document.querySelector(`script[src="${rH[e]}"]`);if(r){let i=()=>window.TencentCaptcha&&sH()===e?t(window.TencentCaptcha):n(Error(`Tencent Captcha SDK unavailable`));window.TencentCaptcha?i():r.addEventListener(`load`,i,{once:!0}),r.addEventListener(`error`,()=>n(Error(`Failed to load Tencent Captcha SDK`)),{once:!0});return}let i=document.createElement(`script`);i.src=rH[e],i.async=!0,i.onload=()=>{window.TencentCaptcha&&sH()===e?t(window.TencentCaptcha):n(Error(`Tencent Captcha SDK unavailable`))},i.onerror=()=>n(Error(`Failed to load Tencent Captcha SDK`)),document.head.appendChild(i)}).catch(e=>{throw iH=null,aH=null,e}),iH)}var lH={class:`captcha-action`},uH=[`disabled`],dH=tH(z({__name:`TencentCaptchaGate`,props:{appId:{},region:{default:`cn`}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=U(()=>oH(r.region)===`intl`),o=I(null),s=I(`idle`),c=null,l=null,u=null,d=null;function f(e){if(e.ret===2){s.value=`idle`,u?.(null),u=null,l=null;return}let t=e.ticket?.trim()||``,n=e.randstr?.trim()||``;if(!t||!n||t.startsWith(`trerror_`)||e.errorCode!==void 0){s.value=`idle`,u?.(null),u=null,l=null,i(`error`);return}let r={ticket:t,randstr:n};d=r,s.value=`verified`,i(`verify`,r),u?.(r),u=null,l=null}async function p(){let e=await cH(oH(r.region));if(!c)if(a.value){if(!o.value)throw Error(`Tencent Captcha container unavailable`);c=new e(o.value,r.appId,f,{enableAutoCheck:!1,type:`popup`})}else c=new e(r.appId,f,{userLanguage:`zh-cn`})}function m(){s.value===`verified`||s.value===`verifying`||(s.value=`verifying`,h())}async function h(){if(d){let e=d;return d=null,e}if(l)return l;let e=new Promise(e=>{u=e});l=e;try{await p(),c?.show()}catch(e){throw s.value=`idle`,u?.(null),u=null,l=null,i(`error`),e}return e}function g(){c?.destroy(),c=null,d=null,s.value=`idle`,u?.(null),u=null,l=null,i(`expire`)}return t({verify:h,reset:g}),mr(()=>{r.appId&&a.value&&p().catch(()=>i(`error`))}),_r(g),(e,t)=>(Ei(),Ai(`div`,lH,[a.value?(Ei(),Ai(`div`,{key:0,ref_key:`internationalContainerRef`,ref:o,class:`captcha-action__international`},null,512)):(Ei(),Ai(`button`,{key:1,type:`button`,class:`captcha-action__trigger`,disabled:s.value===`verified`||s.value===`verifying`,onClick:m},[B(`span`,{class:de([`captcha-action__dot`,{"is-verified":s.value===`verified`}])},null,2),zi(` `+ve(s.value===`verified`?`验证通过`:s.value===`verifying`?`验证中...`:`点击完成安全验证`),1)],8,uH))]))}}),[[`__scopeId`,`data-v-7fd83f77`]]),fH={key:0,class:`captcha-action`},pH=[`disabled`],mH=`https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js`,hH=tH(z({__name:`AliyunCaptchaWidget`,props:{sceneId:{},prefix:{},region:{default:`cn`}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=Math.random().toString(36).slice(2,10),o=`plugin-aliyun-captcha-button-${a}`,s=`plugin-aliyun-captcha-element-${a}`,c=I(`idle`),l=null,u=null,d=null,f=null,p=!1;function m(){return window.initAliyunCaptcha?Promise.resolve():l||(window.AliyunCaptchaConfig={region:r.region||`cn`,prefix:r.prefix},l=new Promise((e,t)=>{let n=document.querySelector(`script[src*="aliyunCaptcha/AliyunCaptcha"]`);if(n){n.addEventListener(`load`,()=>window.initAliyunCaptcha?e():t(Error(`Aliyun Captcha SDK unavailable`)),{once:!0}),n.addEventListener(`error`,()=>t(Error(`Failed to load Aliyun Captcha SDK`)),{once:!0});return}let r=document.createElement(`script`);r.src=mH,r.async=!0,r.onload=()=>window.initAliyunCaptcha?e():t(Error(`Aliyun Captcha SDK unavailable`)),r.onerror=()=>t(Error(`Failed to load Aliyun Captcha SDK`)),document.head.appendChild(r)}).catch(e=>{throw l=null,e}),l)}function h(e){f!==null&&(window.clearTimeout(f),f=null);let t=e.trim();if(!t){c.value=`idle`,d?.resolve(null),d=null,i(`error`);return}u=t,c.value=`verified`,i(`verify`,t),d?.resolve(t),d=null}function g(){if(!p){if(!window.initAliyunCaptcha)throw Error(`Aliyun Captcha SDK unavailable`);window.initAliyunCaptcha({SceneId:r.sceneId,prefix:r.prefix,mode:`popup`,element:`#${s}`,button:`#${o}`,captchaVerifyCallback:e=>(h(e),{captchaResult:!0}),onBizResultCallback:()=>void 0,getInstance:()=>void 0,slideStyle:{width:360,height:40},language:`cn`}),p=!0}}function _(){c.value===`verified`||c.value===`verifying`||(c.value=`verifying`,v().catch(()=>{c.value=`idle`,i(`error`)}))}async function v(){if(u){let e=u;return u=null,e}if(await m(),!window.initAliyunCaptcha)throw Error(`Aliyun Captcha SDK unavailable`);return g(),new Promise(e=>{d={resolve:e},f!==null&&window.clearTimeout(f),f=window.setTimeout(()=>{f=null,c.value=`idle`,d?.resolve(null),d=null},15e3),document.getElementById(o)?.click()})}function y(){f!==null&&(window.clearTimeout(f),f=null),u=null,c.value=`idle`,d?.resolve(null),d=null,document.getElementById(`aliyunCaptcha-mask`)?.remove(),document.getElementById(`aliyunCaptcha-window-popup`)?.remove(),i(`expire`)}return t({verify:v,reset:y}),mr(()=>{!r.sceneId||!r.prefix||m().then(g).catch(()=>i(`error`))}),vr(()=>{f!==null&&(window.clearTimeout(f),f=null),d?.resolve(null),d=null,document.getElementById(`aliyunCaptcha-mask`)?.remove(),document.getElementById(`aliyunCaptcha-window-popup`)?.remove()}),(t,n)=>e.sceneId&&e.prefix?(Ei(),Ai(`div`,fH,[B(`button`,{id:o,type:`button`,class:de([`captcha-action__trigger`,{"is-verified":c.value===`verified`}]),disabled:c.value===`verified`||c.value===`verifying`,onClick:_},[B(`span`,{class:de([`captcha-action__dot`,{"is-verified":c.value===`verified`}])},null,2),zi(` `+ve(c.value===`verified`?`验证通过`:c.value===`verifying`?`验证中...`:`点击完成安全验证`),1)],10,pH),B(`div`,{id:s})])):Bi(``,!0)}}),[[`__scopeId`,`data-v-8a1336a6`]]),gH={key:0,class:`captcha-challenge`,"aria-live":`polite`},_H={key:3,class:`captcha-challenge__missing`},vH=tH(z({__name:`CaptchaChallenge`,props:{enabled:{type:Boolean},provider:{},turnstileSiteKey:{},tencentAppId:{},tencentRegion:{},aliyunSceneId:{},aliyunPrefix:{},aliyunRegion:{}},emits:[`verify`,`expire`,`error`],setup(e,{expose:t,emit:n}){let r=e,i=n,a=I(null),o=I(null),s=I(null),c=I(``),l=I(null),u=I(``),d=U(()=>r.provider);function f(e){c.value=e,i(`verify`,{token:e,randstr:``,provider:`turnstile`})}function p(e){l.value=e,i(`verify`,{token:e.ticket,randstr:e.randstr,provider:`tencent`})}function m(e){u.value=e,i(`verify`,{token:e,randstr:``,provider:`aliyun`})}function h(){c.value=``,l.value=null,u.value=``,i(`expire`)}function g(){h(),i(`error`)}async function _(){if(!r.enabled)return null;if(d.value===`turnstile`)return c.value?{token:c.value,randstr:``,provider:`turnstile`}:null;if(d.value===`tencent`){let e=l.value||await o.value?.verify()||null;return e?{token:e.ticket,randstr:e.randstr,provider:`tencent`}:null}if(d.value===`aliyun`){let e=u.value||await s.value?.verify()||``;return e?{token:e,randstr:``,provider:`aliyun`}:null}return null}function v(){c.value=``,l.value=null,u.value=``,a.value?.reset(),o.value?.reset(),s.value?.reset()}return t({verifyAction:_,reset:v}),(t,n)=>e.enabled?(Ei(),Ai(`div`,gH,[d.value===`turnstile`&&e.turnstileSiteKey?(Ei(),ji(nH,{key:0,ref_key:`turnstileRef`,ref:a,"site-key":e.turnstileSiteKey,onVerify:f,onExpire:h,onError:g},null,8,[`site-key`])):d.value===`tencent`&&e.tencentAppId?(Ei(),ji(dH,{key:1,ref_key:`tencentRef`,ref:o,"app-id":e.tencentAppId,region:e.tencentRegion,onVerify:p,onExpire:h,onError:g},null,8,[`app-id`,`region`])):d.value===`aliyun`&&e.aliyunSceneId&&e.aliyunPrefix?(Ei(),ji(hH,{key:2,ref_key:`aliyunRef`,ref:s,"scene-id":e.aliyunSceneId,prefix:e.aliyunPrefix,region:e.aliyunRegion,onVerify:m,onExpire:h,onError:g},null,8,[`scene-id`,`prefix`,`region`])):(Ei(),Ai(`div`,_H,`验证码配置不完整,请联系管理员`))])):Bi(``,!0)}}),[[`__scopeId`,`data-v-be35acfe`]]),yH={class:`login-page`},bH={class:`login-layout`},xH={class:`login-intro`},SH={class:`brand brand-login`},CH={class:`brand-mark`},wH={class:`login-points`},TH={class:`login-card-heading`},EH={class:`login-security`},DH=z({__name:`Login`,setup(e){let t=Hz(),n=I(!1),r=I(!1),i=I(``),a=I(!1),o=I(``),s=I(null),c=I(null),l=Dt({enabled:!1,provider:``,turnstile_enabled:!1,turnstile_site_key:``,tencent_captcha_enabled:!1,tencent_captcha_app_id:``,tencent_captcha_region:`cn`,aliyun_captcha_enabled:!1,aliyun_captcha_scene_id:``,aliyun_captcha_prefix:``,aliyun_captcha_region:`cn`}),u=Dt({email:``,password:``}),d=Dt({totp_code:``}),f={email:[{required:!0,message:`请输入管理员邮箱`,type:`error`}],password:[{required:!0,message:`请输入密码`,type:`error`}]};async function p(){if(!u.email.trim()||!u.password){i.value=`请输入邮箱和密码`;return}n.value=!0,i.value=``;try{let e=l.enabled&&await s.value?.verifyAction()||null;if(l.enabled&&!e){i.value=`请先完成安全验证`;return}c.value=e;let n=e?.provider===`tencent`?{tencent_captcha_ticket:e.token,tencent_captcha_randstr:e.randstr}:e?.provider===`aliyun`||e?.provider===`turnstile`?{turnstile_token:e.token}:{};(await FV(u.email.trim(),u.password,n)).requires2fa?r.value=!0:(eb.success(`登录成功`),t.push(`/overview`))}catch(e){i.value=e instanceof Error?e.message:`登录失败,请稍后重试`}finally{s.value?.reset(),c.value=null,n.value=!1}}async function m(){if(!/^\d{6}$/.test(d.totp_code)){i.value=`请输入 6 位数字验证码`;return}n.value=!0,i.value=``;try{await IV(d.totp_code),eb.success(`登录成功`),t.push(`/overview`)}catch(e){i.value=e instanceof Error?e.message:`验证码校验失败`}finally{n.value=!1}}function h(){r.value=!1,d.totp_code=``,i.value=``}function g(e){c.value=e,i.value=``}function _(){c.value=null}function v(){c.value=null,i.value=`安全验证加载失败,请刷新页面重试`}return mr(async()=>{o.value=``;try{let e=await NV();Object.assign(l,e),[e.turnstile_enabled,e.tencent_captcha_enabled,e.aliyun_captcha_enabled].filter(Boolean).length>1?o.value=`Core 同时启用了多个验证码服务,请保留一个服务商后重试`:e.enabled&&!e.provider&&(o.value=`验证码配置不完整,请联系管理员`)}catch(e){o.value=e instanceof Error?`验证码配置加载失败:${e.message}`:`验证码配置加载失败,请刷新页面重试`}finally{a.value=!0}}),(e,t)=>{let c=br(`t-tag`),y=br(`t-alert`),b=br(`t-input`),x=br(`t-form-item`),S=br(`t-button`),C=br(`t-form`),w=br(`t-card`);return Ei(),Ai(`main`,yH,[t[18]||=B(`div`,{class:`login-accent`},null,-1),B(`section`,bH,[B(`div`,xH,[B(`div`,SH,[B(`div`,CH,[V(Ht(Pg),{size:`24px`})]),t[3]||=B(`div`,null,[B(`div`,{class:`brand-title`},`Sub2API`),B(`div`,{class:`brand-subtitle`},`插件控制面`)],-1)]),t[7]||=B(`p`,{class:`eyebrow`},`BUSINESS PLUGIN CONTROL PLANE`,-1),t[8]||=B(`h1`,null,`统一管理你的业务插件`,-1),t[9]||=B(`p`,{class:`login-lead`},`使用 Core 管理员会话进入插件市场、生命周期和业务模块。所有插件操作都在同一安全控制面完成。`,-1),B(`div`,wH,[B(`div`,null,[V(Ht(tg),{size:`18px`}),t[4]||=B(`span`,null,`一次登录,访问已启用业务模块`,-1)]),B(`div`,null,[V(Ht(tg),{size:`18px`}),t[5]||=B(`span`,null,`凭据仅保存在服务端会话`,-1)]),B(`div`,null,[V(Ht(tg),{size:`18px`}),t[6]||=B(`span`,null,`每次变更都有可追溯操作记录`,-1)])])]),V(w,{class:`login-card`,bordered:!0},{default:L(()=>[B(`div`,TH,[t[11]||=B(`div`,null,[B(`p`,{class:`eyebrow`},`ADMIN ACCESS`),B(`h2`,null,`管理员登录`)],-1),V(c,{theme:`primary`,variant:`light`},{default:L(()=>[...t[10]||=[zi(`仅管理员`,-1)]]),_:1})]),t[17]||=B(`p`,{class:`muted`},`使用 Sub2API Core 的管理员账号登录,普通账号没有访问权限。`,-1),o.value?(Ei(),ji(y,{key:0,class:`login-error`,theme:`warning`,message:o.value},null,8,[`message`])):Bi(``,!0),r.value?(Ei(),ji(C,{key:2,class:`login-form`,data:d,onSubmit:m},{default:L(()=>[V(y,{theme:`info`,title:`需要二次验证`},{default:L(()=>[...t[13]||=[zi(`请输入 Core 返回的 6 位验证码。`,-1)]]),_:1}),V(x,{label:`验证码`,name:`totp_code`},{default:L(()=>[V(b,{modelValue:d.totp_code,"onUpdate:modelValue":t[2]||=e=>d.totp_code=e,inputmode:`numeric`,maxlength:`6`,placeholder:`000000`},null,8,[`modelValue`])]),_:1}),V(S,{theme:`primary`,type:`submit`,block:``,loading:n.value},{icon:L(()=>[V(Ht(tg))]),default:L(()=>[t[14]||=zi(`验证并继续`,-1)]),_:1},8,[`loading`]),V(S,{variant:`text`,block:``,onClick:h},{default:L(()=>[...t[15]||=[zi(`返回账号登录`,-1)]]),_:1})]),_:1},8,[`data`])):(Ei(),ji(C,{key:1,ref:`loginForm`,class:`login-form`,data:u,rules:f,onSubmit:p},{default:L(()=>[V(x,{label:`邮箱`,name:`email`},{default:L(()=>[V(b,{modelValue:u.email,"onUpdate:modelValue":t[0]||=e=>u.email=e,type:`text`,"aria-label":`邮箱`,autocomplete:`username`,placeholder:`admin@example.com`},null,8,[`modelValue`])]),_:1}),V(x,{label:`密码`,name:`password`},{default:L(()=>[V(b,{modelValue:u.password,"onUpdate:modelValue":t[1]||=e=>u.password=e,type:`password`,"aria-label":`密码`,autocomplete:`current-password`,placeholder:`输入管理员密码`},null,8,[`modelValue`])]),_:1}),a.value&&l.enabled?(Ei(),ji(vH,{key:0,ref_key:`captchaRef`,ref:s,enabled:l.enabled,provider:l.provider,"turnstile-site-key":l.turnstile_site_key,"tencent-app-id":l.tencent_captcha_app_id,"tencent-region":l.tencent_captcha_region,"aliyun-scene-id":l.aliyun_captcha_scene_id,"aliyun-prefix":l.aliyun_captcha_prefix,"aliyun-region":l.aliyun_captcha_region,onVerify:g,onExpire:_,onError:v},null,8,[`enabled`,`provider`,`turnstile-site-key`,`tencent-app-id`,`tencent-region`,`aliyun-scene-id`,`aliyun-prefix`,`aliyun-region`])):Bi(``,!0),V(S,{theme:`primary`,type:`submit`,block:``,loading:n.value,disabled:!a.value||!!o.value},{icon:L(()=>[V(Ht(Nv))]),default:L(()=>[t[12]||=zi(`登录`,-1)]),_:1},8,[`loading`,`disabled`])]),_:1},8,[`data`])),i.value?(Ei(),ji(y,{key:3,class:`login-error`,theme:`error`,message:i.value},null,8,[`message`])):Bi(``,!0),B(`div`,EH,[V(Ht(F_),{size:`15px`}),t[16]||=zi(` HttpOnly 会话 · CSRF 保护 · 8 小时绝对有效期`,-1)])]),_:1})])])}}}),OH={class:`page-header`},kH={class:`eyebrow`},AH={class:`page-subtitle`},jH={class:`page-actions`},MH=z({__name:`PageHeader`,props:{eyebrow:{},title:{},subtitle:{}},setup(e){return(t,n)=>(Ei(),Ai(`header`,OH,[B(`div`,null,[B(`p`,kH,ve(e.eyebrow),1),B(`h1`,null,ve(e.title),1),B(`p`,AH,ve(e.subtitle),1)]),B(`div`,jH,[Dee(t.$slots,`actions`)])]))}}),NH=function(e,t){return NH=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},NH(e,t)};function PH(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);NH(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var FH=`12px sans-serif`,IH=20,LH=100,RH=`007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N`;function zH(e){var t={};if(typeof JSON>`u`)return t;for(var n=0;n=0)s=o*n.length;else for(var c=0;c=eU&&($H=0),$H++}function nU(){var e=[...arguments];typeof console<`u`&&console.error.apply(console,e)}function rU(e){if(typeof e!=`object`||!e)return e;var t=e,n=WH.call(e);if(n===`[object Array]`){if(!VU(e)){t=[];for(var r=0,i=e.length;r`u`&&typeof self<`u`?eW.worker=!0:!eW.hasGlobalWindow||`Deno`in window||typeof navigator<`u`&&typeof navigator.userAgent==`string`&&navigator.userAgent.indexOf(`Node.js`)>-1?(eW.node=!0,eW.svgSupported=!0):tW(navigator.userAgent,eW);function tW(e,t){var n=t.browser,r=e.match(/Firefox\/([\d.]+)/),i=e.match(/MSIE\s([\d.]+)/)||e.match(/Trident\/.+?rv:(([\d.]+))/),a=e.match(/Edge?\/([\d.]+)/),o=/micromessenger/i.test(e);if(r&&(n.firefox=!0,n.version=r[1]),i&&(n.ie=!0,n.version=i[1]),a&&(n.edge=!0,n.version=a[1],n.newEdge=+a[1].split(`.`)[0]>18),o&&(n.weChat=!0),t.svgSupported=typeof SVGRect<`u`,t.touchEventsSupported=`ontouchstart`in window&&!n.ie&&!n.edge,t.pointerEventsSupported=`onpointerdown`in window&&(n.edge||n.ie&&+n.version>=11),t.domSupported=typeof document<`u`){var s=document.documentElement.style;t.transform3dSupported=(n.ie&&`transition`in s||n.edge||`WebKitCSSMatrix`in window&&`m11`in new WebKitCSSMatrix||`MozPerspective`in s)&&!(`OTransition`in s),t.transformSupported=t.transform3dSupported||n.ie&&+n.version>=9}}var nW=`.`,rW=`___EC__COMPONENT__CONTAINER___`,iW=`___EC__EXTENDED_CLASS___`;function aW(e){var t={main:``,sub:``};if(e){var n=e.split(nW);t.main=n[0]||``,t.sub=n[1]||``}return t}function oW(e){LU(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(e),`componentType "`+e+`" illegal`)}function sW(e){return!!(e&&e[iW])}function cW(e,t){e.$constructor=e,e.extend=function(e){var t=this,n;return lW(t)?n=function(e){PH(t,e);function t(){return e.apply(this,arguments)||this}return t}(t):(n=function(){(e.$constructor||t).apply(this,arguments)},lU(n,this)),aU(n.prototype,e),n[iW]=!0,n.extend=this.extend,n.superCall=pW,n.superApply=mW,n.superClass=t,n}}function lW(e){return xU(e)&&/^class\s/.test(Function.prototype.toString.call(e))}function uW(e,t){e.extend=t.extend}var dW=Math.round(Math.random()*10);function fW(e){var t=[`__\0is_clz`,dW++].join(`_`);e.prototype[t]=!0,e.isInstance=function(e){return!!(e&&e[t])}}function pW(e,t){var n=[...arguments].slice(2);return this.superClass.prototype[t].apply(e,n)}function mW(e,t,n){return this.superClass.prototype[t].apply(e,n)}function hW(e){var t={};e.registerClass=function(e){var r=e.type||e.prototype.type;if(r){oW(r),e.prototype.type=r;var i=aW(r);if(!i.sub)t[i.main]=e;else if(i.sub!==rW){var a=n(i);a[i.sub]=e}}return e},e.getClass=function(e,n,r){var i=t[e];if(i&&i[rW]&&(i=n?i[n]:null),r&&!i)throw Error(n?`Component `+e+`.`+(n||``)+` is used but not imported.`:e+`.type should be specified.`);return i},e.getClassesByMainType=function(e){var n=aW(e),r=[],i=t[n.main];return i&&i[rW]?$(i,function(e,t){t!==rW&&r.push(e)}):r.push(i),r},e.hasClass=function(e){return!!t[aW(e).main]},e.getAllClassMainTypes=function(){var e=[];return $(t,function(t,n){e.push(n)}),e},e.hasSubTypes=function(e){var n=t[aW(e).main];return n&&n[rW]};function n(e){var n=t[e.main];return(!n||!n[rW])&&(n=t[e.main]={},n[rW]=!0),n}}function gW(e,t){for(var n=0;n=0||i&&cU(i,s)<0)){var c=n.getShallow(s,t);c!=null&&(a[e[o][0]]=c)}}return a}}var _W=gW([[`fill`,`color`],[`shadowBlur`],[`shadowOffsetX`],[`shadowOffsetY`],[`opacity`],[`shadowColor`]]),vW=function(){function e(){}return e.prototype.getAreaStyle=function(e,t){return _W(this,e,t)},e}(),yW=function(e,t){return yW=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},yW(e,t)};function bW(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);yW(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var xW=function(){function e(e){this.value=e}return e}(),SW=function(){function e(){this._len=0}return e.prototype.insert=function(e){var t=new xW(e);return this.insertEntry(t),t},e.prototype.insertEntry=function(e){this.head?(this.tail.next=e,e.prev=this.tail,e.next=null,this.tail=e):this.head=this.tail=e,this._len++},e.prototype.remove=function(e){var t=e.prev,n=e.next;t?t.next=n:this.head=n,n?n.prev=t:this.tail=t,e.next=e.prev=null,this._len--},e.prototype.len=function(){return this._len},e.prototype.clear=function(){this.head=this.tail=null,this._len=0},e}(),CW=function(){function e(e){this._list=new SW,this._maxSize=10,this._map={},this._maxSize=e}return e.prototype.put=function(e,t){var n=this._list,r=this._map,i=null;if(r[e]==null){var a=n.len(),o=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=n.head;n.remove(s),delete r[s.key],i=s.value,this._lastRemovedEntry=s}o?o.value=t:o=new xW(t),o.key=e,n.insertEntry(o),r[e]=o}return i},e.prototype.get=function(e){var t=this._map[e],n=this._list;if(t!=null)return t!==n.tail&&(n.remove(t),n.insertEntry(t)),t.value},e.prototype.clear=function(){this._list.clear(),this._map={}},e.prototype.len=function(){return this._list.len()},e}(),wW=new CW(50);function TW(e){if(typeof e==`string`){var t=wW.get(e);return t&&t.image}else return e}function EW(e,t,n,r,i){if(!e)return t;if(typeof e==`string`){if(t&&t.__zrImageSrc===e||!n)return t;var a=wW.get(e),o={hostEl:n,cb:r,cbPayload:i};return a?(t=a.image,!OW(t)&&a.pending.push(o)):(t=VH.loadImage(e,DW,DW),t.__zrImageSrc=e,wW.put(e,t.__cachedImgObj={image:t,pending:[o]})),t}else return e}function DW(){var e=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var t=0;tu||d>f||p>m||h>g)return!1;var _=!(u=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height},e.prototype.contain=function(t,n){return e.contain(this,t,n)},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e.prototype.copy=function(e){oG(this,e)},e.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},e.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},e.prototype.isZero=function(){return this.width===0||this.height===0},e.create=function(t){return new e(t?t.x:0,t?t.y:0,t?t.width:0,t?t.height:0)},e.copy=function(e,t){return e.x=t.x,e.y=t.y,e.width=t.width,e.height=t.height,e},e.applyTransform=function(e,t,n){if(!n){e!==t&&oG(e,t);return}if(n[1]<1e-5&&n[1]>-1e-5&&n[2]<1e-5&&n[2]>-1e-5){var r=n[0],i=n[3],a=n[4],o=n[5];e.x=t.x*r+a,e.y=t.y*i+o,e.width=t.width*r,e.height=t.height*i,e.width<0&&(e.x+=e.width,e.width=-e.width),e.height<0&&(e.y+=e.height,e.height=-e.height);return}XW.x=QW.x=t.x,XW.y=$W.y=t.y,ZW.x=$W.x=t.x+t.width,ZW.y=QW.y=t.y+t.height,XW.transform(n),$W.transform(n),ZW.transform(n),QW.transform(n),e.x=KW(XW.x,ZW.x,QW.x,$W.x),e.y=KW(XW.y,ZW.y,QW.y,$W.y);var s=qW(XW.x,ZW.x,QW.x,$W.x),c=qW(XW.y,ZW.y,QW.y,$W.y);e.width=s-e.x,e.height=c-e.y},e.calculateTransform=function(e,t,n){var r=n.width/t.width,i=n.height/t.height;return e=AW(e||[]),NW(e,e,LW(sG,-t.x,-t.y)),kye(e,e,LW(sG,r,i)),NW(e,e,LW(sG,n.x,n.y)),e},e}();iG.create;var aG=iG.set,oG=iG.copy,Rye=iG.calculateTransform;iG.applyTransform,iG.contain;var zye=new iG(0,0,0,0),Bye=new iG(0,0,0,0),sG=[];function cG(e,t,n,r,i,a,o,s){var c=JW(t-n),l=JW(r-e),u=KW(c,l),d=YW[i],f=YW[1-i],p=Lye[i];t=l||!eG.bidirectional)&&(tG[d]=-l,tG[f]=0,eG.useDir&&eG.calcDirMTV())))}function lG(){var e=0,t=new GW,n=new GW,r={minTv:new GW,maxTv:new GW,useDir:!1,dirMinTv:new GW,touchThreshold:0,bidirectional:!0,negativeSize:!1,reset:function(i,a){r.touchThreshold=0,i&&i.touchThreshold!=null&&(r.touchThreshold=qW(0,i.touchThreshold)),r.negativeSize=!1,a&&(r.minTv.set(1/0,1/0),r.maxTv.set(0,0),r.useDir=!1,i&&i.direction!=null&&(r.useDir=!0,r.dirMinTv.copy(r.minTv),n.copy(r.minTv),e=i.direction,r.bidirectional=i.bidirectional==null||!!i.bidirectional,r.bidirectional||t.set(Math.cos(e),Math.sin(e))))},calcDirMTV:function(){var a=r.minTv,o=r.dirMinTv,s=a.y*a.y+a.x*a.x,c=Math.sin(e),l=Math.cos(e),u=c*a.y+l*a.x;if(i(u)){i(a.x)&&i(a.y)&&o.set(0,0);return}if(n.x=s*l/u,n.y=s*c/u,i(n.x)&&i(n.y)){o.set(0,0);return}(r.bidirectional||t.dot(n)>0)&&n.len()=pG)){e||=`12px sans-serif`;for(var t=[],n=+new Date,r=0;r<=127;r++)t[r]=VH.measureText(String.fromCharCode(r),e).width;var i=+new Date-n;return i>16?fG=pG:i>2&&fG++,t}}var fG=0,pG=5;function mG(e,t){return e.asciiWidthMapTried||=(e.asciiWidthMap=Vye(e.font),!0),0<=t&&t<=127?e.asciiWidthMap==null?e.asciiCharWidth:e.asciiWidthMap[t]:e.stWideCharWidth}function hG(e,t){var n=e.strWidthCache,r=n.get(t);return r??(r=VH.measureText(t,e.font).width,n.put(t,r)),r}function gG(e,t,n,r){var i=hG(uG(t),e),a=bG(t);return new iG(vG(0,i,n),yG(0,a,r),i,a)}function _G(e,t,n,r){var i=((e||``)+``).split(` `);if(i.length===1)return gG(i[0],t,n,r);for(var a=new iG(0,0,0,0),o=0;o=0?parseFloat(e)/100*t:parseFloat(e):e}function SG(e,t,n){var r=t.position||`inside`,i=t.distance==null?5:t.distance,a=n.height,o=n.width,s=a/2,c=n.x,l=n.y,u=`left`,d=`top`;if(r instanceof Array)c+=xG(r[0],n.width),l+=xG(r[1],n.height),u=null,d=null;else switch(r){case`left`:c-=i,l+=s,u=`right`,d=`middle`;break;case`right`:c+=i+o,l+=s,d=`middle`;break;case`top`:c+=o/2,l-=i,u=`center`,d=`bottom`;break;case`bottom`:c+=o/2,l+=a+i,u=`center`;break;case`inside`:c+=o/2,l+=s,u=`center`,d=`middle`;break;case`insideLeft`:c+=i,l+=s,d=`middle`;break;case`insideRight`:c+=o-i,l+=s,u=`right`,d=`middle`;break;case`insideTop`:c+=o/2,l+=i,u=`center`;break;case`insideBottom`:c+=o/2,l+=a-i,u=`center`,d=`bottom`;break;case`insideTopLeft`:c+=i,l+=i;break;case`insideTopRight`:c+=o-i,l+=i,u=`right`;break;case`insideBottomLeft`:c+=i,l+=a-i,d=`bottom`;break;case`insideBottomRight`:c+=o-i,l+=a-i,u=`right`,d=`bottom`;break}return e||={},e.x=c,e.y=l,e.align=u,e.verticalAlign=d,e}var CG=/\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;function Hye(e,t,n,r,i,a){if(!n){e.text=``,e.isTruncated=!1;return}var o=(t+``).split(` `);a=wG(n,r,i,a);for(var s=!1,c={},l=0,u=o.length;l=s;l++)c-=s;var u=hG(o,n);return u>c&&(n=``,u=0),c=e-u,i.ellipsis=n,i.ellipsisWidth=u,i.contentWidth=c,i.containerWidth=e,i}function TG(e,t,n){var r=n.containerWidth,i=n.contentWidth,a=n.fontMeasureInfo;if(!r){e.textLine=``,e.isTruncated=!1;return}var o=hG(a,t);if(o<=r){e.textLine=t,e.isTruncated=!1;return}for(var s=0;;s++){if(o<=i||s>=n.maxIterations){t+=n.ellipsis;break}var c=s===0?Uye(t,i,a):o>0?Math.floor(t.length*i/o):0;t=t.substr(0,c),o=hG(a,t)}t===``&&(t=n.placeholder),e.textLine=t,e.isTruncated=!0}function Uye(e,t,n){for(var r=0,i=0,a=e.length;i "/etc/systemd/system/sub2api-$name.service" <"$TMP/stdout" 2>"$TMP/stderr"; then + printf 'FAIL: %s unexpectedly succeeded\n' "$label" >&2 + return 1 + fi + printf 'ok: %s\n' "$label" +} + +mkdir -p "$TMP/real" "$TMP/bin" +ln -s "$TMP/real" "$TMP/path-link" + +# deploy/install.sh must reject an existing symlink component and a missing +# parent before git clone can create or write the checkout. +expect_fail 'deploy install rejects symlink component' \ + env PLUGIN_SOURCE_DIR="$TMP/path-link/sub2api-add" PLUGIN_ALLOW_CUSTOM_PATHS=true \ + bash "$ROOT/deploy/install.sh" +expect_fail 'deploy install rejects missing parent' \ + env PLUGIN_SOURCE_DIR="$TMP/missing/sub2api-add" PLUGIN_ALLOW_CUSTOM_PATHS=true \ + bash "$ROOT/deploy/install.sh" + +# Stub host tools so install-local reaches path validation without requiring +# Go or a running systemd instance. +cat >"$TMP/bin/go" <<'EOF' +#!/usr/bin/env bash +if [[ ${1:-} == version ]]; then printf 'go version go1.23.0 linux/amd64\n'; else exit 0; fi +EOF +cat >"$TMP/bin/systemctl" <<'EOF' +#!/usr/bin/env bash +exit 0 +EOF +chmod +x "$TMP/bin/go" "$TMP/bin/systemctl" + +expect_fail 'install-local rejects symlink component' \ + env PATH="$TMP/bin:/usr/bin:/bin" PLUGIN_ALLOW_CUSTOM_PATHS=true \ + PLUGIN_INSTALL_PREFIX="$TMP/path-link/sub2api-add" \ + PLUGIN_ETC_DIR="$TMP/etc/sub2api-add" PLUGIN_VAR_DIR="$TMP/var/sub2api-add" \ + bash "$ROOT/scripts/install-local.sh" --plugin plugin-admin + +expect_fail 'uninstall rejects symlink component' \ + env PATH="$TMP/bin:/usr/bin:/bin" PLUGIN_ALLOW_CUSTOM_PATHS=true \ + PLUGIN_INSTALL_PREFIX="$TMP/path-link/sub2api-add" \ + PLUGIN_ETC_DIR="$TMP/etc/sub2api-add" PLUGIN_VAR_DIR="$TMP/var/sub2api-add" \ + PLUGIN_SOURCE_DIR="$TMP/source/sub2api-add" \ + bash "$ROOT/deploy/uninstall.sh" --plugin plugin-admin --yes + +printf '%s\n' 'deploy path safety checks passed'