diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..0758a0a7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 2 +indent_style = space +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index cd9776bb..f5304bb1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,8 +3,7 @@ name: Bug report about: 创建一个报告来帮助我们改进 title: "[Bug] 标题简要描述问题" labels: bug -assignees: '' - +assignees: "" --- **描述问题** @@ -12,6 +11,7 @@ assignees: '' **复现步骤** 复现该问题的步骤: + 1. 去到 '...' 2. 点击 '...' 3. 滚动到 '...' @@ -24,9 +24,10 @@ assignees: '' 如有可能,请添加截图以帮助解释问题。 **环境** + - 操作系统: [e.g. Windows, macOS] - 浏览器: [e.g. Chrome, Safari] - 仓库版本: [e.g. v1.0.0] **其他信息** -在此处添加关于该问题的任何其他信息。 \ No newline at end of file +在此处添加关于该问题的任何其他信息。 diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 5b86dfe7..eccd8712 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -3,8 +3,7 @@ name: Feature request about: 提出一个新功能请求 title: "[Feature] 简要描述你希望实现的功能" labels: enhancement -assignees: '' - +assignees: "" --- **功能描述** @@ -17,4 +16,4 @@ assignees: '' 描述你已经考虑过的替代方案。 **其他信息** -在这里添加任何相关的附加信息或截图。 \ No newline at end of file +在这里添加任何相关的附加信息或截图。 diff --git a/.github/workflows/push_image.yml b/.github/workflows/push_image.yml index 78aa8bf2..b64c8bbf 100644 --- a/.github/workflows/push_image.yml +++ b/.github/workflows/push_image.yml @@ -30,7 +30,7 @@ jobs: uses: docker/metadata-action@v5 with: images: | - usual2970/certimate + usual2970/certimate registry.cn-shanghai.aliyuncs.com/usual2970/certimate - name: Log in to DOCKERHUB diff --git a/.gitignore b/.gitignore index 8ef500b1..7fd3ecd1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,7 @@ -__debug_bin* -vendor -pb_data -main -./certimate -build -/docker/data - -# Editor directories and files .vscode/* !.vscode/extensions.json +!.vscode/settings.json +!.vscode/settings.tailwind.json .idea .DS_Store *.suo @@ -17,4 +10,12 @@ build *.sln *.sw? +__debug_bin* +vendor +pb_data +build +main + ./dist +./certimate +/docker/data diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..2ccc8bc8 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "bradlc.vscode-tailwindcss", + "esbenp.prettier-vscode" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..47a3060e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "css.customData": [ + ".vscode/settings.tailwind.json" + ], + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "go.useLanguageServer": true, + "gopls": { + "formatting.gofumpt": true, + }, + "[go]": { + "editor.defaultFormatter": "golang.go" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} \ No newline at end of file diff --git a/.vscode/settings.tailwind.json b/.vscode/settings.tailwind.json new file mode 100644 index 00000000..96a1f579 --- /dev/null +++ b/.vscode/settings.tailwind.json @@ -0,0 +1,55 @@ +{ + "version": 1.1, + "atDirectives": [ + { + "name": "@tailwind", + "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" + } + ] + }, + { + "name": "@apply", + "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#apply" + } + ] + }, + { + "name": "@responsive", + "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" + } + ] + }, + { + "name": "@screen", + "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#screen" + } + ] + }, + { + "name": "@variants", + "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#variants" + } + ] + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54e81666..ee425a10 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,7 @@ git clone https://github.com/your_username/certimate.git 1. 进入根目录 2. 运行以下命令启动服务: + ```bash go run main.go serve ``` @@ -36,11 +37,12 @@ git clone https://github.com/your_username/certimate.git **在向主仓库提交 PR 之前,建议你:** +- 使用 [gofumpt](https://github.com/mvdan/gofumpt) 对你的代码进行格式化。 + - 为你的改动添加单元测试或集成测试(Certimate 使用 Go 的标准 `testing` 包)。你可以通过以下命令运行测试(在项目根目录下): ```bash go test ./... - ``` ## 修改管理页面 (Admin UI) @@ -49,17 +51,19 @@ Certimate 的管理页面是一个基于 React 和 Vite 构建的单页应用( 要启动 Admin UI: -1. 进入 `ui` 项目目录 -2. 运行 `npm install` 安装依赖 +1. 进入 `ui` 项目目录。 + +2. 运行 `npm install` 安装依赖。 + 3. 启动 Vite 开发服务器: + ```bash npm run dev ``` 你可以通过浏览器访问 `http://localhost:5173` 来查看运行中的管理页面。 -由于 Admin UI 只是一个客户端应用,运行时需要 Certimate 的后端服务作为支撑。你可以手动运行Certimate,或者使用预构建的可执行文件。 - +由于 Admin UI 只是一个客户端应用,运行时需要 Certimate 的后端服务作为支撑。你可以手动运行 Certimate,或者使用预构建的可执行文件。 所有对 Admin UI 的修改将会自动反映在浏览器中,无需手动刷新页面。 @@ -69,4 +73,4 @@ Certimate 的管理页面是一个基于 React 和 Vite 构建的单页应用( npm run build ``` -完成所有步骤后,你可以将改动提交 PR 到 Certimate 主仓库。 \ No newline at end of file +完成所有步骤后,你可以将改动提交 PR 到 Certimate 主仓库。 diff --git a/CONTRIBUTING_EN.md b/CONTRIBUTING_EN.md index 2f2d6efd..3d848ec8 100644 --- a/CONTRIBUTING_EN.md +++ b/CONTRIBUTING_EN.md @@ -27,7 +27,9 @@ git clone https://github.com/your_username/certimate.git Once you have made changes to the Go code in Certimate, follow these steps to run the project: 1. Navigate to the root directory. + 2. Start the service by running: + ```bash go run main.go serve ``` @@ -36,6 +38,8 @@ This will start a web server at `http://localhost:8090` using the prebuilt Admin **Before submitting a PR to the main repository, consider:** +- Format your source code by using [gofumpt](https://github.com/mvdan/gofumpt). + - Adding unit or integration tests for your changes. Certimate uses Go’s standard `testing` package. You can run tests using the following command (while in the root project directory): ```bash @@ -49,11 +53,15 @@ Certimate’s Admin UI is a single-page application (SPA) built using React and To start the Admin UI: 1. Navigate to the `ui` project directory. + 2. Install the necessary dependencies by running: + ```bash npm install ``` + 3. Start the Vite development server: + ```bash npm run dev ``` @@ -70,4 +78,4 @@ After completing your changes, build the Admin UI so it can be embedded into the npm run build ``` -Once all steps are completed, you are ready to submit a PR to the main Certimate repository. \ No newline at end of file +Once all steps are completed, you are ready to submit a PR to the main Certimate repository. diff --git a/Dockerfile_build b/Dockerfile_build index 23b27630..efd3d962 100644 --- a/Dockerfile_build +++ b/Dockerfile_build @@ -13,4 +13,4 @@ WORKDIR /app COPY --from=builder /app/certimate . -ENTRYPOINT ["./certimate", "serve", "--http", "0.0.0.0:8090"] \ No newline at end of file +ENTRYPOINT ["./certimate", "serve", "--http", "0.0.0.0:8090"] diff --git a/Makefile b/Makefile index fb6c79e9..7c2f0d6d 100644 --- a/Makefile +++ b/Makefile @@ -34,4 +34,4 @@ help: @echo " make clean - 清理构建文件" @echo " make help - 显示此帮助信息" -.PHONY: all build clean help \ No newline at end of file +.PHONY: all build clean help diff --git a/README.md b/README.md index d0866159..881a5db6 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ 做个人产品或在小企业负责运维的同学,需要管理多个域名,要给域名申请证书。但手动申请证书有以下缺点: -1. 😱麻烦:申请、部署证书虽不困难,但也挺麻烦的,尤其是维护多个域名的时候。 -2. 😭易忘:当前免费证书有效期仅90天,这就要求定期操作,增加工作量的同时,也很容易忘掉,导致网站无法访问。 +1. 😱 麻烦:申请、部署证书虽不困难,但也挺麻烦的,尤其是维护多个域名的时候。 +2. 😭 易忘:当前免费证书有效期仅 90 天,这就要求定期操作,增加工作量的同时,也很容易忘掉,导致网站无法访问。 Certimate 就是为了解决上述问题而产生的,它具有以下特点: @@ -15,9 +15,9 @@ Certimate 就是为了解决上述问题而产生的,它具有以下特点: 相关文章: -* [⚠️⚠️⚠️V0.2.0-第一个不向后兼容的版本](https://docs.certimate.me/blog/v0.2.0) -* [Why Certimate?](https://docs.certimate.me/blog/why-certimate) -* [域名变量及部署授权组介绍](https://docs.certimate.me/blog/multi-deployer) +- [⚠️⚠️⚠️V0.2.0-第一个不向后兼容的版本](https://docs.certimate.me/blog/v0.2.0) +- [Why Certimate?](https://docs.certimate.me/blog/why-certimate) +- [域名变量及部署授权组介绍](https://docs.certimate.me/blog/multi-deployer) Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决方案。使用文档请访问[https://docs.certimate.me](https://docs.certimate.me) @@ -34,12 +34,13 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决 ``` 或运行以下命令自动给 Certimate 自身添加证书 + ```bash ./certimate serve 你的域名 ``` > [!NOTE] -> MacOS 在执行二进制文件时会提示:无法打开“certimate”,因为Apple无法检查其是否包含恶意软件。可在系统设置> 隐私与安全性> 安全性 中点击 "仍然允许",然后再次尝试执行二进制文件。 +> MacOS 在执行二进制文件时会提示:无法打开“certimate”,因为 Apple 无法检查其是否包含恶意软件。可在系统设置> 隐私与安全性> 安全性 中点击 "仍然允许",然后再次尝试执行二进制文件。 ### 2. Docker 安装 @@ -71,14 +72,14 @@ go run main.go serve ## 三、支持的服务商列表 -| 服务商 | 是否域名服务商 | 是否部署服务 | 备注 | -| ---------- | -------------- | ------------ | ------------------------------------------------------ | -| 阿里云 | 是 | 是 | 支持阿里云注册的域名,支持部署到阿里云 CDN,OSS | -| 腾讯云 | 是 | 是 | 支持腾讯云注册的域名,支持部署到腾讯云 CDN | -| 七牛云 | 否 | 是 | 七牛云没有注册域名服务,支持部署到七牛云 CDN | -| CloudFlare | 是 | 否 | 支持 CloudFlare 注册的域名,CloudFlare 服务自带SSL证书 | -| SSH | 否 | 是 | 支持部署到 SSH 服务器 | -| WEBHOOK | 否 | 是 | 支持回调到 WEBHOOK | +| 服务商 | 是否域名服务商 | 是否部署服务 | 备注 | +| ---------- | -------------- | ------------ | -------------------------------------------------------- | +| 阿里云 | 是 | 是 | 支持阿里云注册的域名,支持部署到阿里云 CDN,OSS | +| 腾讯云 | 是 | 是 | 支持腾讯云注册的域名,支持部署到腾讯云 CDN | +| 七牛云 | 否 | 是 | 七牛云没有注册域名服务,支持部署到七牛云 CDN | +| CloudFlare | 是 | 否 | 支持 CloudFlare 注册的域名,CloudFlare 服务自带 SSL 证书 | +| SSH | 否 | 是 | 支持部署到 SSH 服务器 | +| WEBHOOK | 否 | 是 | 支持回调到 WEBHOOK | ## 四、系统截图 @@ -96,10 +97,10 @@ go run main.go serve Certimate 的工作流程如下: -* 用户通过 Certimate 管理页面填写申请证书的信息,包括域名、dns 服务商的授权信息、以及要部署到的服务商的授权信息。 -* Certimate 向证书厂商的 API 发起申请请求,获取 SSL 证书。 -* Certimate 存储证书信息,包括证书内容、私钥、证书有效期等,并在证书即将过期时自动续期。 -* Certimate 向服务商的 API 发起部署请求,将证书部署到服务商的服务器上。 +- 用户通过 Certimate 管理页面填写申请证书的信息,包括域名、dns 服务商的授权信息、以及要部署到的服务商的授权信息。 +- Certimate 向证书厂商的 API 发起申请请求,获取 SSL 证书。 +- Certimate 存储证书信息,包括证书内容、私钥、证书有效期等,并在证书即将过期时自动续期。 +- Certimate 向服务商的 API 发起部署请求,将证书部署到服务商的服务器上。 这就涉及域名、dns 服务商的授权信息、部署服务商的授权信息等。 @@ -135,17 +136,17 @@ Certimate 申请证书后,会自动将证书部署到你指定的目标上, ## 六、常见问题 -Q: 提供saas服务吗? +Q: 提供 saas 服务吗? -> A: 不提供,目前仅支持self-hosted(私有部署)。 +> A: 不提供,目前仅支持 self-hosted(私有部署)。 Q: 数据安全? -> A: 由于仅支持私有部署,各种数据都保存在用户的服务器上。另外Certimate源码也开源,二进制包及Docker镜像打包过程全部使用Github actions进行,过程透明可见,可自行审计。 +> A: 由于仅支持私有部署,各种数据都保存在用户的服务器上。另外 Certimate 源码也开源,二进制包及 Docker 镜像打包过程全部使用 Github actions 进行,过程透明可见,可自行审计。 Q: 自动续期证书? -> A: 已经申请的证书会在过期前10天自动续期。每天会检查一次证书是否快要过期,快要过期时会自动重新申请证书并部署到目标服务上。 +> A: 已经申请的证书会在过期前 10 天自动续期。每天会检查一次证书是否快要过期,快要过期时会自动重新申请证书并部署到目标服务上。 ## 七、贡献 @@ -153,17 +154,18 @@ Certimate 是一个免费且开源的项目,采用 [MIT 开源协议](LICENSE. 你可以通过以下方式来支持 Certimate 的开发: -* [提交代码:如果你发现了 bug 或有新的功能需求,而你又有相关经验,可以提交代码给我们](CONTRIBUTING.md)。 -* 提交 issue:功能建议或者 bug 可以[提交 issue](https://github.com/usual2970/certimate/issues) 给我们。 +- [提交代码:如果你发现了 bug 或有新的功能需求,而你又有相关经验,可以提交代码给我们](CONTRIBUTING.md)。 +- 提交 issue:功能建议或者 bug 可以[提交 issue](https://github.com/usual2970/certimate/issues) 给我们。 支持更多服务商、UI 的优化改进、BUG 修复、文档完善等,欢迎大家提交 PR。 ## 八、加入社区 -* [Telegram-a new era of messaging](https://t.me/+ZXphsppxUg41YmVl) -* 微信群聊(超200人需邀请入群,可先加作者好友) +- [Telegram-a new era of messaging](https://t.me/+ZXphsppxUg41YmVl) +- 微信群聊(超 200 人需邀请入群,可先加作者好友) ## 九、Star History + [![Stargazers over time](https://starchart.cc/usual2970/certimate.svg?variant=adaptive)](https://starchart.cc/usual2970/certimate) diff --git a/README_EN.md b/README_EN.md index 4d1794ea..9064b8b6 100644 --- a/README_EN.md +++ b/README_EN.md @@ -15,8 +15,8 @@ Certimate was created to solve the above-mentioned issues and has the following Related articles: -* [Why Certimate?](https://docs.certimate.me/blog/why-certimate) -* [Introduction to Domain Variables and Deployment Authorization Groups](https://docs.certimate.me/blog/multi-deployer) +- [Why Certimate?](https://docs.certimate.me/blog/why-certimate) +- [Introduction to Domain Variables and Deployment Authorization Groups](https://docs.certimate.me/blog/multi-deployer) Certimate aims to provide users with a secure and user-friendly SSL certificate management solution. For usage documentation, please visit.[https://docs.certimate.me](https://docs.certimate.me) @@ -96,10 +96,10 @@ password:1234567890 The workflow of Certimate is as follows: -* Users fill in the certificate application information on the Certimate management page, including domain name, authorization information for the DNS provider, and authorization information for the service provider to deploy to. -* Certimate sends a request to the certificate vendor's API to apply for an SSL certificate. -* Certimate stores the certificate information, including the certificate content, private key, validity period, etc., and automatically renews the certificate when it is about to expire. -* Certimate sends a deployment request to the service provider's API to deploy the certificate to the service provider's servers. +- Users fill in the certificate application information on the Certimate management page, including domain name, authorization information for the DNS provider, and authorization information for the service provider to deploy to. +- Certimate sends a request to the certificate vendor's API to apply for an SSL certificate. +- Certimate stores the certificate information, including the certificate content, private key, validity period, etc., and automatically renews the certificate when it is about to expire. +- Certimate sends a deployment request to the service provider's API to deploy the certificate to the service provider's servers. This involves authorization information for the domain, DNS provider, and deployment service provider. @@ -153,14 +153,14 @@ Certimate is a free and open-source project, licensed under the [MIT License](LI You can support the development of Certimate in the following ways: -* **Submit Code**: If you find a bug or have new feature requests, and you have relevant experience, [you can submit code to us](CONTRIBUTING_EN.md). -* **Submit an Issue**: For feature suggestions or bugs, you can [submit an issue](https://github.com/usual2970/certimate/issues) to us. +- **Submit Code**: If you find a bug or have new feature requests, and you have relevant experience, [you can submit code to us](CONTRIBUTING_EN.md). +- **Submit an Issue**: For feature suggestions or bugs, you can [submit an issue](https://github.com/usual2970/certimate/issues) to us. Support for more service providers, UI enhancements, bug fixes, and documentation improvements are all welcome. We encourage everyone to submit pull requests (PRs). ## Join the Community -* [Telegram-a new era of messaging](https://t.me/+ZXphsppxUg41YmVl) -* Wechat Group +- [Telegram-a new era of messaging](https://t.me/+ZXphsppxUg41YmVl) +- Wechat Group diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 385bc989..858148e8 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,10 +1,10 @@ -version: '3.0' +version: "3.0" services: - certimate: - image: registry.cn-shanghai.aliyuncs.com/usual2970/certimate:latest - container_name: certimate_server - ports: + certimate: + image: registry.cn-shanghai.aliyuncs.com/usual2970/certimate:latest + container_name: certimate_server + ports: - 8090:8090 - volumes: + volumes: - ./data:/app/pb_data - restart: unless-stopped \ No newline at end of file + restart: unless-stopped diff --git a/internal/applicant/aliyun.go b/internal/applicant/aliyun.go index 6ab27e44..0b0dc61d 100644 --- a/internal/applicant/aliyun.go +++ b/internal/applicant/aliyun.go @@ -1,12 +1,13 @@ package applicant import ( - "certimate/internal/domain" "encoding/json" "fmt" "os" "github.com/go-acme/lego/v4/providers/dns/alidns" + + "certimate/internal/domain" ) type aliyun struct { @@ -20,7 +21,6 @@ func NewAliyun(option *ApplyOption) Applicant { } func (a *aliyun) Apply() (*Certificate, error) { - access := &domain.AliyunAccess{} json.Unmarshal([]byte(a.option.Access), access) diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index fd869f1d..2385bbad 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -1,8 +1,6 @@ package applicant import ( - "certimate/internal/domain" - "certimate/internal/utils/app" "crypto" "crypto/ecdsa" "crypto/elliptic" @@ -18,6 +16,9 @@ import ( "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/registration" "github.com/pocketbase/pocketbase/models" + + "certimate/internal/domain" + "certimate/internal/utils/app" ) const ( @@ -66,19 +67,21 @@ type ApplyOption struct { Timeout int64 `json:"timeout"` } -type MyUser struct { +type ApplyUser struct { Email string Registration *registration.Resource key crypto.PrivateKey } -func (u *MyUser) GetEmail() string { +func (u *ApplyUser) GetEmail() string { return u.Email } -func (u MyUser) GetRegistration() *registration.Resource { + +func (u ApplyUser) GetRegistration() *registration.Resource { return u.Registration } -func (u *MyUser) GetPrivateKey() crypto.PrivateKey { + +func (u *ApplyUser) GetPrivateKey() crypto.PrivateKey { return u.key } @@ -87,7 +90,6 @@ type Applicant interface { } func Get(record *models.Record) (Applicant, error) { - if record.GetString("applyConfig") == "" { return nil, errors.New("apply config is empty") } @@ -97,7 +99,6 @@ func Get(record *models.Record) (Applicant, error) { record.UnmarshalJSONField("applyConfig", applyConfig) access, err := app.GetApp().Dao().FindRecordById("access", applyConfig.Access) - if err != nil { return nil, fmt.Errorf("access record not found: %w", err) } @@ -129,7 +130,6 @@ func Get(record *models.Record) (Applicant, error) { default: return nil, errors.New("unknown config type") } - } type SSLProviderConfig struct { @@ -162,7 +162,7 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro return nil, err } - myUser := MyUser{ + myUser := ApplyUser{ Email: option.Email, key: privateKey, } @@ -213,7 +213,6 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro IssuerCertificate: string(certificates.IssuerCertificate), Csr: string(certificates.CSR), }, nil - } func getReg(client *lego.Client, sslProvider *SSLProviderConfig) (*registration.Resource, error) { diff --git a/internal/applicant/cloudflare.go b/internal/applicant/cloudflare.go index a2e9e061..75d083fd 100644 --- a/internal/applicant/cloudflare.go +++ b/internal/applicant/cloudflare.go @@ -1,12 +1,13 @@ package applicant import ( - "certimate/internal/domain" "encoding/json" "fmt" "os" cf "github.com/go-acme/lego/v4/providers/dns/cloudflare" + + "certimate/internal/domain" ) type cloudflare struct { diff --git a/internal/applicant/godaddy.go b/internal/applicant/godaddy.go index 911ee7cd..adcfe13b 100644 --- a/internal/applicant/godaddy.go +++ b/internal/applicant/godaddy.go @@ -1,12 +1,13 @@ package applicant import ( - "certimate/internal/domain" "encoding/json" "fmt" "os" godaddyProvider "github.com/go-acme/lego/v4/providers/dns/godaddy" + + "certimate/internal/domain" ) type godaddy struct { @@ -20,7 +21,6 @@ func NewGodaddy(option *ApplyOption) Applicant { } func (a *godaddy) Apply() (*Certificate, error) { - access := &domain.GodaddyAccess{} json.Unmarshal([]byte(a.option.Access), access) diff --git a/internal/applicant/huaweicloud.go b/internal/applicant/huaweicloud.go index 8da5f6ae..294e95a6 100644 --- a/internal/applicant/huaweicloud.go +++ b/internal/applicant/huaweicloud.go @@ -1,12 +1,13 @@ package applicant import ( - "certimate/internal/domain" "encoding/json" "fmt" "os" huaweicloudProvider "github.com/go-acme/lego/v4/providers/dns/huaweicloud" + + "certimate/internal/domain" ) type huaweicloud struct { @@ -20,7 +21,6 @@ func NewHuaweiCloud(option *ApplyOption) Applicant { } func (t *huaweicloud) Apply() (*Certificate, error) { - access := &domain.HuaweiCloudAccess{} json.Unmarshal([]byte(t.option.Access), access) @@ -28,7 +28,7 @@ func (t *huaweicloud) Apply() (*Certificate, error) { os.Setenv("HUAWEICLOUD_ACCESS_KEY_ID", access.AccessKeyId) os.Setenv("HUAWEICLOUD_SECRET_ACCESS_KEY", access.SecretAccessKey) os.Setenv("HUAWEICLOUD_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", t.option.Timeout)) - + dnsProvider, err := huaweicloudProvider.NewDNSProvider() if err != nil { return nil, err diff --git a/internal/applicant/namesilo.go b/internal/applicant/namesilo.go index 69f6277a..0f2aa155 100644 --- a/internal/applicant/namesilo.go +++ b/internal/applicant/namesilo.go @@ -1,12 +1,13 @@ package applicant import ( - "certimate/internal/domain" "encoding/json" "fmt" "os" namesiloProvider "github.com/go-acme/lego/v4/providers/dns/namesilo" + + "certimate/internal/domain" ) type namesilo struct { @@ -20,7 +21,6 @@ func NewNamesilo(option *ApplyOption) Applicant { } func (a *namesilo) Apply() (*Certificate, error) { - access := &domain.NameSiloAccess{} json.Unmarshal([]byte(a.option.Access), access) diff --git a/internal/applicant/tencent.go b/internal/applicant/tencent.go index d7ed6dc9..705f63ad 100644 --- a/internal/applicant/tencent.go +++ b/internal/applicant/tencent.go @@ -1,12 +1,13 @@ package applicant import ( - "certimate/internal/domain" "encoding/json" "fmt" "os" "github.com/go-acme/lego/v4/providers/dns/tencentcloud" + + "certimate/internal/domain" ) type tencent struct { @@ -20,14 +21,13 @@ func NewTencent(option *ApplyOption) Applicant { } func (t *tencent) Apply() (*Certificate, error) { - access := &domain.TencentAccess{} json.Unmarshal([]byte(t.option.Access), access) os.Setenv("TENCENTCLOUD_SECRET_ID", access.SecretId) os.Setenv("TENCENTCLOUD_SECRET_KEY", access.SecretKey) os.Setenv("TENCENTCLOUD_PROPAGATION_TIMEOUT", fmt.Sprintf("%d", t.option.Timeout)) - + dnsProvider, err := tencentcloud.NewDNSProvider() if err != nil { return nil, err diff --git a/internal/deployer/aliyun.go b/internal/deployer/aliyun.go index ce8f0a2d..9c56e6df 100644 --- a/internal/deployer/aliyun.go +++ b/internal/deployer/aliyun.go @@ -1,12 +1,13 @@ package deployer import ( - "certimate/internal/domain" "context" "encoding/json" "fmt" "github.com/aliyun/aliyun-oss-go-sdk/oss" + + "certimate/internal/domain" ) type aliyun struct { @@ -28,7 +29,6 @@ func NewAliyun(option *DeployerOption) (Deployer, error) { } a.client = client return a, nil - } func (a *aliyun) GetID() string { @@ -48,13 +48,11 @@ func (a *aliyun) Deploy(ctx context.Context) error { Force: true, }, }) - if err != nil { return fmt.Errorf("deploy aliyun oss error: %w", err) } return nil - } func (a *aliyun) createClient(accessKeyId, accessKeySecret string) (*oss.Client, error) { diff --git a/internal/deployer/aliyun_cdn.go b/internal/deployer/aliyun_cdn.go index d0f1edd4..0de5959f 100644 --- a/internal/deployer/aliyun_cdn.go +++ b/internal/deployer/aliyun_cdn.go @@ -1,8 +1,6 @@ package deployer import ( - "certimate/internal/domain" - "certimate/internal/utils/rand" "context" "encoding/json" "fmt" @@ -11,6 +9,9 @@ import ( openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" util "github.com/alibabacloud-go/tea-utils/v2/service" "github.com/alibabacloud-go/tea/tea" + + "certimate/internal/domain" + "certimate/internal/utils/rand" ) type AliyunCdn struct { @@ -46,7 +47,6 @@ func (a *AliyunCdn) GetInfo() []string { } func (a *AliyunCdn) Deploy(ctx context.Context) error { - certName := fmt.Sprintf("%s-%s-%s", a.option.Domain, a.option.DomainId, rand.RandStr(6)) setCdnDomainSSLCertificateRequest := &cdn20180510.SetCdnDomainSSLCertificateRequest{ DomainName: tea.String(getDeployString(a.option.DeployConfig, "domain")), diff --git a/internal/deployer/aliyun_esa.go b/internal/deployer/aliyun_esa.go index 27ce040f..2115d796 100644 --- a/internal/deployer/aliyun_esa.go +++ b/internal/deployer/aliyun_esa.go @@ -6,8 +6,6 @@ package deployer import ( - "certimate/internal/domain" - "certimate/internal/utils/rand" "context" "encoding/json" "fmt" @@ -16,6 +14,9 @@ import ( dcdn20180115 "github.com/alibabacloud-go/dcdn-20180115/v3/client" util "github.com/alibabacloud-go/tea-utils/v2/service" "github.com/alibabacloud-go/tea/tea" + + "certimate/internal/domain" + "certimate/internal/utils/rand" ) type AliyunEsa struct { @@ -51,7 +52,6 @@ func (a *AliyunEsa) GetInfo() []string { } func (a *AliyunEsa) Deploy(ctx context.Context) error { - certName := fmt.Sprintf("%s-%s-%s", a.option.Domain, a.option.DomainId, rand.RandStr(6)) setDcdnDomainSSLCertificateRequest := &dcdn20180115.SetDcdnDomainSSLCertificateRequest{ DomainName: tea.String(getDeployString(a.option.DeployConfig, "domain")), diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index 1a6497a9..d764c37d 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -1,9 +1,6 @@ package deployer import ( - "certimate/internal/applicant" - "certimate/internal/domain" - "certimate/internal/utils/app" "context" "encoding/json" "errors" @@ -11,6 +8,10 @@ import ( "strings" "github.com/pocketbase/pocketbase/models" + + "certimate/internal/applicant" + "certimate/internal/domain" + "certimate/internal/utils/app" ) const ( @@ -61,7 +62,6 @@ func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error for _, deployConfig := range deployConfigs { deployer, err := getWithDeployConfig(record, cert, deployConfig) - if err != nil { return nil, err } @@ -70,13 +70,10 @@ func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error } return rs, nil - } func getWithDeployConfig(record *models.Record, cert *applicant.Certificate, deployConfig domain.DeployConfig) (Deployer, error) { - access, err := app.GetApp().Dao().FindRecordById("access", deployConfig.Access) - if err != nil { return nil, fmt.Errorf("access record not found: %w", err) } @@ -169,5 +166,4 @@ func getDeployVariables(conf domain.DeployConfig) map[string]string { } return rs - } diff --git a/internal/deployer/local.go b/internal/deployer/local.go index d092db95..f358215b 100644 --- a/internal/deployer/local.go +++ b/internal/deployer/local.go @@ -10,8 +10,7 @@ import ( "runtime" ) -type localAccess struct { -} +type localAccess struct{} type local struct { option *DeployerOption diff --git a/internal/deployer/qiniu.go b/internal/deployer/qiniu.go index 637b1167..46ccee10 100644 --- a/internal/deployer/qiniu.go +++ b/internal/deployer/qiniu.go @@ -2,8 +2,6 @@ package deployer import ( "bytes" - "certimate/internal/domain" - xhttp "certimate/internal/utils/http" "context" "encoding/json" "fmt" @@ -11,6 +9,9 @@ import ( "net/http" "github.com/qiniu/go-sdk/v7/auth" + + "certimate/internal/domain" + xhttp "certimate/internal/utils/http" ) const qiniuGateway = "http://api.qiniu.com" @@ -42,7 +43,6 @@ func (q *qiuniu) GetInfo() []string { } func (q *qiuniu) Deploy(ctx context.Context) error { - // 上传证书 certId, err := q.uploadCert() if err != nil { diff --git a/internal/deployer/qiniu_test.go b/internal/deployer/qiniu_test.go index 35b0746a..38b54960 100644 --- a/internal/deployer/qiniu_test.go +++ b/internal/deployer/qiniu_test.go @@ -1,10 +1,11 @@ package deployer import ( - "certimate/internal/applicant" "testing" "github.com/qiniu/go-sdk/v7/auth" + + "certimate/internal/applicant" ) func Test_qiuniu_uploadCert(t *testing.T) { diff --git a/internal/deployer/ssh.go b/internal/deployer/ssh.go index c7a03d4c..a534b5f6 100644 --- a/internal/deployer/ssh.go +++ b/internal/deployer/ssh.go @@ -103,7 +103,6 @@ func (s *ssh) sshExecCommand(client *sshPkg.Client, command string) (error, stri } func (s *ssh) upload(client *sshPkg.Client, content, path string) error { - sftpCli, err := sftp.NewClient(client) if err != nil { return fmt.Errorf("failed to create sftp client: %w", err) @@ -129,7 +128,6 @@ func (s *ssh) upload(client *sshPkg.Client, content, path string) error { } func (s *ssh) getClient(access *sshAccess) (*sshPkg.Client, error) { - var authMethod sshPkg.AuthMethod if access.Key != "" { diff --git a/internal/deployer/ssh_test.go b/internal/deployer/ssh_test.go index 909b68e2..c9b1e85a 100644 --- a/internal/deployer/ssh_test.go +++ b/internal/deployer/ssh_test.go @@ -8,5 +8,5 @@ import ( func TestPath(t *testing.T) { dir := path.Dir("./a/b/c") - os.MkdirAll(dir, 0755) + os.MkdirAll(dir, 0o755) } diff --git a/internal/deployer/tencent_cdn.go b/internal/deployer/tencent_cdn.go index 9c1b96b1..3da84775 100644 --- a/internal/deployer/tencent_cdn.go +++ b/internal/deployer/tencent_cdn.go @@ -1,8 +1,6 @@ package deployer import ( - "certimate/internal/domain" - "certimate/internal/utils/rand" "context" "encoding/base64" "encoding/json" @@ -13,6 +11,9 @@ import ( "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" ssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" + + "certimate/internal/domain" + "certimate/internal/utils/rand" ) type tencentCdn struct { @@ -22,7 +23,6 @@ type tencentCdn struct { } func NewTencentCdn(option *DeployerOption) (Deployer, error) { - access := &domain.TencentAccess{} if err := json.Unmarshal([]byte(option.Access), access); err != nil { return nil, fmt.Errorf("failed to unmarshal tencent access: %w", err) @@ -49,7 +49,6 @@ func (t *tencentCdn) GetInfo() []string { } func (t *tencentCdn) Deploy(ctx context.Context) error { - // 上传证书 certId, err := t.uploadCert() if err != nil { @@ -65,7 +64,6 @@ func (t *tencentCdn) Deploy(ctx context.Context) error { } func (t *tencentCdn) uploadCert() (string, error) { - cpf := profile.NewClientProfile() cpf.HttpProfile.Endpoint = "ssl.tencentcloudapi.com" @@ -116,7 +114,6 @@ func (t *tencentCdn) deploy(certId string) error { // 返回的resp是一个DeployCertificateInstanceResponse的实例,与请求对象对应 resp, err := client.DeployCertificateInstance(request) - if err != nil { return fmt.Errorf("failed to deploy certificate: %w", err) } diff --git a/internal/deployer/webhook.go b/internal/deployer/webhook.go index 56486585..ce84f312 100644 --- a/internal/deployer/webhook.go +++ b/internal/deployer/webhook.go @@ -2,11 +2,12 @@ package deployer import ( "bytes" - xhttp "certimate/internal/utils/http" "context" "encoding/json" "fmt" "net/http" + + xhttp "certimate/internal/utils/http" ) type webhookAccess struct { @@ -26,7 +27,6 @@ type webhook struct { } func NewWebhook(option *DeployerOption) (Deployer, error) { - return &webhook{ option: option, infos: make([]string, 0), diff --git a/internal/domain/access.go b/internal/domain/access.go index 80cdee59..ca1df988 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -33,4 +33,3 @@ type GodaddyAccess struct { ApiKey string `json:"apiKey"` ApiSecret string `json:"apiSecret"` } - diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go index 2f48434b..0f6776c6 100644 --- a/internal/domains/deploy.go +++ b/internal/domains/deploy.go @@ -1,14 +1,15 @@ package domains import ( - "certimate/internal/applicant" - "certimate/internal/deployer" - "certimate/internal/utils/app" "context" "fmt" "time" "github.com/pocketbase/pocketbase/models" + + "certimate/internal/applicant" + "certimate/internal/deployer" + "certimate/internal/utils/app" ) type Phase string diff --git a/internal/domains/domains.go b/internal/domains/domains.go index 17d59ee9..03fc24f1 100644 --- a/internal/domains/domains.go +++ b/internal/domains/domains.go @@ -1,11 +1,12 @@ package domains import ( - "certimate/internal/utils/app" "context" "fmt" "github.com/pocketbase/pocketbase/models" + + "certimate/internal/utils/app" ) func create(ctx context.Context, record *models.Record) error { @@ -19,7 +20,6 @@ func create(ctx context.Context, record *models.Record) error { app.GetApp().Logger().Error("deploy failed", "err", err) } }() - } scheduler := app.GetScheduler() @@ -27,7 +27,6 @@ func create(ctx context.Context, record *models.Record) error { err := scheduler.Add(record.Id, record.GetString("crontab"), func() { deploy(ctx, record) }) - if err != nil { app.GetApp().Logger().Error("add cron job failed", "err", err) return fmt.Errorf("add cron job failed: %w", err) @@ -46,7 +45,6 @@ func update(ctx context.Context, record *models.Record) error { } if record.GetBool("rightnow") { - go func() { if err := deploy(ctx, record); err != nil { app.GetApp().Logger().Error("deploy failed", "err", err) @@ -57,7 +55,6 @@ func update(ctx context.Context, record *models.Record) error { err := scheduler.Add(record.Id, record.GetString("crontab"), func() { deploy(ctx, record) }) - if err != nil { app.GetApp().Logger().Error("update cron job failed", "err", err) return fmt.Errorf("update cron job failed: %w", err) diff --git a/internal/domains/event.go b/internal/domains/event.go index 33d1a571..5ad38ad1 100644 --- a/internal/domains/event.go +++ b/internal/domains/event.go @@ -1,9 +1,9 @@ package domains import ( - "certimate/internal/utils/app" - "github.com/pocketbase/pocketbase/core" + + "certimate/internal/utils/app" ) const tableName = "domains" diff --git a/internal/domains/history.go b/internal/domains/history.go index 8850b37b..616c7c8c 100644 --- a/internal/domains/history.go +++ b/internal/domains/history.go @@ -1,12 +1,13 @@ package domains import ( - "certimate/internal/applicant" - "certimate/internal/utils/app" - "certimate/internal/utils/xtime" "time" "github.com/pocketbase/pocketbase/models" + + "certimate/internal/applicant" + "certimate/internal/utils/app" + "certimate/internal/utils/xtime" ) type historyItem struct { @@ -62,7 +63,6 @@ func (a *history) record(phase Phase, msg string, info *RecordInfo, pass ...bool Info: info.Info, Time: xtime.BeijingTimeStr(), }) - } func (a *history) setCert(cert *applicant.Certificate) { diff --git a/internal/domains/init.go b/internal/domains/init.go index 46f1dd5d..69de4018 100644 --- a/internal/domains/init.go +++ b/internal/domains/init.go @@ -1,9 +1,10 @@ package domains import ( + "context" + "certimate/internal/notify" "certimate/internal/utils/app" - "context" ) func InitSchedule() { @@ -34,5 +35,4 @@ func InitSchedule() { // 启动定时任务 app.GetScheduler().Start() app.GetApp().Logger().Info("定时任务启动成功", "total", app.GetScheduler().Total()) - } diff --git a/internal/notify/expire.go b/internal/notify/expire.go index c5a546ec..985d7491 100644 --- a/internal/notify/expire.go +++ b/internal/notify/expire.go @@ -1,14 +1,15 @@ package notify import ( - "certimate/internal/utils/app" - "certimate/internal/utils/xtime" "strconv" "strings" "time" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/models" + + "certimate/internal/utils/app" + "certimate/internal/utils/xtime" ) type msg struct { @@ -41,7 +42,6 @@ func PushExpireMsg() { if err := Send(msg.subject, msg.message); err != nil { app.GetApp().Logger().Error("send expire msg", "error", err) } - } type notifyTemplates struct { @@ -94,5 +94,4 @@ func buildMsg(records []*models.Record) *msg { subject: title, message: content, } - } diff --git a/internal/notify/notify.go b/internal/notify/notify.go index 3b238d52..3334fa67 100644 --- a/internal/notify/notify.go +++ b/internal/notify/notify.go @@ -1,18 +1,16 @@ package notify import ( - "certimate/internal/utils/app" "context" "fmt" "strconv" notifyPackage "github.com/nikoksr/notify" - "github.com/nikoksr/notify/service/dingding" - + "github.com/nikoksr/notify/service/http" "github.com/nikoksr/notify/service/telegram" - "github.com/nikoksr/notify/service/http" + "certimate/internal/utils/app" ) const ( @@ -40,7 +38,6 @@ func Send(title, content string) error { } func getNotifiers() ([]notifyPackage.Notifier, error) { - resp, err := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='notifyChannels'") if err != nil { return nil, fmt.Errorf("find notifyChannels error: %w", err) @@ -77,7 +74,6 @@ func getNotifiers() ([]notifyPackage.Notifier, error) { } return notifiers, nil - } func getWebhookNotifier(conf map[string]any) notifyPackage.Notifier { @@ -110,7 +106,6 @@ func getDingTalkNotifier(conf map[string]any) notifyPackage.Notifier { Token: getString(conf, "accessToken"), Secret: getString(conf, "secret"), }) - } func getString(conf map[string]any, key string) string { diff --git a/internal/utils/http/http.go b/internal/utils/http/http.go index 743fa015..6269ea98 100644 --- a/internal/utils/http/http.go +++ b/internal/utils/http/http.go @@ -35,11 +35,9 @@ func Req2GetReader(url string, method string, body io.Reader, head map[string]st req := BuildReq(url, method, body, head) return ToRequest(req, opts...) - } func BuildReq(url string, method string, body io.Reader, head map[string]string) *http.Request { - // Create an http.Request instance req, _ := http.NewRequest(method, url, body) for k, v := range head { diff --git a/internal/utils/variables/variables.go b/internal/utils/variables/variables.go index 626d513b..74a7b22d 100644 --- a/internal/utils/variables/variables.go +++ b/internal/utils/variables/variables.go @@ -4,7 +4,6 @@ import "strings" // Parse2Map 将变量赋值字符串解析为map func Parse2Map(str string) map[string]string { - m := make(map[string]string) lines := strings.Split(str, ";") diff --git a/internal/utils/xtime/time.go b/internal/utils/xtime/time.go index 745ec45b..2c074e6c 100644 --- a/internal/utils/xtime/time.go +++ b/internal/utils/xtime/time.go @@ -15,7 +15,6 @@ func BeijingTimeStr() string { } func GetTimeAfter(d time.Duration) string { - t := time.Now().UTC() return t.Add(d).Format("2006-01-02 15:04:05") diff --git a/nixpacks.toml b/nixpacks.toml index 1d68c6bf..c56baee7 100644 --- a/nixpacks.toml +++ b/nixpacks.toml @@ -27,4 +27,4 @@ nixOverlays = [] nixpkgsArchive = '1f13eabcd6f5b00fe9de9575ac52c66a0e887ce6' [start] -cmd = './out serve --http=0.0.0.0:8090 --dir=/data/pb_data ' \ No newline at end of file +cmd = './out serve --http=0.0.0.0:8090 --dir=/data/pb_data ' diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs index d6c95379..1281ed3a 100644 --- a/ui/.eslintrc.cjs +++ b/ui/.eslintrc.cjs @@ -1,18 +1,23 @@ +/** + * @type {import("eslint").Linter.Config} + */ module.exports = { root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], + env: { + browser: true, + node: true, + es2020: true, + }, + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "plugin:react-hooks/recommended"], + ignorePatterns: ["dist", ".eslintrc.cjs"], + parser: "@typescript-eslint/parser", + plugins: ["react-refresh"], rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, + "react-refresh/only-export-components": [ + "warn", + { + allowConstantExport: true, + }, ], }, -} +}; diff --git a/ui/.prettierrc.cjs b/ui/.prettierrc.cjs new file mode 100644 index 00000000..6eab4828 --- /dev/null +++ b/ui/.prettierrc.cjs @@ -0,0 +1,20 @@ +/** + * @type {import("prettier").Config} + */ +module.exports = { + arrowParens: "always", + bracketSpacing: true, + editorconfig: true, + htmlWhitespaceSensitivity: "ignore", + jsxSingleQuote: false, + endOfLine: "crlf", + printWidth: 160, + proseWrap: "preserve", + quoteProps: "as-needed", + semi: true, + singleQuote: false, + tabs: false, + tabWidth: 2, + trailingComma: "es5", + useTabs: false, +}; diff --git a/ui/README.md b/ui/README.md index e1cdc89d..85a6989e 100644 --- a/ui/README.md +++ b/ui/README.md @@ -17,12 +17,12 @@ If you are developing a production application, we recommend updating the config export default { // other rules... parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json', './tsconfig.app.json'], + ecmaVersion: "latest", + sourceType: "module", + project: ["./tsconfig.json", "./tsconfig.node.json", "./tsconfig.app.json"], tsconfigRootDir: __dirname, }, -} +}; ``` - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` diff --git a/ui/components.json b/ui/components.json index 46f4379c..b67a3e09 100644 --- a/ui/components.json +++ b/ui/components.json @@ -14,4 +14,4 @@ "components": "@/components", "utils": "@/lib/utils" } -} \ No newline at end of file +} diff --git a/ui/dist/assets/index-C9iolg9g.js b/ui/dist/assets/index-C9iolg9g.js new file mode 100644 index 00000000..ae63a915 --- /dev/null +++ b/ui/dist/assets/index-C9iolg9g.js @@ -0,0 +1,324 @@ +var pP=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var VH=pP((n9,Ed)=>{function g1(e,t){for(var n=0;nr[s]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const o of s)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&r(i)}).observe(document,{childList:!0,subtree:!0});function n(s){const o={};return s.integrity&&(o.integrity=s.integrity),s.referrerPolicy&&(o.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?o.credentials="include":s.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(s){if(s.ep)return;s.ep=!0;const o=n(s);fetch(s.href,o)}})();var Cu=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Uf(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var y1={exports:{}},Vf={},v1={exports:{}},nt={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Gc=Symbol.for("react.element"),gP=Symbol.for("react.portal"),yP=Symbol.for("react.fragment"),vP=Symbol.for("react.strict_mode"),xP=Symbol.for("react.profiler"),wP=Symbol.for("react.provider"),bP=Symbol.for("react.context"),_P=Symbol.for("react.forward_ref"),SP=Symbol.for("react.suspense"),kP=Symbol.for("react.memo"),CP=Symbol.for("react.lazy"),l0=Symbol.iterator;function jP(e){return e===null||typeof e!="object"?null:(e=l0&&e[l0]||e["@@iterator"],typeof e=="function"?e:null)}var x1={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},w1=Object.assign,b1={};function Ya(e,t,n){this.props=e,this.context=t,this.refs=b1,this.updater=n||x1}Ya.prototype.isReactComponent={};Ya.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};Ya.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function _1(){}_1.prototype=Ya.prototype;function ry(e,t,n){this.props=e,this.context=t,this.refs=b1,this.updater=n||x1}var sy=ry.prototype=new _1;sy.constructor=ry;w1(sy,Ya.prototype);sy.isPureReactComponent=!0;var c0=Array.isArray,S1=Object.prototype.hasOwnProperty,oy={current:null},k1={key:!0,ref:!0,__self:!0,__source:!0};function C1(e,t,n){var r,s={},o=null,i=null;if(t!=null)for(r in t.ref!==void 0&&(i=t.ref),t.key!==void 0&&(o=""+t.key),t)S1.call(t,r)&&!k1.hasOwnProperty(r)&&(s[r]=t[r]);var a=arguments.length-2;if(a===1)s.children=n;else if(1>>1,B=W[$];if(0>>1;$s(oe,X))Oes(me,oe)?(W[$]=me,W[Oe]=X,$=Oe):(W[$]=oe,W[se]=X,$=se);else if(Oes(me,X))W[$]=me,W[Oe]=X,$=Oe;else break e}}return I}function s(W,I){var X=W.sortIndex-I.sortIndex;return X!==0?X:W.id-I.id}if(typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var i=Date,a=i.now();e.unstable_now=function(){return i.now()-a}}var c=[],u=[],d=1,f=null,h=3,m=!1,x=!1,p=!1,w=typeof setTimeout=="function"?setTimeout:null,g=typeof clearTimeout=="function"?clearTimeout:null,v=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function b(W){for(var I=n(u);I!==null;){if(I.callback===null)r(u);else if(I.startTime<=W)r(u),I.sortIndex=I.expirationTime,t(c,I);else break;I=n(u)}}function _(W){if(p=!1,b(W),!x)if(n(c)!==null)x=!0,J(C);else{var I=n(u);I!==null&&F(_,I.startTime-W)}}function C(W,I){x=!1,p&&(p=!1,g(R),R=-1),m=!0;var X=h;try{for(b(I),f=n(c);f!==null&&(!(f.expirationTime>I)||W&&!G());){var $=f.callback;if(typeof $=="function"){f.callback=null,h=f.priorityLevel;var B=$(f.expirationTime<=I);I=e.unstable_now(),typeof B=="function"?f.callback=B:f===n(c)&&r(c),b(I)}else r(c);f=n(c)}if(f!==null)var he=!0;else{var se=n(u);se!==null&&F(_,se.startTime-I),he=!1}return he}finally{f=null,h=X,m=!1}}var j=!1,T=null,R=-1,A=5,O=-1;function G(){return!(e.unstable_now()-OW||125$?(W.sortIndex=X,t(u,W),n(c)===null&&W===n(u)&&(p?(g(R),R=-1):p=!0,F(_,X-$))):(W.sortIndex=B,t(c,W),x||m||(x=!0,J(C))),W},e.unstable_shouldYield=G,e.unstable_wrapCallback=function(W){var I=h;return function(){var X=h;h=I;try{return W.apply(this,arguments)}finally{h=X}}}})(R1);P1.exports=R1;var LP=P1.exports;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var zP=y,Kn=LP;function ie(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),vp=Object.prototype.hasOwnProperty,FP=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,d0={},f0={};function $P(e){return vp.call(f0,e)?!0:vp.call(d0,e)?!1:FP.test(e)?f0[e]=!0:(d0[e]=!0,!1)}function UP(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function VP(e,t,n,r){if(t===null||typeof t>"u"||UP(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function jn(e,t,n,r,s,o,i){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=s,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var sn={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){sn[e]=new jn(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];sn[t]=new jn(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){sn[e]=new jn(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){sn[e]=new jn(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){sn[e]=new jn(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){sn[e]=new jn(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){sn[e]=new jn(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){sn[e]=new jn(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){sn[e]=new jn(e,5,!1,e.toLowerCase(),null,!1,!1)});var ay=/[\-:]([a-z])/g;function ly(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(ay,ly);sn[t]=new jn(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(ay,ly);sn[t]=new jn(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(ay,ly);sn[t]=new jn(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){sn[e]=new jn(e,1,!1,e.toLowerCase(),null,!1,!1)});sn.xlinkHref=new jn("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){sn[e]=new jn(e,1,!1,e.toLowerCase(),null,!0,!0)});function cy(e,t,n,r){var s=sn.hasOwnProperty(t)?sn[t]:null;(s!==null?s.type!==0:r||!(2a||s[i]!==o[a]){var c=` +`+s[i].replace(" at new "," at ");return e.displayName&&c.includes("")&&(c=c.replace("",e.displayName)),c}while(1<=i&&0<=a);break}}}finally{mm=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Pl(e):""}function BP(e){switch(e.tag){case 5:return Pl(e.type);case 16:return Pl("Lazy");case 13:return Pl("Suspense");case 19:return Pl("SuspenseList");case 0:case 2:case 15:return e=pm(e.type,!1),e;case 11:return e=pm(e.type.render,!1),e;case 1:return e=pm(e.type,!0),e;default:return""}}function _p(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Gi:return"Fragment";case Ki:return"Portal";case xp:return"Profiler";case uy:return"StrictMode";case wp:return"Suspense";case bp:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case O1:return(e.displayName||"Context")+".Consumer";case D1:return(e._context.displayName||"Context")+".Provider";case dy:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case fy:return t=e.displayName||null,t!==null?t:_p(e.type)||"Memo";case ro:t=e._payload,e=e._init;try{return _p(e(t))}catch{}}return null}function WP(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return _p(t);case 8:return t===uy?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function So(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function M1(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function HP(e){var t=M1(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var s=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return s.call(this)},set:function(i){r=""+i,o.call(this,i)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(i){r=""+i},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Nu(e){e._valueTracker||(e._valueTracker=HP(e))}function L1(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=M1(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function Nd(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Sp(e,t){var n=t.checked;return Mt({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function m0(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=So(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function z1(e,t){t=t.checked,t!=null&&cy(e,"checked",t,!1)}function kp(e,t){z1(e,t);var n=So(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?Cp(e,t.type,n):t.hasOwnProperty("defaultValue")&&Cp(e,t.type,So(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function p0(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function Cp(e,t,n){(t!=="number"||Nd(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var Rl=Array.isArray;function fa(e,t,n,r){if(e=e.options,t){t={};for(var s=0;s"+t.valueOf().toString()+"",t=Tu.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function rc(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Vl={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},YP=["Webkit","ms","Moz","O"];Object.keys(Vl).forEach(function(e){YP.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Vl[t]=Vl[e]})});function V1(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||Vl.hasOwnProperty(e)&&Vl[e]?(""+t).trim():t+"px"}function B1(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,s=V1(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,s):e[n]=s}}var KP=Mt({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Np(e,t){if(t){if(KP[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(ie(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(ie(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(ie(61))}if(t.style!=null&&typeof t.style!="object")throw Error(ie(62))}}function Tp(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Pp=null;function hy(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Rp=null,ha=null,ma=null;function v0(e){if(e=Xc(e)){if(typeof Rp!="function")throw Error(ie(280));var t=e.stateNode;t&&(t=Kf(t),Rp(e.stateNode,e.type,t))}}function W1(e){ha?ma?ma.push(e):ma=[e]:ha=e}function H1(){if(ha){var e=ha,t=ma;if(ma=ha=null,v0(e),t)for(e=0;e>>=0,e===0?32:31-(sR(e)/oR|0)|0}var Pu=64,Ru=4194304;function Al(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Ad(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,s=e.suspendedLanes,o=e.pingedLanes,i=n&268435455;if(i!==0){var a=i&~s;a!==0?r=Al(a):(o&=i,o!==0&&(r=Al(o)))}else i=n&~s,i!==0?r=Al(i):o!==0&&(r=Al(o));if(r===0)return 0;if(t!==0&&t!==r&&!(t&s)&&(s=r&-r,o=t&-t,s>=o||s===16&&(o&4194240)!==0))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Zc(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-jr(t),e[t]=n}function cR(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=Wl),E0=" ",N0=!1;function d_(e,t){switch(e){case"keyup":return LR.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function f_(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Zi=!1;function FR(e,t){switch(e){case"compositionend":return f_(t);case"keypress":return t.which!==32?null:(N0=!0,E0);case"textInput":return e=t.data,e===E0&&N0?null:e;default:return null}}function $R(e,t){if(Zi)return e==="compositionend"||!by&&d_(e,t)?(e=c_(),ad=vy=lo=null,Zi=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=A0(n)}}function g_(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?g_(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function y_(){for(var e=window,t=Nd();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=Nd(e.document)}return t}function _y(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function ZR(e){var t=y_(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&g_(n.ownerDocument.documentElement,n)){if(r!==null&&_y(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var s=n.textContent.length,o=Math.min(r.start,s);r=r.end===void 0?o:Math.min(r.end,s),!e.extend&&o>r&&(s=r,r=o,o=s),s=D0(n,o);var i=D0(n,r);s&&i&&(e.rangeCount!==1||e.anchorNode!==s.node||e.anchorOffset!==s.offset||e.focusNode!==i.node||e.focusOffset!==i.offset)&&(t=t.createRange(),t.setStart(s.node,s.offset),e.removeAllRanges(),o>r?(e.addRange(t),e.extend(i.node,i.offset)):(t.setEnd(i.node,i.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,qi=null,Lp=null,Yl=null,zp=!1;function O0(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;zp||qi==null||qi!==Nd(r)||(r=qi,"selectionStart"in r&&_y(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Yl&&cc(Yl,r)||(Yl=r,r=Id(Lp,"onSelect"),0Ji||(e.current=Wp[Ji],Wp[Ji]=null,Ji--)}function bt(e,t){Ji++,Wp[Ji]=e.current,e.current=t}var ko={},gn=Oo(ko),An=Oo(!1),si=ko;function Ea(e,t){var n=e.type.contextTypes;if(!n)return ko;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var s={},o;for(o in n)s[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=s),s}function Dn(e){return e=e.childContextTypes,e!=null}function Ld(){kt(An),kt(gn)}function U0(e,t,n){if(gn.current!==ko)throw Error(ie(168));bt(gn,t),bt(An,n)}function j_(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var s in r)if(!(s in t))throw Error(ie(108,WP(e)||"Unknown",s));return Mt({},n,r)}function zd(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||ko,si=gn.current,bt(gn,e),bt(An,An.current),!0}function V0(e,t,n){var r=e.stateNode;if(!r)throw Error(ie(169));n?(e=j_(e,t,si),r.__reactInternalMemoizedMergedChildContext=e,kt(An),kt(gn),bt(gn,e)):kt(An),bt(An,n)}var _s=null,Gf=!1,Tm=!1;function E_(e){_s===null?_s=[e]:_s.push(e)}function aA(e){Gf=!0,E_(e)}function Io(){if(!Tm&&_s!==null){Tm=!0;var e=0,t=gt;try{var n=_s;for(gt=1;e>=i,s-=i,Ss=1<<32-jr(t)+s|n<R?(A=T,T=null):A=T.sibling;var O=h(g,T,b[R],_);if(O===null){T===null&&(T=A);break}e&&T&&O.alternate===null&&t(g,T),v=o(O,v,R),j===null?C=O:j.sibling=O,j=O,T=A}if(R===b.length)return n(g,T),Pt&&$o(g,R),C;if(T===null){for(;RR?(A=T,T=null):A=T.sibling;var G=h(g,T,O.value,_);if(G===null){T===null&&(T=A);break}e&&T&&G.alternate===null&&t(g,T),v=o(G,v,R),j===null?C=G:j.sibling=G,j=G,T=A}if(O.done)return n(g,T),Pt&&$o(g,R),C;if(T===null){for(;!O.done;R++,O=b.next())O=f(g,O.value,_),O!==null&&(v=o(O,v,R),j===null?C=O:j.sibling=O,j=O);return Pt&&$o(g,R),C}for(T=r(g,T);!O.done;R++,O=b.next())O=m(T,g,R,O.value,_),O!==null&&(e&&O.alternate!==null&&T.delete(O.key===null?R:O.key),v=o(O,v,R),j===null?C=O:j.sibling=O,j=O);return e&&T.forEach(function(N){return t(g,N)}),Pt&&$o(g,R),C}function w(g,v,b,_){if(typeof b=="object"&&b!==null&&b.type===Gi&&b.key===null&&(b=b.props.children),typeof b=="object"&&b!==null){switch(b.$$typeof){case Eu:e:{for(var C=b.key,j=v;j!==null;){if(j.key===C){if(C=b.type,C===Gi){if(j.tag===7){n(g,j.sibling),v=s(j,b.props.children),v.return=g,g=v;break e}}else if(j.elementType===C||typeof C=="object"&&C!==null&&C.$$typeof===ro&&H0(C)===j.type){n(g,j.sibling),v=s(j,b.props),v.ref=gl(g,j,b),v.return=g,g=v;break e}n(g,j);break}else t(g,j);j=j.sibling}b.type===Gi?(v=ei(b.props.children,g.mode,_,b.key),v.return=g,g=v):(_=pd(b.type,b.key,b.props,null,g.mode,_),_.ref=gl(g,v,b),_.return=g,g=_)}return i(g);case Ki:e:{for(j=b.key;v!==null;){if(v.key===j)if(v.tag===4&&v.stateNode.containerInfo===b.containerInfo&&v.stateNode.implementation===b.implementation){n(g,v.sibling),v=s(v,b.children||[]),v.return=g,g=v;break e}else{n(g,v);break}else t(g,v);v=v.sibling}v=Lm(b,g.mode,_),v.return=g,g=v}return i(g);case ro:return j=b._init,w(g,v,j(b._payload),_)}if(Rl(b))return x(g,v,b,_);if(dl(b))return p(g,v,b,_);zu(g,b)}return typeof b=="string"&&b!==""||typeof b=="number"?(b=""+b,v!==null&&v.tag===6?(n(g,v.sibling),v=s(v,b),v.return=g,g=v):(n(g,v),v=Mm(b,g.mode,_),v.return=g,g=v),i(g)):n(g,v)}return w}var Ta=R_(!0),A_=R_(!1),Ud=Oo(null),Vd=null,na=null,jy=null;function Ey(){jy=na=Vd=null}function Ny(e){var t=Ud.current;kt(Ud),e._currentValue=t}function Kp(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function ga(e,t){Vd=e,jy=na=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&t&&(Rn=!0),e.firstContext=null)}function dr(e){var t=e._currentValue;if(jy!==e)if(e={context:e,memoizedValue:t,next:null},na===null){if(Vd===null)throw Error(ie(308));na=e,Vd.dependencies={lanes:0,firstContext:e}}else na=na.next=e;return t}var Ho=null;function Ty(e){Ho===null?Ho=[e]:Ho.push(e)}function D_(e,t,n,r){var s=t.interleaved;return s===null?(n.next=n,Ty(t)):(n.next=s.next,s.next=n),t.interleaved=n,Os(e,r)}function Os(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var so=!1;function Py(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function O_(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Es(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function vo(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,ct&2){var s=r.pending;return s===null?t.next=t:(t.next=s.next,s.next=t),r.pending=t,Os(e,n)}return s=r.interleaved,s===null?(t.next=t,Ty(r)):(t.next=s.next,s.next=t),r.interleaved=t,Os(e,n)}function cd(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,py(e,n)}}function Y0(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var s=null,o=null;if(n=n.firstBaseUpdate,n!==null){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};o===null?s=o=i:o=o.next=i,n=n.next}while(n!==null);o===null?s=o=t:o=o.next=t}else s=o=t;n={baseState:r.baseState,firstBaseUpdate:s,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Bd(e,t,n,r){var s=e.updateQueue;so=!1;var o=s.firstBaseUpdate,i=s.lastBaseUpdate,a=s.shared.pending;if(a!==null){s.shared.pending=null;var c=a,u=c.next;c.next=null,i===null?o=u:i.next=u,i=c;var d=e.alternate;d!==null&&(d=d.updateQueue,a=d.lastBaseUpdate,a!==i&&(a===null?d.firstBaseUpdate=u:a.next=u,d.lastBaseUpdate=c))}if(o!==null){var f=s.baseState;i=0,d=u=c=null,a=o;do{var h=a.lane,m=a.eventTime;if((r&h)===h){d!==null&&(d=d.next={eventTime:m,lane:0,tag:a.tag,payload:a.payload,callback:a.callback,next:null});e:{var x=e,p=a;switch(h=t,m=n,p.tag){case 1:if(x=p.payload,typeof x=="function"){f=x.call(m,f,h);break e}f=x;break e;case 3:x.flags=x.flags&-65537|128;case 0:if(x=p.payload,h=typeof x=="function"?x.call(m,f,h):x,h==null)break e;f=Mt({},f,h);break e;case 2:so=!0}}a.callback!==null&&a.lane!==0&&(e.flags|=64,h=s.effects,h===null?s.effects=[a]:h.push(a))}else m={eventTime:m,lane:h,tag:a.tag,payload:a.payload,callback:a.callback,next:null},d===null?(u=d=m,c=f):d=d.next=m,i|=h;if(a=a.next,a===null){if(a=s.shared.pending,a===null)break;h=a,a=h.next,h.next=null,s.lastBaseUpdate=h,s.shared.pending=null}}while(!0);if(d===null&&(c=f),s.baseState=c,s.firstBaseUpdate=u,s.lastBaseUpdate=d,t=s.shared.interleaved,t!==null){s=t;do i|=s.lane,s=s.next;while(s!==t)}else o===null&&(s.shared.lanes=0);ai|=i,e.lanes=i,e.memoizedState=f}}function K0(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=Rm.transition;Rm.transition={};try{e(!1),t()}finally{gt=n,Rm.transition=r}}function X_(){return fr().memoizedState}function dA(e,t,n){var r=wo(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Q_(e))J_(t,n);else if(n=D_(e,t,n,r),n!==null){var s=Sn();Er(n,e,r,s),eS(n,t,r)}}function fA(e,t,n){var r=wo(e),s={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Q_(e))J_(t,s);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=t.lastRenderedReducer,o!==null))try{var i=t.lastRenderedState,a=o(i,n);if(s.hasEagerState=!0,s.eagerState=a,Tr(a,i)){var c=t.interleaved;c===null?(s.next=s,Ty(t)):(s.next=c.next,c.next=s),t.interleaved=s;return}}catch{}finally{}n=D_(e,t,s,r),n!==null&&(s=Sn(),Er(n,e,r,s),eS(n,t,r))}}function Q_(e){var t=e.alternate;return e===It||t!==null&&t===It}function J_(e,t){Kl=Hd=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function eS(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,py(e,n)}}var Yd={readContext:dr,useCallback:fn,useContext:fn,useEffect:fn,useImperativeHandle:fn,useInsertionEffect:fn,useLayoutEffect:fn,useMemo:fn,useReducer:fn,useRef:fn,useState:fn,useDebugValue:fn,useDeferredValue:fn,useTransition:fn,useMutableSource:fn,useSyncExternalStore:fn,useId:fn,unstable_isNewReconciler:!1},hA={readContext:dr,useCallback:function(e,t){return Vr().memoizedState=[e,t===void 0?null:t],e},useContext:dr,useEffect:Z0,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,dd(4194308,4,Y_.bind(null,t,e),n)},useLayoutEffect:function(e,t){return dd(4194308,4,e,t)},useInsertionEffect:function(e,t){return dd(4,2,e,t)},useMemo:function(e,t){var n=Vr();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Vr();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=dA.bind(null,It,e),[r.memoizedState,e]},useRef:function(e){var t=Vr();return e={current:e},t.memoizedState=e},useState:G0,useDebugValue:zy,useDeferredValue:function(e){return Vr().memoizedState=e},useTransition:function(){var e=G0(!1),t=e[0];return e=uA.bind(null,e[1]),Vr().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=It,s=Vr();if(Pt){if(n===void 0)throw Error(ie(407));n=n()}else{if(n=t(),Jt===null)throw Error(ie(349));ii&30||z_(r,t,n)}s.memoizedState=n;var o={value:n,getSnapshot:t};return s.queue=o,Z0($_.bind(null,r,o,e),[e]),r.flags|=2048,yc(9,F_.bind(null,r,o,n,t),void 0,null),n},useId:function(){var e=Vr(),t=Jt.identifierPrefix;if(Pt){var n=ks,r=Ss;n=(r&~(1<<32-jr(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=pc++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=i.createElement(n,{is:r.is}):(e=i.createElement(n),n==="select"&&(i=e,r.multiple?i.multiple=!0:r.size&&(i.size=r.size))):e=i.createElementNS(e,n),e[Br]=t,e[fc]=r,uS(e,t,!1,!1),t.stateNode=e;e:{switch(i=Tp(n,r),n){case"dialog":St("cancel",e),St("close",e),s=r;break;case"iframe":case"object":case"embed":St("load",e),s=r;break;case"video":case"audio":for(s=0;sAa&&(t.flags|=128,r=!0,yl(o,!1),t.lanes=4194304)}else{if(!r)if(e=Wd(i),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),yl(o,!0),o.tail===null&&o.tailMode==="hidden"&&!i.alternate&&!Pt)return hn(t),null}else 2*Ut()-o.renderingStartTime>Aa&&n!==1073741824&&(t.flags|=128,r=!0,yl(o,!1),t.lanes=4194304);o.isBackwards?(i.sibling=t.child,t.child=i):(n=o.last,n!==null?n.sibling=i:t.child=i,o.last=i)}return o.tail!==null?(t=o.tail,o.rendering=t,o.tail=t.sibling,o.renderingStartTime=Ut(),t.sibling=null,n=Dt.current,bt(Dt,r?n&1|2:n&1),t):(hn(t),null);case 22:case 23:return Wy(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&t.mode&1?zn&1073741824&&(hn(t),t.subtreeFlags&6&&(t.flags|=8192)):hn(t),null;case 24:return null;case 25:return null}throw Error(ie(156,t.tag))}function bA(e,t){switch(ky(t),t.tag){case 1:return Dn(t.type)&&Ld(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Pa(),kt(An),kt(gn),Dy(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Ay(t),null;case 13:if(kt(Dt),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(ie(340));Na()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return kt(Dt),null;case 4:return Pa(),null;case 10:return Ny(t.type._context),null;case 22:case 23:return Wy(),null;case 24:return null;default:return null}}var $u=!1,mn=!1,_A=typeof WeakSet=="function"?WeakSet:Set,Ne=null;function ra(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){zt(e,t,r)}else n.current=null}function ng(e,t,n){try{n()}catch(r){zt(e,t,r)}}var iw=!1;function SA(e,t){if(Fp=Dd,e=y_(),_y(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var s=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break e}var i=0,a=-1,c=-1,u=0,d=0,f=e,h=null;t:for(;;){for(var m;f!==n||s!==0&&f.nodeType!==3||(a=i+s),f!==o||r!==0&&f.nodeType!==3||(c=i+r),f.nodeType===3&&(i+=f.nodeValue.length),(m=f.firstChild)!==null;)h=f,f=m;for(;;){if(f===e)break t;if(h===n&&++u===s&&(a=i),h===o&&++d===r&&(c=i),(m=f.nextSibling)!==null)break;f=h,h=f.parentNode}f=m}n=a===-1||c===-1?null:{start:a,end:c}}else n=null}n=n||{start:0,end:0}}else n=null;for($p={focusedElem:e,selectionRange:n},Dd=!1,Ne=t;Ne!==null;)if(t=Ne,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,Ne=e;else for(;Ne!==null;){t=Ne;try{var x=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(x!==null){var p=x.memoizedProps,w=x.memoizedState,g=t.stateNode,v=g.getSnapshotBeforeUpdate(t.elementType===t.type?p:yr(t.type,p),w);g.__reactInternalSnapshotBeforeUpdate=v}break;case 3:var b=t.stateNode.containerInfo;b.nodeType===1?b.textContent="":b.nodeType===9&&b.documentElement&&b.removeChild(b.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(ie(163))}}catch(_){zt(t,t.return,_)}if(e=t.sibling,e!==null){e.return=t.return,Ne=e;break}Ne=t.return}return x=iw,iw=!1,x}function Gl(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var s=r=r.next;do{if((s.tag&e)===e){var o=s.destroy;s.destroy=void 0,o!==void 0&&ng(t,n,o)}s=s.next}while(s!==r)}}function Xf(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function rg(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function hS(e){var t=e.alternate;t!==null&&(e.alternate=null,hS(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Br],delete t[fc],delete t[Bp],delete t[oA],delete t[iA])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function mS(e){return e.tag===5||e.tag===3||e.tag===4}function aw(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||mS(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function sg(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Md));else if(r!==4&&(e=e.child,e!==null))for(sg(e,t,n),e=e.sibling;e!==null;)sg(e,t,n),e=e.sibling}function og(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(og(e,t,n),e=e.sibling;e!==null;)og(e,t,n),e=e.sibling}var nn=null,vr=!1;function Qs(e,t,n){for(n=n.child;n!==null;)pS(e,t,n),n=n.sibling}function pS(e,t,n){if(Xr&&typeof Xr.onCommitFiberUnmount=="function")try{Xr.onCommitFiberUnmount(Bf,n)}catch{}switch(n.tag){case 5:mn||ra(n,t);case 6:var r=nn,s=vr;nn=null,Qs(e,t,n),nn=r,vr=s,nn!==null&&(vr?(e=nn,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):nn.removeChild(n.stateNode));break;case 18:nn!==null&&(vr?(e=nn,n=n.stateNode,e.nodeType===8?Nm(e.parentNode,n):e.nodeType===1&&Nm(e,n),ac(e)):Nm(nn,n.stateNode));break;case 4:r=nn,s=vr,nn=n.stateNode.containerInfo,vr=!0,Qs(e,t,n),nn=r,vr=s;break;case 0:case 11:case 14:case 15:if(!mn&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){s=r=r.next;do{var o=s,i=o.destroy;o=o.tag,i!==void 0&&(o&2||o&4)&&ng(n,t,i),s=s.next}while(s!==r)}Qs(e,t,n);break;case 1:if(!mn&&(ra(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(a){zt(n,t,a)}Qs(e,t,n);break;case 21:Qs(e,t,n);break;case 22:n.mode&1?(mn=(r=mn)||n.memoizedState!==null,Qs(e,t,n),mn=r):Qs(e,t,n);break;default:Qs(e,t,n)}}function lw(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new _A),t.forEach(function(r){var s=AA.bind(null,e,r);n.has(r)||(n.add(r),r.then(s,s))})}}function gr(e,t){var n=t.deletions;if(n!==null)for(var r=0;rs&&(s=i),r&=~o}if(r=s,r=Ut()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*CA(r/1960))-r,10e?16:e,co===null)var r=!1;else{if(e=co,co=null,Zd=0,ct&6)throw Error(ie(331));var s=ct;for(ct|=4,Ne=e.current;Ne!==null;){var o=Ne,i=o.child;if(Ne.flags&16){var a=o.deletions;if(a!==null){for(var c=0;cUt()-Vy?Jo(e,0):Uy|=n),On(e,t)}function SS(e,t){t===0&&(e.mode&1?(t=Ru,Ru<<=1,!(Ru&130023424)&&(Ru=4194304)):t=1);var n=Sn();e=Os(e,t),e!==null&&(Zc(e,t,n),On(e,n))}function RA(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),SS(e,n)}function AA(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,s=e.memoizedState;s!==null&&(n=s.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(ie(314))}r!==null&&r.delete(t),SS(e,n)}var kS;kS=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||An.current)Rn=!0;else{if(!(e.lanes&n)&&!(t.flags&128))return Rn=!1,xA(e,t,n);Rn=!!(e.flags&131072)}else Rn=!1,Pt&&t.flags&1048576&&N_(t,$d,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;fd(e,t),e=t.pendingProps;var s=Ea(t,gn.current);ga(t,n),s=Iy(null,t,r,e,s,n);var o=My();return t.flags|=1,typeof s=="object"&&s!==null&&typeof s.render=="function"&&s.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Dn(r)?(o=!0,zd(t)):o=!1,t.memoizedState=s.state!==null&&s.state!==void 0?s.state:null,Py(t),s.updater=qf,t.stateNode=s,s._reactInternals=t,Zp(t,r,e,n),t=Qp(null,t,r,!0,o,n)):(t.tag=0,Pt&&o&&Sy(t),bn(null,t,s,n),t=t.child),t;case 16:r=t.elementType;e:{switch(fd(e,t),e=t.pendingProps,s=r._init,r=s(r._payload),t.type=r,s=t.tag=OA(r),e=yr(r,e),s){case 0:t=Xp(null,t,r,e,n);break e;case 1:t=rw(null,t,r,e,n);break e;case 11:t=tw(null,t,r,e,n);break e;case 14:t=nw(null,t,r,yr(r.type,e),n);break e}throw Error(ie(306,r,""))}return t;case 0:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:yr(r,s),Xp(e,t,r,s,n);case 1:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:yr(r,s),rw(e,t,r,s,n);case 3:e:{if(aS(t),e===null)throw Error(ie(387));r=t.pendingProps,o=t.memoizedState,s=o.element,O_(e,t),Bd(t,r,null,n);var i=t.memoizedState;if(r=i.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){s=Ra(Error(ie(423)),t),t=sw(e,t,r,n,s);break e}else if(r!==s){s=Ra(Error(ie(424)),t),t=sw(e,t,r,n,s);break e}else for(Un=yo(t.stateNode.containerInfo.firstChild),Vn=t,Pt=!0,wr=null,n=A_(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Na(),r===s){t=Is(e,t,n);break e}bn(e,t,r,n)}t=t.child}return t;case 5:return I_(t),e===null&&Yp(t),r=t.type,s=t.pendingProps,o=e!==null?e.memoizedProps:null,i=s.children,Up(r,s)?i=null:o!==null&&Up(r,o)&&(t.flags|=32),iS(e,t),bn(e,t,i,n),t.child;case 6:return e===null&&Yp(t),null;case 13:return lS(e,t,n);case 4:return Ry(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Ta(t,null,r,n):bn(e,t,r,n),t.child;case 11:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:yr(r,s),tw(e,t,r,s,n);case 7:return bn(e,t,t.pendingProps,n),t.child;case 8:return bn(e,t,t.pendingProps.children,n),t.child;case 12:return bn(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,s=t.pendingProps,o=t.memoizedProps,i=s.value,bt(Ud,r._currentValue),r._currentValue=i,o!==null)if(Tr(o.value,i)){if(o.children===s.children&&!An.current){t=Is(e,t,n);break e}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var a=o.dependencies;if(a!==null){i=o.child;for(var c=a.firstContext;c!==null;){if(c.context===r){if(o.tag===1){c=Es(-1,n&-n),c.tag=2;var u=o.updateQueue;if(u!==null){u=u.shared;var d=u.pending;d===null?c.next=c:(c.next=d.next,d.next=c),u.pending=c}}o.lanes|=n,c=o.alternate,c!==null&&(c.lanes|=n),Kp(o.return,n,t),a.lanes|=n;break}c=c.next}}else if(o.tag===10)i=o.type===t.type?null:o.child;else if(o.tag===18){if(i=o.return,i===null)throw Error(ie(341));i.lanes|=n,a=i.alternate,a!==null&&(a.lanes|=n),Kp(i,n,t),i=o.sibling}else i=o.child;if(i!==null)i.return=o;else for(i=o;i!==null;){if(i===t){i=null;break}if(o=i.sibling,o!==null){o.return=i.return,i=o;break}i=i.return}o=i}bn(e,t,s.children,n),t=t.child}return t;case 9:return s=t.type,r=t.pendingProps.children,ga(t,n),s=dr(s),r=r(s),t.flags|=1,bn(e,t,r,n),t.child;case 14:return r=t.type,s=yr(r,t.pendingProps),s=yr(r.type,s),nw(e,t,r,s,n);case 15:return sS(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,s=t.pendingProps,s=t.elementType===r?s:yr(r,s),fd(e,t),t.tag=1,Dn(r)?(e=!0,zd(t)):e=!1,ga(t,n),tS(t,r,s),Zp(t,r,s,n),Qp(null,t,r,!0,e,n);case 19:return cS(e,t,n);case 22:return oS(e,t,n)}throw Error(ie(156,t.tag))};function CS(e,t){return Q1(e,t)}function DA(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ir(e,t,n,r){return new DA(e,t,n,r)}function Yy(e){return e=e.prototype,!(!e||!e.isReactComponent)}function OA(e){if(typeof e=="function")return Yy(e)?1:0;if(e!=null){if(e=e.$$typeof,e===dy)return 11;if(e===fy)return 14}return 2}function bo(e,t){var n=e.alternate;return n===null?(n=ir(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function pd(e,t,n,r,s,o){var i=2;if(r=e,typeof e=="function")Yy(e)&&(i=1);else if(typeof e=="string")i=5;else e:switch(e){case Gi:return ei(n.children,s,o,t);case uy:i=8,s|=8;break;case xp:return e=ir(12,n,t,s|2),e.elementType=xp,e.lanes=o,e;case wp:return e=ir(13,n,t,s),e.elementType=wp,e.lanes=o,e;case bp:return e=ir(19,n,t,s),e.elementType=bp,e.lanes=o,e;case I1:return Jf(n,s,o,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case D1:i=10;break e;case O1:i=9;break e;case dy:i=11;break e;case fy:i=14;break e;case ro:i=16,r=null;break e}throw Error(ie(130,e==null?e:typeof e,""))}return t=ir(i,n,t,s),t.elementType=e,t.type=r,t.lanes=o,t}function ei(e,t,n,r){return e=ir(7,e,r,t),e.lanes=n,e}function Jf(e,t,n,r){return e=ir(22,e,r,t),e.elementType=I1,e.lanes=n,e.stateNode={isHidden:!1},e}function Mm(e,t,n){return e=ir(6,e,null,t),e.lanes=n,e}function Lm(e,t,n){return t=ir(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function IA(e,t,n,r,s){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ym(0),this.expirationTimes=ym(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ym(0),this.identifierPrefix=r,this.onRecoverableError=s,this.mutableSourceEagerHydrationData=null}function Ky(e,t,n,r,s,o,i,a,c){return e=new IA(e,t,n,a,c),t===1?(t=1,o===!0&&(t|=8)):t=0,o=ir(3,null,null,t),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Py(o),e}function MA(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(TS)}catch(e){console.error(e)}}TS(),T1.exports=Xn;var Vs=T1.exports;const PS=Uf(Vs),UA=g1({__proto__:null,default:PS},[Vs]);var gw=Vs;yp.createRoot=gw.createRoot,yp.hydrateRoot=gw.hydrateRoot;/** + * @remix-run/router v1.18.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function At(){return At=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u")throw new Error(t)}function ci(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function BA(){return Math.random().toString(36).substr(2,8)}function vw(e,t){return{usr:e.state,key:e.key,idx:t}}function xc(e,t,n,r){return n===void 0&&(n=null),At({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?Bs(t):t,{state:n,key:t&&t.key||r||BA()})}function ui(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&n!=="?"&&(t+=n.charAt(0)==="?"?n:"?"+n),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function Bs(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function WA(e,t,n,r){r===void 0&&(r={});let{window:s=document.defaultView,v5Compat:o=!1}=r,i=s.history,a=Wt.Pop,c=null,u=d();u==null&&(u=0,i.replaceState(At({},i.state,{idx:u}),""));function d(){return(i.state||{idx:null}).idx}function f(){a=Wt.Pop;let w=d(),g=w==null?null:w-u;u=w,c&&c({action:a,location:p.location,delta:g})}function h(w,g){a=Wt.Push;let v=xc(p.location,w,g);n&&n(v,w),u=d()+1;let b=vw(v,u),_=p.createHref(v);try{i.pushState(b,"",_)}catch(C){if(C instanceof DOMException&&C.name==="DataCloneError")throw C;s.location.assign(_)}o&&c&&c({action:a,location:p.location,delta:1})}function m(w,g){a=Wt.Replace;let v=xc(p.location,w,g);n&&n(v,w),u=d();let b=vw(v,u),_=p.createHref(v);i.replaceState(b,"",_),o&&c&&c({action:a,location:p.location,delta:0})}function x(w){let g=s.location.origin!=="null"?s.location.origin:s.location.href,v=typeof w=="string"?w:ui(w);return v=v.replace(/ $/,"%20"),tt(g,"No window.location.(origin|href) available to create URL for href: "+v),new URL(v,g)}let p={get action(){return a},get location(){return e(s,i)},listen(w){if(c)throw new Error("A history only accepts one active listener");return s.addEventListener(yw,f),c=w,()=>{s.removeEventListener(yw,f),c=null}},createHref(w){return t(s,w)},createURL:x,encodeLocation(w){let g=x(w);return{pathname:g.pathname,search:g.search,hash:g.hash}},push:h,replace:m,go(w){return i.go(w)}};return p}var wt;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(wt||(wt={}));const HA=new Set(["lazy","caseSensitive","path","id","index","children"]);function YA(e){return e.index===!0}function wc(e,t,n,r){return n===void 0&&(n=[]),r===void 0&&(r={}),e.map((s,o)=>{let i=[...n,String(o)],a=typeof s.id=="string"?s.id:i.join("-");if(tt(s.index!==!0||!s.children,"Cannot specify children on an index route"),tt(!r[a],'Found a route id collision on id "'+a+`". Route id's must be globally unique within Data Router usages`),YA(s)){let c=At({},s,t(s),{id:a});return r[a]=c,c}else{let c=At({},s,t(s),{id:a,children:void 0});return r[a]=c,s.children&&(c.children=wc(s.children,t,i,r)),c}})}function Bo(e,t,n){return n===void 0&&(n="/"),gd(e,t,n,!1)}function gd(e,t,n,r){let s=typeof t=="string"?Bs(t):t,o=Za(s.pathname||"/",n);if(o==null)return null;let i=RS(e);GA(i);let a=null;for(let c=0;a==null&&c{let c={relativePath:a===void 0?o.path||"":a,caseSensitive:o.caseSensitive===!0,childrenIndex:i,route:o};c.relativePath.startsWith("/")&&(tt(c.relativePath.startsWith(r),'Absolute route path "'+c.relativePath+'" nested under path '+('"'+r+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),c.relativePath=c.relativePath.slice(r.length));let u=Ns([r,c.relativePath]),d=n.concat(c);o.children&&o.children.length>0&&(tt(o.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+u+'".')),RS(o.children,t,d,u)),!(o.path==null&&!o.index)&&t.push({path:u,score:tD(u,o.index),routesMeta:d})};return e.forEach((o,i)=>{var a;if(o.path===""||!((a=o.path)!=null&&a.includes("?")))s(o,i);else for(let c of AS(o.path))s(o,i,c)}),t}function AS(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,s=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return s?[o,""]:[o];let i=AS(r.join("/")),a=[];return a.push(...i.map(c=>c===""?o:[o,c].join("/"))),s&&a.push(...i),a.map(c=>e.startsWith("/")&&c===""?"/":c)}function GA(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:nD(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const ZA=/^:[\w-]+$/,qA=3,XA=2,QA=1,JA=10,eD=-2,xw=e=>e==="*";function tD(e,t){let n=e.split("/"),r=n.length;return n.some(xw)&&(r+=eD),t&&(r+=XA),n.filter(s=>!xw(s)).reduce((s,o)=>s+(ZA.test(o)?qA:o===""?QA:JA),r)}function nD(e,t){return e.length===t.length&&e.slice(0,-1).every((r,s)=>r===t[s])?e[e.length-1]-t[t.length-1]:0}function rD(e,t,n){n===void 0&&(n=!1);let{routesMeta:r}=e,s={},o="/",i=[];for(let a=0;a{let{paramName:h,isOptional:m}=d;if(h==="*"){let p=a[f]||"";i=o.slice(0,o.length-p.length).replace(/(.)\/+$/,"$1")}const x=a[f];return m&&!x?u[h]=void 0:u[h]=(x||"").replace(/%2F/g,"/"),u},{}),pathname:o,pathnameBase:i,pattern:e}}function sD(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),ci(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let r=[],s="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(i,a,c)=>(r.push({paramName:a,isOptional:c!=null}),c?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),s+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?s+="\\/*$":e!==""&&e!=="/"&&(s+="(?:(?=\\/|$))"),[new RegExp(s,t?void 0:"i"),r]}function oD(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return ci(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function Za(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}function iD(e,t){t===void 0&&(t="/");let{pathname:n,search:r="",hash:s=""}=typeof e=="string"?Bs(e):e;return{pathname:n?n.startsWith("/")?n:aD(n,t):t,search:cD(r),hash:uD(s)}}function aD(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(s=>{s===".."?n.length>1&&n.pop():s!=="."&&n.push(s)}),n.length>1?n.join("/"):"/"}function zm(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(r)+"]. Please separate it out to the ")+("`to."+n+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function DS(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function sh(e,t){let n=DS(e);return t?n.map((r,s)=>s===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function oh(e,t,n,r){r===void 0&&(r=!1);let s;typeof e=="string"?s=Bs(e):(s=At({},e),tt(!s.pathname||!s.pathname.includes("?"),zm("?","pathname","search",s)),tt(!s.pathname||!s.pathname.includes("#"),zm("#","pathname","hash",s)),tt(!s.search||!s.search.includes("#"),zm("#","search","hash",s)));let o=e===""||s.pathname==="",i=o?"/":s.pathname,a;if(i==null)a=n;else{let f=t.length-1;if(!r&&i.startsWith("..")){let h=i.split("/");for(;h[0]==="..";)h.shift(),f-=1;s.pathname=h.join("/")}a=f>=0?t[f]:"/"}let c=iD(s,a),u=i&&i!=="/"&&i.endsWith("/"),d=(o||i===".")&&n.endsWith("/");return!c.pathname.endsWith("/")&&(u||d)&&(c.pathname+="/"),c}const Ns=e=>e.join("/").replace(/\/\/+/g,"/"),lD=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),cD=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,uD=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;class Xy{constructor(t,n,r,s){s===void 0&&(s=!1),this.status=t,this.statusText=n||"",this.internal=s,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}}function ih(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const OS=["post","put","patch","delete"],dD=new Set(OS),fD=["get",...OS],hD=new Set(fD),mD=new Set([301,302,303,307,308]),pD=new Set([307,308]),Fm={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},gD={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},xl={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},Qy=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,yD=e=>({hasErrorBoundary:!!e.hasErrorBoundary}),IS="remix-router-transitions";function vD(e){const t=e.window?e.window:typeof window<"u"?window:void 0,n=typeof t<"u"&&typeof t.document<"u"&&typeof t.document.createElement<"u",r=!n;tt(e.routes.length>0,"You must provide a non-empty routes array to createRouter");let s;if(e.mapRouteProperties)s=e.mapRouteProperties;else if(e.detectErrorBoundary){let V=e.detectErrorBoundary;s=H=>({hasErrorBoundary:V(H)})}else s=yD;let o={},i=wc(e.routes,s,void 0,o),a,c=e.basename||"/",u=e.unstable_dataStrategy||SD,d=e.unstable_patchRoutesOnMiss,f=At({v7_fetcherPersist:!1,v7_normalizeFormMethod:!1,v7_partialHydration:!1,v7_prependBasename:!1,v7_relativeSplatPath:!1,v7_skipActionErrorRevalidation:!1},e.future),h=null,m=new Set,x=null,p=null,w=null,g=e.hydrationData!=null,v=Bo(i,e.history.location,c),b=null;if(v==null&&!d){let V=xn(404,{pathname:e.history.location.pathname}),{matches:H,route:q}=Pw(i);v=H,b={[q.id]:V}}v&&d&&!e.hydrationData&&dm(v,i,e.history.location.pathname).active&&(v=null);let _;if(!v)_=!1,v=[];else if(v.some(V=>V.route.lazy))_=!1;else if(!v.some(V=>V.route.loader))_=!0;else if(f.v7_partialHydration){let V=e.hydrationData?e.hydrationData.loaderData:null,H=e.hydrationData?e.hydrationData.errors:null,q=ne=>ne.route.loader?typeof ne.route.loader=="function"&&ne.route.loader.hydrate===!0?!1:V&&V[ne.route.id]!==void 0||H&&H[ne.route.id]!==void 0:!0;if(H){let ne=v.findIndex(be=>H[be.route.id]!==void 0);_=v.slice(0,ne+1).every(q)}else _=v.every(q)}else _=e.hydrationData!=null;let C,j={historyAction:e.history.action,location:e.history.location,matches:v,initialized:_,navigation:Fm,restoreScrollPosition:e.hydrationData!=null?!1:null,preventScrollReset:!1,revalidation:"idle",loaderData:e.hydrationData&&e.hydrationData.loaderData||{},actionData:e.hydrationData&&e.hydrationData.actionData||null,errors:e.hydrationData&&e.hydrationData.errors||b,fetchers:new Map,blockers:new Map},T=Wt.Pop,R=!1,A,O=!1,G=new Map,N=null,z=!1,S=!1,U=[],J=[],F=new Map,W=0,I=-1,X=new Map,$=new Set,B=new Map,he=new Map,se=new Set,oe=new Map,Oe=new Map,me=new Map,we=!1;function Te(){if(h=e.history.listen(V=>{let{action:H,location:q,delta:ne}=V;if(we){we=!1;return}ci(Oe.size===0||ne!=null,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let be=wu({currentLocation:j.location,nextLocation:q,historyAction:H});if(be&&ne!=null){we=!0,e.history.go(ne*-1),Ri(be,{state:"blocked",location:q,proceed(){Ri(be,{state:"proceeding",proceed:void 0,reset:void 0,location:q}),e.history.go(ne)},reset(){let Ae=new Map(j.blockers);Ae.set(be,xl),Re({blockers:Ae})}});return}return Z(H,q)}),n){MD(t,G);let V=()=>LD(t,G);t.addEventListener("pagehide",V),N=()=>t.removeEventListener("pagehide",V)}return j.initialized||Z(Wt.Pop,j.location,{initialHydration:!0}),C}function Fe(){h&&h(),N&&N(),m.clear(),A&&A.abort(),j.fetchers.forEach((V,H)=>Yt(H)),j.blockers.forEach((V,H)=>xu(H))}function Ie(V){return m.add(V),()=>m.delete(V)}function Re(V,H){H===void 0&&(H={}),j=At({},j,V);let q=[],ne=[];f.v7_fetcherPersist&&j.fetchers.forEach((be,Ae)=>{be.state==="idle"&&(se.has(Ae)?ne.push(Ae):q.push(Ae))}),[...m].forEach(be=>be(j,{deletedFetchers:ne,unstable_viewTransitionOpts:H.viewTransitionOpts,unstable_flushSync:H.flushSync===!0})),f.v7_fetcherPersist&&(q.forEach(be=>j.fetchers.delete(be)),ne.forEach(be=>Yt(be)))}function st(V,H,q){var ne,be;let{flushSync:Ae}=q===void 0?{}:q,Be=j.actionData!=null&&j.navigation.formMethod!=null&&xr(j.navigation.formMethod)&&j.navigation.state==="loading"&&((ne=V.state)==null?void 0:ne._isRedirect)!==!0,fe;H.actionData?Object.keys(H.actionData).length>0?fe=H.actionData:fe=null:Be?fe=j.actionData:fe=null;let qe=H.loaderData?Nw(j.loaderData,H.loaderData,H.matches||[],H.errors):j.loaderData,ze=j.blockers;ze.size>0&&(ze=new Map(ze),ze.forEach((pt,xt)=>ze.set(xt,xl)));let $e=R===!0||j.navigation.formMethod!=null&&xr(j.navigation.formMethod)&&((be=V.state)==null?void 0:be._isRedirect)!==!0;a&&(i=a,a=void 0),z||T===Wt.Pop||(T===Wt.Push?e.history.push(V,V.state):T===Wt.Replace&&e.history.replace(V,V.state));let yt;if(T===Wt.Pop){let pt=G.get(j.location.pathname);pt&&pt.has(V.pathname)?yt={currentLocation:j.location,nextLocation:V}:G.has(V.pathname)&&(yt={currentLocation:V,nextLocation:j.location})}else if(O){let pt=G.get(j.location.pathname);pt?pt.add(V.pathname):(pt=new Set([V.pathname]),G.set(j.location.pathname,pt)),yt={currentLocation:j.location,nextLocation:V}}Re(At({},H,{actionData:fe,loaderData:qe,historyAction:T,location:V,initialized:!0,navigation:Fm,revalidation:"idle",restoreScrollPosition:i0(V,H.matches||j.matches),preventScrollReset:$e,blockers:ze}),{viewTransitionOpts:yt,flushSync:Ae===!0}),T=Wt.Pop,R=!1,O=!1,z=!1,S=!1,U=[],J=[]}async function E(V,H){if(typeof V=="number"){e.history.go(V);return}let q=ug(j.location,j.matches,c,f.v7_prependBasename,V,f.v7_relativeSplatPath,H==null?void 0:H.fromRouteId,H==null?void 0:H.relative),{path:ne,submission:be,error:Ae}=bw(f.v7_normalizeFormMethod,!1,q,H),Be=j.location,fe=xc(j.location,ne,H&&H.state);fe=At({},fe,e.history.encodeLocation(fe));let qe=H&&H.replace!=null?H.replace:void 0,ze=Wt.Push;qe===!0?ze=Wt.Replace:qe===!1||be!=null&&xr(be.formMethod)&&be.formAction===j.location.pathname+j.location.search&&(ze=Wt.Replace);let $e=H&&"preventScrollReset"in H?H.preventScrollReset===!0:void 0,yt=(H&&H.unstable_flushSync)===!0,pt=wu({currentLocation:Be,nextLocation:fe,historyAction:ze});if(pt){Ri(pt,{state:"blocked",location:fe,proceed(){Ri(pt,{state:"proceeding",proceed:void 0,reset:void 0,location:fe}),E(V,H)},reset(){let xt=new Map(j.blockers);xt.set(pt,xl),Re({blockers:xt})}});return}return await Z(ze,fe,{submission:be,pendingError:Ae,preventScrollReset:$e,replace:H&&H.replace,enableViewTransition:H&&H.unstable_viewTransition,flushSync:yt})}function ee(){if(Ke(),Re({revalidation:"loading"}),j.navigation.state!=="submitting"){if(j.navigation.state==="idle"){Z(j.historyAction,j.location,{startUninterruptedRevalidation:!0});return}Z(T||j.historyAction,j.navigation.location,{overrideNavigation:j.navigation})}}async function Z(V,H,q){A&&A.abort(),A=null,T=V,z=(q&&q.startUninterruptedRevalidation)===!0,dP(j.location,j.matches),R=(q&&q.preventScrollReset)===!0,O=(q&&q.enableViewTransition)===!0;let ne=a||i,be=q&&q.overrideNavigation,Ae=Bo(ne,H,c),Be=(q&&q.flushSync)===!0,fe=dm(Ae,ne,H.pathname);if(fe.active&&fe.matches&&(Ae=fe.matches),!Ae){let{error:ht,notFoundMatches:tn,route:Bt}=Ai(H.pathname);st(H,{matches:tn,loaderData:{},errors:{[Bt.id]:ht}},{flushSync:Be});return}if(j.initialized&&!S&&TD(j.location,H)&&!(q&&q.submission&&xr(q.submission.formMethod))){st(H,{matches:Ae},{flushSync:Be});return}A=new AbortController;let qe=Li(e.history,H,A.signal,q&&q.submission),ze;if(q&&q.pendingError)ze=[oa(Ae).route.id,{type:wt.error,error:q.pendingError}];else if(q&&q.submission&&xr(q.submission.formMethod)){let ht=await D(qe,H,q.submission,Ae,fe.active,{replace:q.replace,flushSync:Be});if(ht.shortCircuited)return;if(ht.pendingActionResult){let[tn,Bt]=ht.pendingActionResult;if(Fn(Bt)&&ih(Bt.error)&&Bt.error.status===404){A=null,st(H,{matches:ht.matches,loaderData:{},errors:{[tn]:Bt.error}});return}}Ae=ht.matches||Ae,ze=ht.pendingActionResult,be=$m(H,q.submission),Be=!1,fe.active=!1,qe=Li(e.history,qe.url,qe.signal)}let{shortCircuited:$e,matches:yt,loaderData:pt,errors:xt}=await k(qe,H,Ae,fe.active,be,q&&q.submission,q&&q.fetcherSubmission,q&&q.replace,q&&q.initialHydration===!0,Be,ze);$e||(A=null,st(H,At({matches:yt||Ae},Tw(ze),{loaderData:pt,errors:xt})))}async function D(V,H,q,ne,be,Ae){Ae===void 0&&(Ae={}),Ke();let Be=OD(H,q);if(Re({navigation:Be},{flushSync:Ae.flushSync===!0}),be){let ze=await bu(ne,H.pathname,V.signal);if(ze.type==="aborted")return{shortCircuited:!0};if(ze.type==="error"){let{boundaryId:$e,error:yt}=Fr(H.pathname,ze);return{matches:ze.partialMatches,pendingActionResult:[$e,{type:wt.error,error:yt}]}}else if(ze.matches)ne=ze.matches;else{let{notFoundMatches:$e,error:yt,route:pt}=Ai(H.pathname);return{matches:$e,pendingActionResult:[pt.id,{type:wt.error,error:yt}]}}}let fe,qe=Ol(ne,H);if(!qe.route.action&&!qe.route.lazy)fe={type:wt.error,error:xn(405,{method:V.method,pathname:H.pathname,routeId:qe.route.id})};else if(fe=(await te("action",V,[qe],ne))[0],V.signal.aborted)return{shortCircuited:!0};if(Go(fe)){let ze;return Ae&&Ae.replace!=null?ze=Ae.replace:ze=Cw(fe.response.headers.get("Location"),new URL(V.url),c)===j.location.pathname+j.location.search,await Q(V,fe,{submission:q,replace:ze}),{shortCircuited:!0}}if(Ko(fe))throw xn(400,{type:"defer-action"});if(Fn(fe)){let ze=oa(ne,qe.route.id);return(Ae&&Ae.replace)!==!0&&(T=Wt.Push),{matches:ne,pendingActionResult:[ze.route.id,fe]}}return{matches:ne,pendingActionResult:[qe.route.id,fe]}}async function k(V,H,q,ne,be,Ae,Be,fe,qe,ze,$e){let yt=be||$m(H,Ae),pt=Ae||Be||Dw(yt),xt=!z&&(!f.v7_partialHydration||!qe);if(ne){if(xt){let Lt=P($e);Re(At({navigation:yt},Lt!==void 0?{actionData:Lt}:{}),{flushSync:ze})}let Je=await bu(q,H.pathname,V.signal);if(Je.type==="aborted")return{shortCircuited:!0};if(Je.type==="error"){let{boundaryId:Lt,error:In}=Fr(H.pathname,Je);return{matches:Je.partialMatches,loaderData:{},errors:{[Lt]:In}}}else if(Je.matches)q=Je.matches;else{let{error:Lt,notFoundMatches:In,route:Nt}=Ai(H.pathname);return{matches:In,loaderData:{},errors:{[Nt.id]:Lt}}}}let ht=a||i,[tn,Bt]=_w(e.history,j,q,pt,H,f.v7_partialHydration&&qe===!0,f.v7_skipActionErrorRevalidation,S,U,J,se,B,$,ht,c,$e);if(qs(Je=>!(q&&q.some(Lt=>Lt.route.id===Je))||tn&&tn.some(Lt=>Lt.route.id===Je)),I=++W,tn.length===0&&Bt.length===0){let Je=hs();return st(H,At({matches:q,loaderData:{},errors:$e&&Fn($e[1])?{[$e[0]]:$e[1].error}:null},Tw($e),Je?{fetchers:new Map(j.fetchers)}:{}),{flushSync:ze}),{shortCircuited:!0}}if(xt){let Je={};if(!ne){Je.navigation=yt;let Lt=P($e);Lt!==void 0&&(Je.actionData=Lt)}Bt.length>0&&(Je.fetchers=M(Bt)),Re(Je,{flushSync:ze})}Bt.forEach(Je=>{F.has(Je.key)&<(Je.key),Je.controller&&F.set(Je.key,Je.controller)});let ul=()=>Bt.forEach(Je=>lt(Je.key));A&&A.signal.addEventListener("abort",ul);let{loaderResults:Xs,fetcherResults:Di}=await ge(j.matches,q,tn,Bt,V);if(V.signal.aborted)return{shortCircuited:!0};A&&A.signal.removeEventListener("abort",ul),Bt.forEach(Je=>F.delete(Je.key));let Oi=Rw([...Xs,...Di]);if(Oi){if(Oi.idx>=tn.length){let Je=Bt[Oi.idx-tn.length].key;$.add(Je)}return await Q(V,Oi.result,{replace:fe}),{shortCircuited:!0}}let{loaderData:Ii,errors:$r}=Ew(j,q,tn,Xs,$e,Bt,Di,oe);oe.forEach((Je,Lt)=>{Je.subscribe(In=>{(In||Je.done)&&oe.delete(Lt)})}),f.v7_partialHydration&&qe&&j.errors&&Object.entries(j.errors).filter(Je=>{let[Lt]=Je;return!tn.some(In=>In.route.id===Lt)}).forEach(Je=>{let[Lt,In]=Je;$r=Object.assign($r||{},{[Lt]:In})});let _u=hs(),Su=nr(I),ku=_u||Su||Bt.length>0;return At({matches:q,loaderData:Ii,errors:$r},ku?{fetchers:new Map(j.fetchers)}:{})}function P(V){if(V&&!Fn(V[1]))return{[V[0]]:V[1].data};if(j.actionData)return Object.keys(j.actionData).length===0?null:j.actionData}function M(V){return V.forEach(H=>{let q=j.fetchers.get(H.key),ne=wl(void 0,q?q.data:void 0);j.fetchers.set(H.key,ne)}),new Map(j.fetchers)}function K(V,H,q,ne){if(r)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");F.has(V)&<(V);let be=(ne&&ne.unstable_flushSync)===!0,Ae=a||i,Be=ug(j.location,j.matches,c,f.v7_prependBasename,q,f.v7_relativeSplatPath,H,ne==null?void 0:ne.relative),fe=Bo(Ae,Be,c),qe=dm(fe,Ae,Be);if(qe.active&&qe.matches&&(fe=qe.matches),!fe){Et(V,H,xn(404,{pathname:Be}),{flushSync:be});return}let{path:ze,submission:$e,error:yt}=bw(f.v7_normalizeFormMethod,!0,Be,ne);if(yt){Et(V,H,yt,{flushSync:be});return}let pt=Ol(fe,ze);if(R=(ne&&ne.preventScrollReset)===!0,$e&&xr($e.formMethod)){L(V,H,ze,pt,fe,qe.active,be,$e);return}B.set(V,{routeId:H,path:ze}),Y(V,H,ze,pt,fe,qe.active,be,$e)}async function L(V,H,q,ne,be,Ae,Be,fe){Ke(),B.delete(V);function qe(Nt){if(!Nt.route.action&&!Nt.route.lazy){let ms=xn(405,{method:fe.formMethod,pathname:q,routeId:H});return Et(V,H,ms,{flushSync:Be}),!0}return!1}if(!Ae&&qe(ne))return;let ze=j.fetchers.get(V);Ue(V,ID(fe,ze),{flushSync:Be});let $e=new AbortController,yt=Li(e.history,q,$e.signal,fe);if(Ae){let Nt=await bu(be,q,yt.signal);if(Nt.type==="aborted")return;if(Nt.type==="error"){let{error:ms}=Fr(q,Nt);Et(V,H,ms,{flushSync:Be});return}else if(Nt.matches){if(be=Nt.matches,ne=Ol(be,q),qe(ne))return}else{Et(V,H,xn(404,{pathname:q}),{flushSync:Be});return}}F.set(V,$e);let pt=W,ht=(await te("action",yt,[ne],be))[0];if(yt.signal.aborted){F.get(V)===$e&&F.delete(V);return}if(f.v7_fetcherPersist&&se.has(V)){if(Go(ht)||Fn(ht)){Ue(V,to(void 0));return}}else{if(Go(ht))if(F.delete(V),I>pt){Ue(V,to(void 0));return}else return $.add(V),Ue(V,wl(fe)),Q(yt,ht,{fetcherSubmission:fe});if(Fn(ht)){Et(V,H,ht.error);return}}if(Ko(ht))throw xn(400,{type:"defer-action"});let tn=j.navigation.location||j.location,Bt=Li(e.history,tn,$e.signal),ul=a||i,Xs=j.navigation.state!=="idle"?Bo(ul,j.navigation.location,c):j.matches;tt(Xs,"Didn't find any matches after fetcher action");let Di=++W;X.set(V,Di);let Oi=wl(fe,ht.data);j.fetchers.set(V,Oi);let[Ii,$r]=_w(e.history,j,Xs,fe,tn,!1,f.v7_skipActionErrorRevalidation,S,U,J,se,B,$,ul,c,[ne.route.id,ht]);$r.filter(Nt=>Nt.key!==V).forEach(Nt=>{let ms=Nt.key,a0=j.fetchers.get(ms),mP=wl(void 0,a0?a0.data:void 0);j.fetchers.set(ms,mP),F.has(ms)&<(ms),Nt.controller&&F.set(ms,Nt.controller)}),Re({fetchers:new Map(j.fetchers)});let _u=()=>$r.forEach(Nt=>lt(Nt.key));$e.signal.addEventListener("abort",_u);let{loaderResults:Su,fetcherResults:ku}=await ge(j.matches,Xs,Ii,$r,Bt);if($e.signal.aborted)return;$e.signal.removeEventListener("abort",_u),X.delete(V),F.delete(V),$r.forEach(Nt=>F.delete(Nt.key));let Je=Rw([...Su,...ku]);if(Je){if(Je.idx>=Ii.length){let Nt=$r[Je.idx-Ii.length].key;$.add(Nt)}return Q(Bt,Je.result)}let{loaderData:Lt,errors:In}=Ew(j,j.matches,Ii,Su,void 0,$r,ku,oe);if(j.fetchers.has(V)){let Nt=to(ht.data);j.fetchers.set(V,Nt)}nr(Di),j.navigation.state==="loading"&&Di>I?(tt(T,"Expected pending action"),A&&A.abort(),st(j.navigation.location,{matches:Xs,loaderData:Lt,errors:In,fetchers:new Map(j.fetchers)})):(Re({errors:In,loaderData:Nw(j.loaderData,Lt,Xs,In),fetchers:new Map(j.fetchers)}),S=!1)}async function Y(V,H,q,ne,be,Ae,Be,fe){let qe=j.fetchers.get(V);Ue(V,wl(fe,qe?qe.data:void 0),{flushSync:Be});let ze=new AbortController,$e=Li(e.history,q,ze.signal);if(Ae){let ht=await bu(be,q,$e.signal);if(ht.type==="aborted")return;if(ht.type==="error"){let{error:tn}=Fr(q,ht);Et(V,H,tn,{flushSync:Be});return}else if(ht.matches)be=ht.matches,ne=Ol(be,q);else{Et(V,H,xn(404,{pathname:q}),{flushSync:Be});return}}F.set(V,ze);let yt=W,xt=(await te("loader",$e,[ne],be))[0];if(Ko(xt)&&(xt=await $S(xt,$e.signal,!0)||xt),F.get(V)===ze&&F.delete(V),!$e.signal.aborted){if(se.has(V)){Ue(V,to(void 0));return}if(Go(xt))if(I>yt){Ue(V,to(void 0));return}else{$.add(V),await Q($e,xt);return}if(Fn(xt)){Et(V,H,xt.error);return}tt(!Ko(xt),"Unhandled fetcher deferred data"),Ue(V,to(xt.data))}}async function Q(V,H,q){let{submission:ne,fetcherSubmission:be,replace:Ae}=q===void 0?{}:q;H.response.headers.has("X-Remix-Revalidate")&&(S=!0);let Be=H.response.headers.get("Location");tt(Be,"Expected a Location header on the redirect Response"),Be=Cw(Be,new URL(V.url),c);let fe=xc(j.location,Be,{_isRedirect:!0});if(n){let xt=!1;if(H.response.headers.has("X-Remix-Reload-Document"))xt=!0;else if(Qy.test(Be)){const ht=e.history.createURL(Be);xt=ht.origin!==t.location.origin||Za(ht.pathname,c)==null}if(xt){Ae?t.location.replace(Be):t.location.assign(Be);return}}A=null;let qe=Ae===!0?Wt.Replace:Wt.Push,{formMethod:ze,formAction:$e,formEncType:yt}=j.navigation;!ne&&!be&&ze&&$e&&yt&&(ne=Dw(j.navigation));let pt=ne||be;if(pD.has(H.response.status)&&pt&&xr(pt.formMethod))await Z(qe,fe,{submission:At({},pt,{formAction:Be}),preventScrollReset:R});else{let xt=$m(fe,ne);await Z(qe,fe,{overrideNavigation:xt,fetcherSubmission:be,preventScrollReset:R})}}async function te(V,H,q,ne){try{let be=await kD(u,V,H,q,ne,o,s);return await Promise.all(be.map((Ae,Be)=>{if(RD(Ae)){let fe=Ae.result;return{type:wt.redirect,response:ED(fe,H,q[Be].route.id,ne,c,f.v7_relativeSplatPath)}}return jD(Ae)}))}catch(be){return q.map(()=>({type:wt.error,error:be}))}}async function ge(V,H,q,ne,be){let[Ae,...Be]=await Promise.all([q.length?te("loader",be,q,H):[],...ne.map(fe=>{if(fe.matches&&fe.match&&fe.controller){let qe=Li(e.history,fe.path,fe.controller.signal);return te("loader",qe,[fe.match],fe.matches).then(ze=>ze[0])}else return Promise.resolve({type:wt.error,error:xn(404,{pathname:fe.path})})})]);return await Promise.all([Aw(V,q,Ae,Ae.map(()=>be.signal),!1,j.loaderData),Aw(V,ne.map(fe=>fe.match),Be,ne.map(fe=>fe.controller?fe.controller.signal:null),!0)]),{loaderResults:Ae,fetcherResults:Be}}function Ke(){S=!0,U.push(...qs()),B.forEach((V,H)=>{F.has(H)&&(J.push(H),lt(H))})}function Ue(V,H,q){q===void 0&&(q={}),j.fetchers.set(V,H),Re({fetchers:new Map(j.fetchers)},{flushSync:(q&&q.flushSync)===!0})}function Et(V,H,q,ne){ne===void 0&&(ne={});let be=oa(j.matches,H);Yt(V),Re({errors:{[be.route.id]:q},fetchers:new Map(j.fetchers)},{flushSync:(ne&&ne.flushSync)===!0})}function tr(V){return f.v7_fetcherPersist&&(he.set(V,(he.get(V)||0)+1),se.has(V)&&se.delete(V)),j.fetchers.get(V)||gD}function Yt(V){let H=j.fetchers.get(V);F.has(V)&&!(H&&H.state==="loading"&&X.has(V))&<(V),B.delete(V),X.delete(V),$.delete(V),se.delete(V),j.fetchers.delete(V)}function ds(V){if(f.v7_fetcherPersist){let H=(he.get(V)||0)-1;H<=0?(he.delete(V),se.add(V)):he.set(V,H)}else Yt(V);Re({fetchers:new Map(j.fetchers)})}function lt(V){let H=F.get(V);tt(H,"Expected fetch controller: "+V),H.abort(),F.delete(V)}function fs(V){for(let H of V){let q=tr(H),ne=to(q.data);j.fetchers.set(H,ne)}}function hs(){let V=[],H=!1;for(let q of $){let ne=j.fetchers.get(q);tt(ne,"Expected fetcher: "+q),ne.state==="loading"&&($.delete(q),V.push(q),H=!0)}return fs(V),H}function nr(V){let H=[];for(let[q,ne]of X)if(ne0}function vu(V,H){let q=j.blockers.get(V)||xl;return Oe.get(V)!==H&&Oe.set(V,H),q}function xu(V){j.blockers.delete(V),Oe.delete(V)}function Ri(V,H){let q=j.blockers.get(V)||xl;tt(q.state==="unblocked"&&H.state==="blocked"||q.state==="blocked"&&H.state==="blocked"||q.state==="blocked"&&H.state==="proceeding"||q.state==="blocked"&&H.state==="unblocked"||q.state==="proceeding"&&H.state==="unblocked","Invalid blocker state transition: "+q.state+" -> "+H.state);let ne=new Map(j.blockers);ne.set(V,H),Re({blockers:ne})}function wu(V){let{currentLocation:H,nextLocation:q,historyAction:ne}=V;if(Oe.size===0)return;Oe.size>1&&ci(!1,"A router only supports one blocker at a time");let be=Array.from(Oe.entries()),[Ae,Be]=be[be.length-1],fe=j.blockers.get(Ae);if(!(fe&&fe.state==="proceeding")&&Be({currentLocation:H,nextLocation:q,historyAction:ne}))return Ae}function Ai(V){let H=xn(404,{pathname:V}),q=a||i,{matches:ne,route:be}=Pw(q);return qs(),{notFoundMatches:ne,route:be,error:H}}function Fr(V,H){return{boundaryId:oa(H.partialMatches).route.id,error:xn(400,{type:"route-discovery",pathname:V,message:H.error!=null&&"message"in H.error?H.error:String(H.error)})}}function qs(V){let H=[];return oe.forEach((q,ne)=>{(!V||V(ne))&&(q.cancel(),H.push(ne),oe.delete(ne))}),H}function uP(V,H,q){if(x=V,w=H,p=q||null,!g&&j.navigation===Fm){g=!0;let ne=i0(j.location,j.matches);ne!=null&&Re({restoreScrollPosition:ne})}return()=>{x=null,w=null,p=null}}function o0(V,H){return p&&p(V,H.map(ne=>KA(ne,j.loaderData)))||V.key}function dP(V,H){if(x&&w){let q=o0(V,H);x[q]=w()}}function i0(V,H){if(x){let q=o0(V,H),ne=x[q];if(typeof ne=="number")return ne}return null}function dm(V,H,q){if(d)if(V){let ne=V[V.length-1].route;if(ne.path&&(ne.path==="*"||ne.path.endsWith("/*")))return{active:!0,matches:gd(H,q,c,!0)}}else return{active:!0,matches:gd(H,q,c,!0)||[]};return{active:!1,matches:null}}async function bu(V,H,q){let ne=V,be=ne.length>0?ne[ne.length-1].route:null;for(;;){let Ae=a==null,Be=a||i;try{await _D(d,H,ne,Be,o,s,me,q)}catch($e){return{type:"error",error:$e,partialMatches:ne}}finally{Ae&&(i=[...i])}if(q.aborted)return{type:"aborted"};let fe=Bo(Be,H,c),qe=!1;if(fe){let $e=fe[fe.length-1].route;if($e.index)return{type:"success",matches:fe};if($e.path&&$e.path.length>0)if($e.path==="*")qe=!0;else return{type:"success",matches:fe}}let ze=gd(Be,H,c,!0);if(!ze||ne.map($e=>$e.route.id).join("-")===ze.map($e=>$e.route.id).join("-"))return{type:"success",matches:qe?fe:null};if(ne=ze,be=ne[ne.length-1].route,be.path==="*")return{type:"success",matches:ne}}}function fP(V){o={},a=wc(V,s,void 0,o)}function hP(V,H){let q=a==null;LS(V,H,a||i,o,s),q&&(i=[...i],Re({}))}return C={get basename(){return c},get future(){return f},get state(){return j},get routes(){return i},get window(){return t},initialize:Te,subscribe:Ie,enableScrollRestoration:uP,navigate:E,fetch:K,revalidate:ee,createHref:V=>e.history.createHref(V),encodeLocation:V=>e.history.encodeLocation(V),getFetcher:tr,deleteFetcher:ds,dispose:Fe,getBlocker:vu,deleteBlocker:xu,patchRoutes:hP,_internalFetchControllers:F,_internalActiveDeferreds:oe,_internalSetRoutes:fP},C}function xD(e){return e!=null&&("formData"in e&&e.formData!=null||"body"in e&&e.body!==void 0)}function ug(e,t,n,r,s,o,i,a){let c,u;if(i){c=[];for(let f of t)if(c.push(f),f.route.id===i){u=f;break}}else c=t,u=t[t.length-1];let d=oh(s||".",sh(c,o),Za(e.pathname,n)||e.pathname,a==="path");return s==null&&(d.search=e.search,d.hash=e.hash),(s==null||s===""||s===".")&&u&&u.route.index&&!Jy(d.search)&&(d.search=d.search?d.search.replace(/^\?/,"?index&"):"?index"),r&&n!=="/"&&(d.pathname=d.pathname==="/"?n:Ns([n,d.pathname])),ui(d)}function bw(e,t,n,r){if(!r||!xD(r))return{path:n};if(r.formMethod&&!DD(r.formMethod))return{path:n,error:xn(405,{method:r.formMethod})};let s=()=>({path:n,error:xn(400,{type:"invalid-body"})}),o=r.formMethod||"get",i=e?o.toUpperCase():o.toLowerCase(),a=zS(n);if(r.body!==void 0){if(r.formEncType==="text/plain"){if(!xr(i))return s();let h=typeof r.body=="string"?r.body:r.body instanceof FormData||r.body instanceof URLSearchParams?Array.from(r.body.entries()).reduce((m,x)=>{let[p,w]=x;return""+m+p+"="+w+` +`},""):String(r.body);return{path:n,submission:{formMethod:i,formAction:a,formEncType:r.formEncType,formData:void 0,json:void 0,text:h}}}else if(r.formEncType==="application/json"){if(!xr(i))return s();try{let h=typeof r.body=="string"?JSON.parse(r.body):r.body;return{path:n,submission:{formMethod:i,formAction:a,formEncType:r.formEncType,formData:void 0,json:h,text:void 0}}}catch{return s()}}}tt(typeof FormData=="function","FormData is not available in this environment");let c,u;if(r.formData)c=dg(r.formData),u=r.formData;else if(r.body instanceof FormData)c=dg(r.body),u=r.body;else if(r.body instanceof URLSearchParams)c=r.body,u=jw(c);else if(r.body==null)c=new URLSearchParams,u=new FormData;else try{c=new URLSearchParams(r.body),u=jw(c)}catch{return s()}let d={formMethod:i,formAction:a,formEncType:r&&r.formEncType||"application/x-www-form-urlencoded",formData:u,json:void 0,text:void 0};if(xr(d.formMethod))return{path:n,submission:d};let f=Bs(n);return t&&f.search&&Jy(f.search)&&c.append("index",""),f.search="?"+c,{path:ui(f),submission:d}}function wD(e,t){let n=e;if(t){let r=e.findIndex(s=>s.route.id===t);r>=0&&(n=e.slice(0,r))}return n}function _w(e,t,n,r,s,o,i,a,c,u,d,f,h,m,x,p){let w=p?Fn(p[1])?p[1].error:p[1].data:void 0,g=e.createURL(t.location),v=e.createURL(s),b=p&&Fn(p[1])?p[0]:void 0,_=b?wD(n,b):n,C=p?p[1].statusCode:void 0,j=i&&C&&C>=400,T=_.filter((A,O)=>{let{route:G}=A;if(G.lazy)return!0;if(G.loader==null)return!1;if(o)return typeof G.loader!="function"||G.loader.hydrate?!0:t.loaderData[G.id]===void 0&&(!t.errors||t.errors[G.id]===void 0);if(bD(t.loaderData,t.matches[O],A)||c.some(S=>S===A.route.id))return!0;let N=t.matches[O],z=A;return Sw(A,At({currentUrl:g,currentParams:N.params,nextUrl:v,nextParams:z.params},r,{actionResult:w,actionStatus:C,defaultShouldRevalidate:j?!1:a||g.pathname+g.search===v.pathname+v.search||g.search!==v.search||MS(N,z)}))}),R=[];return f.forEach((A,O)=>{if(o||!n.some(U=>U.route.id===A.routeId)||d.has(O))return;let G=Bo(m,A.path,x);if(!G){R.push({key:O,routeId:A.routeId,path:A.path,matches:null,match:null,controller:null});return}let N=t.fetchers.get(O),z=Ol(G,A.path),S=!1;h.has(O)?S=!1:u.includes(O)?S=!0:N&&N.state!=="idle"&&N.data===void 0?S=a:S=Sw(z,At({currentUrl:g,currentParams:t.matches[t.matches.length-1].params,nextUrl:v,nextParams:n[n.length-1].params},r,{actionResult:w,actionStatus:C,defaultShouldRevalidate:j?!1:a})),S&&R.push({key:O,routeId:A.routeId,path:A.path,matches:G,match:z,controller:new AbortController})}),[T,R]}function bD(e,t,n){let r=!t||n.route.id!==t.route.id,s=e[n.route.id]===void 0;return r||s}function MS(e,t){let n=e.route.path;return e.pathname!==t.pathname||n!=null&&n.endsWith("*")&&e.params["*"]!==t.params["*"]}function Sw(e,t){if(e.route.shouldRevalidate){let n=e.route.shouldRevalidate(t);if(typeof n=="boolean")return n}return t.defaultShouldRevalidate}async function _D(e,t,n,r,s,o,i,a){let c=[t,...n.map(u=>u.route.id)].join("-");try{let u=i.get(c);u||(u=e({path:t,matches:n,patch:(d,f)=>{a.aborted||LS(d,f,r,s,o)}}),i.set(c,u)),u&&PD(u)&&await u}finally{i.delete(c)}}function LS(e,t,n,r,s){if(e){var o;let i=r[e];tt(i,"No route found to patch children into: routeId = "+e);let a=wc(t,s,[e,"patch",String(((o=i.children)==null?void 0:o.length)||"0")],r);i.children?i.children.push(...a):i.children=a}else{let i=wc(t,s,["patch",String(n.length||"0")],r);n.push(...i)}}async function kw(e,t,n){if(!e.lazy)return;let r=await e.lazy();if(!e.lazy)return;let s=n[e.id];tt(s,"No route found in manifest");let o={};for(let i in r){let c=s[i]!==void 0&&i!=="hasErrorBoundary";ci(!c,'Route "'+s.id+'" has a static property "'+i+'" defined but its lazy function is also returning a value for this property. '+('The lazy route property "'+i+'" will be ignored.')),!c&&!HA.has(i)&&(o[i]=r[i])}Object.assign(s,o),Object.assign(s,At({},t(s),{lazy:void 0}))}function SD(e){return Promise.all(e.matches.map(t=>t.resolve()))}async function kD(e,t,n,r,s,o,i,a){let c=r.reduce((f,h)=>f.add(h.route.id),new Set),u=new Set,d=await e({matches:s.map(f=>{let h=c.has(f.route.id);return At({},f,{shouldLoad:h,resolve:x=>(u.add(f.route.id),h?CD(t,n,f,o,i,x,a):Promise.resolve({type:wt.data,result:void 0}))})}),request:n,params:s[0].params,context:a});return s.forEach(f=>tt(u.has(f.route.id),'`match.resolve()` was not called for route id "'+f.route.id+'". You must call `match.resolve()` on every match passed to `dataStrategy` to ensure all routes are properly loaded.')),d.filter((f,h)=>c.has(s[h].route.id))}async function CD(e,t,n,r,s,o,i){let a,c,u=d=>{let f,h=new Promise((p,w)=>f=w);c=()=>f(),t.signal.addEventListener("abort",c);let m=p=>typeof d!="function"?Promise.reject(new Error("You cannot call the handler for a route which defines a boolean "+('"'+e+'" [routeId: '+n.route.id+"]"))):d({request:t,params:n.params,context:i},...p!==void 0?[p]:[]),x;return o?x=o(p=>m(p)):x=(async()=>{try{return{type:"data",result:await m()}}catch(p){return{type:"error",result:p}}})(),Promise.race([x,h])};try{let d=n.route[e];if(n.route.lazy)if(d){let f,[h]=await Promise.all([u(d).catch(m=>{f=m}),kw(n.route,s,r)]);if(f!==void 0)throw f;a=h}else if(await kw(n.route,s,r),d=n.route[e],d)a=await u(d);else if(e==="action"){let f=new URL(t.url),h=f.pathname+f.search;throw xn(405,{method:t.method,pathname:h,routeId:n.route.id})}else return{type:wt.data,result:void 0};else if(d)a=await u(d);else{let f=new URL(t.url),h=f.pathname+f.search;throw xn(404,{pathname:h})}tt(a.result!==void 0,"You defined "+(e==="action"?"an action":"a loader")+" for route "+('"'+n.route.id+"\" but didn't return anything from your `"+e+"` ")+"function. Please return a value or `null`.")}catch(d){return{type:wt.error,result:d}}finally{c&&t.signal.removeEventListener("abort",c)}return a}async function jD(e){let{result:t,type:n,status:r}=e;if(FS(t)){let i;try{let a=t.headers.get("Content-Type");a&&/\bapplication\/json\b/.test(a)?t.body==null?i=null:i=await t.json():i=await t.text()}catch(a){return{type:wt.error,error:a}}return n===wt.error?{type:wt.error,error:new Xy(t.status,t.statusText,i),statusCode:t.status,headers:t.headers}:{type:wt.data,data:i,statusCode:t.status,headers:t.headers}}if(n===wt.error)return{type:wt.error,error:t,statusCode:ih(t)?t.status:r};if(AD(t)){var s,o;return{type:wt.deferred,deferredData:t,statusCode:(s=t.init)==null?void 0:s.status,headers:((o=t.init)==null?void 0:o.headers)&&new Headers(t.init.headers)}}return{type:wt.data,data:t,statusCode:r}}function ED(e,t,n,r,s,o){let i=e.headers.get("Location");if(tt(i,"Redirects returned/thrown from loaders/actions must have a Location header"),!Qy.test(i)){let a=r.slice(0,r.findIndex(c=>c.route.id===n)+1);i=ug(new URL(t.url),a,s,!0,i,o),e.headers.set("Location",i)}return e}function Cw(e,t,n){if(Qy.test(e)){let r=e,s=r.startsWith("//")?new URL(t.protocol+r):new URL(r),o=Za(s.pathname,n)!=null;if(s.origin===t.origin&&o)return s.pathname+s.search+s.hash}return e}function Li(e,t,n,r){let s=e.createURL(zS(t)).toString(),o={signal:n};if(r&&xr(r.formMethod)){let{formMethod:i,formEncType:a}=r;o.method=i.toUpperCase(),a==="application/json"?(o.headers=new Headers({"Content-Type":a}),o.body=JSON.stringify(r.json)):a==="text/plain"?o.body=r.text:a==="application/x-www-form-urlencoded"&&r.formData?o.body=dg(r.formData):o.body=r.formData}return new Request(s,o)}function dg(e){let t=new URLSearchParams;for(let[n,r]of e.entries())t.append(n,typeof r=="string"?r:r.name);return t}function jw(e){let t=new FormData;for(let[n,r]of e.entries())t.append(n,r);return t}function ND(e,t,n,r,s,o){let i={},a=null,c,u=!1,d={},f=r&&Fn(r[1])?r[1].error:void 0;return n.forEach((h,m)=>{let x=t[m].route.id;if(tt(!Go(h),"Cannot handle redirect results in processLoaderData"),Fn(h)){let p=h.error;f!==void 0&&(p=f,f=void 0),a=a||{};{let w=oa(e,x);a[w.route.id]==null&&(a[w.route.id]=p)}i[x]=void 0,u||(u=!0,c=ih(h.error)?h.error.status:500),h.headers&&(d[x]=h.headers)}else Ko(h)?(s.set(x,h.deferredData),i[x]=h.deferredData.data,h.statusCode!=null&&h.statusCode!==200&&!u&&(c=h.statusCode),h.headers&&(d[x]=h.headers)):(i[x]=h.data,h.statusCode&&h.statusCode!==200&&!u&&(c=h.statusCode),h.headers&&(d[x]=h.headers))}),f!==void 0&&r&&(a={[r[0]]:f},i[r[0]]=void 0),{loaderData:i,errors:a,statusCode:c||200,loaderHeaders:d}}function Ew(e,t,n,r,s,o,i,a){let{loaderData:c,errors:u}=ND(t,n,r,s,a);for(let d=0;dr.route.id===t)+1):[...e]).reverse().find(r=>r.route.hasErrorBoundary===!0)||e[0]}function Pw(e){let t=e.length===1?e[0]:e.find(n=>n.index||!n.path||n.path==="/")||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function xn(e,t){let{pathname:n,routeId:r,method:s,type:o,message:i}=t===void 0?{}:t,a="Unknown Server Error",c="Unknown @remix-run/router error";return e===400?(a="Bad Request",o==="route-discovery"?c='Unable to match URL "'+n+'" - the `unstable_patchRoutesOnMiss()` '+(`function threw the following error: +`+i):s&&n&&r?c="You made a "+s+' request to "'+n+'" but '+('did not provide a `loader` for route "'+r+'", ')+"so there is no way to handle the request.":o==="defer-action"?c="defer() is not supported in actions":o==="invalid-body"&&(c="Unable to encode submission body")):e===403?(a="Forbidden",c='Route "'+r+'" does not match URL "'+n+'"'):e===404?(a="Not Found",c='No route matches URL "'+n+'"'):e===405&&(a="Method Not Allowed",s&&n&&r?c="You made a "+s.toUpperCase()+' request to "'+n+'" but '+('did not provide an `action` for route "'+r+'", ')+"so there is no way to handle the request.":s&&(c='Invalid request method "'+s.toUpperCase()+'"')),new Xy(e||500,a,new Error(c),!0)}function Rw(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(Go(n))return{result:n,idx:t}}}function zS(e){let t=typeof e=="string"?Bs(e):e;return ui(At({},t,{hash:""}))}function TD(e,t){return e.pathname!==t.pathname||e.search!==t.search?!1:e.hash===""?t.hash!=="":e.hash===t.hash?!0:t.hash!==""}function PD(e){return typeof e=="object"&&e!=null&&"then"in e}function RD(e){return FS(e.result)&&mD.has(e.result.status)}function Ko(e){return e.type===wt.deferred}function Fn(e){return e.type===wt.error}function Go(e){return(e&&e.type)===wt.redirect}function AD(e){let t=e;return t&&typeof t=="object"&&typeof t.data=="object"&&typeof t.subscribe=="function"&&typeof t.cancel=="function"&&typeof t.resolveData=="function"}function FS(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.headers=="object"&&typeof e.body<"u"}function DD(e){return hD.has(e.toLowerCase())}function xr(e){return dD.has(e.toLowerCase())}async function Aw(e,t,n,r,s,o){for(let i=0;if.route.id===c.route.id),d=u!=null&&!MS(u,c)&&(o&&o[c.route.id])!==void 0;if(Ko(a)&&(s||d)){let f=r[i];tt(f,"Expected an AbortSignal for revalidating fetcher deferred result"),await $S(a,f,s).then(h=>{h&&(n[i]=h||n[i])})}}}async function $S(e,t,n){if(n===void 0&&(n=!1),!await e.deferredData.resolveData(t)){if(n)try{return{type:wt.data,data:e.deferredData.unwrappedData}}catch(s){return{type:wt.error,error:s}}return{type:wt.data,data:e.deferredData.data}}}function Jy(e){return new URLSearchParams(e).getAll("index").some(t=>t==="")}function Ol(e,t){let n=typeof t=="string"?Bs(t).search:t.search;if(e[e.length-1].route.index&&Jy(n||""))return e[e.length-1];let r=DS(e);return r[r.length-1]}function Dw(e){let{formMethod:t,formAction:n,formEncType:r,text:s,formData:o,json:i}=e;if(!(!t||!n||!r)){if(s!=null)return{formMethod:t,formAction:n,formEncType:r,formData:void 0,json:void 0,text:s};if(o!=null)return{formMethod:t,formAction:n,formEncType:r,formData:o,json:void 0,text:void 0};if(i!==void 0)return{formMethod:t,formAction:n,formEncType:r,formData:void 0,json:i,text:void 0}}}function $m(e,t){return t?{state:"loading",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}:{state:"loading",location:e,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}function OD(e,t){return{state:"submitting",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}}function wl(e,t){return e?{state:"loading",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t}:{state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:t}}function ID(e,t){return{state:"submitting",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t?t.data:void 0}}function to(e){return{state:"idle",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:e}}function MD(e,t){try{let n=e.sessionStorage.getItem(IS);if(n){let r=JSON.parse(n);for(let[s,o]of Object.entries(r||{}))o&&Array.isArray(o)&&t.set(s,new Set(o||[]))}}catch{}}function LD(e,t){if(t.size>0){let n={};for(let[r,s]of t)n[r]=[...s];try{e.sessionStorage.setItem(IS,JSON.stringify(n))}catch(r){ci(!1,"Failed to save applied view transitions in sessionStorage ("+r+").")}}}/** + * React Router v6.25.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function Qd(){return Qd=Object.assign?Object.assign.bind():function(e){for(var t=1;t{a.current=!0}),y.useCallback(function(u,d){if(d===void 0&&(d={}),!a.current)return;if(typeof u=="number"){r.go(u);return}let f=oh(u,JSON.parse(i),o,d.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:Ns([t,f.pathname])),(d.replace?r.replace:r.push)(f,d.state,d)},[t,r,i,o,e])}const $D=y.createContext(null);function UD(e){let t=y.useContext(Ws).outlet;return t&&y.createElement($D.Provider,{value:e},t)}function WS(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=y.useContext(Mo),{matches:s}=y.useContext(Ws),{pathname:o}=Ir(),i=JSON.stringify(sh(s,r.v7_relativeSplatPath));return y.useMemo(()=>oh(e,JSON.parse(i),o,n==="path"),[e,i,o,n])}function VD(e,t,n,r){qa()||tt(!1);let{navigator:s}=y.useContext(Mo),{matches:o}=y.useContext(Ws),i=o[o.length-1],a=i?i.params:{};i&&i.pathname;let c=i?i.pathnameBase:"/";i&&i.route;let u=Ir(),d;d=u;let f=d.pathname||"/",h=f;if(c!=="/"){let p=c.replace(/^\//,"").split("/");h="/"+f.replace(/^\//,"").split("/").slice(p.length).join("/")}let m=Bo(e,{pathname:h});return KD(m&&m.map(p=>Object.assign({},p,{params:Object.assign({},a,p.params),pathname:Ns([c,s.encodeLocation?s.encodeLocation(p.pathname).pathname:p.pathname]),pathnameBase:p.pathnameBase==="/"?c:Ns([c,s.encodeLocation?s.encodeLocation(p.pathnameBase).pathname:p.pathnameBase])})),o,n,r)}function BD(){let e=XD(),t=ih(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,s={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return y.createElement(y.Fragment,null,y.createElement("h2",null,"Unexpected Application Error!"),y.createElement("h3",{style:{fontStyle:"italic"}},t),n?y.createElement("pre",{style:s},n):null,null)}const WD=y.createElement(BD,null);class HD extends y.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,n){return n.location!==t.location||n.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error("React Router caught the following error during render",t,n)}render(){return this.state.error!==void 0?y.createElement(Ws.Provider,{value:this.props.routeContext},y.createElement(VS.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function YD(e){let{routeContext:t,match:n,children:r}=e,s=y.useContext(ah);return s&&s.static&&s.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=n.route.id),y.createElement(Ws.Provider,{value:t},r)}function KD(e,t,n,r){var s;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var o;if((o=n)!=null&&o.errors)e=n.matches;else return null}let i=e,a=(s=n)==null?void 0:s.errors;if(a!=null){let d=i.findIndex(f=>f.route.id&&(a==null?void 0:a[f.route.id])!==void 0);d>=0||tt(!1),i=i.slice(0,Math.min(i.length,d+1))}let c=!1,u=-1;if(n&&r&&r.v7_partialHydration)for(let d=0;d=0?i=i.slice(0,u+1):i=[i[0]];break}}}return i.reduceRight((d,f,h)=>{let m,x=!1,p=null,w=null;n&&(m=a&&f.route.id?a[f.route.id]:void 0,p=f.route.errorElement||WD,c&&(u<0&&h===0?(JD("route-fallback"),x=!0,w=null):u===h&&(x=!0,w=f.route.hydrateFallbackElement||null)));let g=t.concat(i.slice(0,h+1)),v=()=>{let b;return m?b=p:x?b=w:f.route.Component?b=y.createElement(f.route.Component,null):f.route.element?b=f.route.element:b=d,y.createElement(YD,{match:f,routeContext:{outlet:d,matches:g,isDataRoute:n!=null},children:b})};return n&&(f.route.ErrorBoundary||f.route.errorElement||h===0)?y.createElement(HD,{location:n.location,revalidation:n.revalidation,component:p,error:m,children:v(),routeContext:{outlet:null,matches:g,isDataRoute:!0}}):v()},null)}var HS=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(HS||{}),Jd=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(Jd||{});function GD(e){let t=y.useContext(ah);return t||tt(!1),t}function ZD(e){let t=y.useContext(US);return t||tt(!1),t}function qD(e){let t=y.useContext(Ws);return t||tt(!1),t}function YS(e){let t=qD(),n=t.matches[t.matches.length-1];return n.route.id||tt(!1),n.route.id}function XD(){var e;let t=y.useContext(VS),n=ZD(Jd.UseRouteError),r=YS(Jd.UseRouteError);return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function QD(){let{router:e}=GD(HS.UseNavigateStable),t=YS(Jd.UseNavigateStable),n=y.useRef(!1);return BS(()=>{n.current=!0}),y.useCallback(function(s,o){o===void 0&&(o={}),n.current&&(typeof s=="number"?e.navigate(s):e.navigate(s,Qd({fromRouteId:t},o)))},[e,t])}const Ow={};function JD(e,t,n){Ow[e]||(Ow[e]=!0)}function KS(e){let{to:t,replace:n,state:r,relative:s}=e;qa()||tt(!1);let{future:o,static:i}=y.useContext(Mo),{matches:a}=y.useContext(Ws),{pathname:c}=Ir(),u=Jn(),d=oh(t,sh(a,o.v7_relativeSplatPath),c,s==="path"),f=JSON.stringify(d);return y.useEffect(()=>u(JSON.parse(f),{replace:n,state:r,relative:s}),[u,f,s,n,r]),null}function tv(e){return UD(e.context)}function eO(e){let{basename:t="/",children:n=null,location:r,navigationType:s=Wt.Pop,navigator:o,static:i=!1,future:a}=e;qa()&&tt(!1);let c=t.replace(/^\/*/,"/"),u=y.useMemo(()=>({basename:c,navigator:o,static:i,future:Qd({v7_relativeSplatPath:!1},a)}),[c,a,o,i]);typeof r=="string"&&(r=Bs(r));let{pathname:d="/",search:f="",hash:h="",state:m=null,key:x="default"}=r,p=y.useMemo(()=>{let w=Za(d,c);return w==null?null:{location:{pathname:w,search:f,hash:h,state:m,key:x},navigationType:s}},[c,d,f,h,m,x,s]);return p==null?null:y.createElement(Mo.Provider,{value:u},y.createElement(ev.Provider,{children:n,value:p}))}new Promise(()=>{});function tO(e){let t={hasErrorBoundary:e.ErrorBoundary!=null||e.errorElement!=null};return e.Component&&Object.assign(t,{element:y.createElement(e.Component),Component:void 0}),e.HydrateFallback&&Object.assign(t,{hydrateFallbackElement:y.createElement(e.HydrateFallback),HydrateFallback:void 0}),e.ErrorBoundary&&Object.assign(t,{errorElement:y.createElement(e.ErrorBoundary),ErrorBoundary:void 0}),t}/** + * React Router DOM v6.25.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function bc(){return bc=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&(n[s]=e[s]);return n}function rO(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function sO(e,t){return e.button===0&&(!t||t==="_self")&&!rO(e)}function fg(e){return e===void 0&&(e=""),new URLSearchParams(typeof e=="string"||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(s=>[n,s]):[[n,r]])},[]))}function oO(e,t){let n=fg(e);return t&&t.forEach((r,s)=>{n.has(s)||t.getAll(s).forEach(o=>{n.append(s,o)})}),n}const iO=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","unstable_viewTransition"],aO="6";try{window.__reactRouterVersion=aO}catch{}function lO(e,t){return vD({basename:void 0,future:bc({},void 0,{v7_prependBasename:!0}),history:VA({window:void 0}),hydrationData:cO(),routes:e,mapRouteProperties:tO,unstable_dataStrategy:void 0,unstable_patchRoutesOnMiss:void 0,window:void 0}).initialize()}function cO(){var e;let t=(e=window)==null?void 0:e.__staticRouterHydrationData;return t&&t.errors&&(t=bc({},t,{errors:uO(t.errors)})),t}function uO(e){if(!e)return null;let t=Object.entries(e),n={};for(let[r,s]of t)if(s&&s.__type==="RouteErrorResponse")n[r]=new Xy(s.status,s.statusText,s.data,s.internal===!0);else if(s&&s.__type==="Error"){if(s.__subType){let o=window[s.__subType];if(typeof o=="function")try{let i=new o(s.message);i.stack="",n[r]=i}catch{}}if(n[r]==null){let o=new Error(s.message);o.stack="",n[r]=o}}else n[r]=s;return n}const dO=y.createContext({isTransitioning:!1}),fO=y.createContext(new Map),hO="startTransition",Iw=E1[hO],mO="flushSync",Mw=UA[mO];function pO(e){Iw?Iw(e):e()}function bl(e){Mw?Mw(e):e()}class gO{constructor(){this.status="pending",this.promise=new Promise((t,n)=>{this.resolve=r=>{this.status==="pending"&&(this.status="resolved",t(r))},this.reject=r=>{this.status==="pending"&&(this.status="rejected",n(r))}})}}function yO(e){let{fallbackElement:t,router:n,future:r}=e,[s,o]=y.useState(n.state),[i,a]=y.useState(),[c,u]=y.useState({isTransitioning:!1}),[d,f]=y.useState(),[h,m]=y.useState(),[x,p]=y.useState(),w=y.useRef(new Map),{v7_startTransition:g}=r||{},v=y.useCallback(R=>{g?pO(R):R()},[g]),b=y.useCallback((R,A)=>{let{deletedFetchers:O,unstable_flushSync:G,unstable_viewTransitionOpts:N}=A;O.forEach(S=>w.current.delete(S)),R.fetchers.forEach((S,U)=>{S.data!==void 0&&w.current.set(U,S.data)});let z=n.window==null||n.window.document==null||typeof n.window.document.startViewTransition!="function";if(!N||z){G?bl(()=>o(R)):v(()=>o(R));return}if(G){bl(()=>{h&&(d&&d.resolve(),h.skipTransition()),u({isTransitioning:!0,flushSync:!0,currentLocation:N.currentLocation,nextLocation:N.nextLocation})});let S=n.window.document.startViewTransition(()=>{bl(()=>o(R))});S.finished.finally(()=>{bl(()=>{f(void 0),m(void 0),a(void 0),u({isTransitioning:!1})})}),bl(()=>m(S));return}h?(d&&d.resolve(),h.skipTransition(),p({state:R,currentLocation:N.currentLocation,nextLocation:N.nextLocation})):(a(R),u({isTransitioning:!0,flushSync:!1,currentLocation:N.currentLocation,nextLocation:N.nextLocation}))},[n.window,h,d,w,v]);y.useLayoutEffect(()=>n.subscribe(b),[n,b]),y.useEffect(()=>{c.isTransitioning&&!c.flushSync&&f(new gO)},[c]),y.useEffect(()=>{if(d&&i&&n.window){let R=i,A=d.promise,O=n.window.document.startViewTransition(async()=>{v(()=>o(R)),await A});O.finished.finally(()=>{f(void 0),m(void 0),a(void 0),u({isTransitioning:!1})}),m(O)}},[v,i,d,n.window]),y.useEffect(()=>{d&&i&&s.location.key===i.location.key&&d.resolve()},[d,h,s.location,i]),y.useEffect(()=>{!c.isTransitioning&&x&&(a(x.state),u({isTransitioning:!0,flushSync:!1,currentLocation:x.currentLocation,nextLocation:x.nextLocation}),p(void 0))},[c.isTransitioning,x]),y.useEffect(()=>{},[]);let _=y.useMemo(()=>({createHref:n.createHref,encodeLocation:n.encodeLocation,go:R=>n.navigate(R),push:(R,A,O)=>n.navigate(R,{state:A,preventScrollReset:O==null?void 0:O.preventScrollReset}),replace:(R,A,O)=>n.navigate(R,{replace:!0,state:A,preventScrollReset:O==null?void 0:O.preventScrollReset})}),[n]),C=n.basename||"/",j=y.useMemo(()=>({router:n,navigator:_,static:!1,basename:C}),[n,_,C]),T=y.useMemo(()=>({v7_relativeSplatPath:n.future.v7_relativeSplatPath}),[n.future.v7_relativeSplatPath]);return y.createElement(y.Fragment,null,y.createElement(ah.Provider,{value:j},y.createElement(US.Provider,{value:s},y.createElement(fO.Provider,{value:w.current},y.createElement(dO.Provider,{value:c},y.createElement(eO,{basename:C,location:s.location,navigationType:s.historyAction,navigator:_,future:T},s.initialized||n.future.v7_partialHydration?y.createElement(vO,{routes:n.routes,future:n.future,state:s}):t))))),null)}const vO=y.memo(xO);function xO(e){let{routes:t,future:n,state:r}=e;return VD(t,void 0,r,n)}const wO=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",bO=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,wn=y.forwardRef(function(t,n){let{onClick:r,relative:s,reloadDocument:o,replace:i,state:a,target:c,to:u,preventScrollReset:d,unstable_viewTransition:f}=t,h=nO(t,iO),{basename:m}=y.useContext(Mo),x,p=!1;if(typeof u=="string"&&bO.test(u)&&(x=u,wO))try{let b=new URL(window.location.href),_=u.startsWith("//")?new URL(b.protocol+u):new URL(u),C=Za(_.pathname,m);_.origin===b.origin&&C!=null?u=C+_.search+_.hash:p=!0}catch{}let w=zD(u,{relative:s}),g=_O(u,{replace:i,state:a,target:c,preventScrollReset:d,relative:s,unstable_viewTransition:f});function v(b){r&&r(b),b.defaultPrevented||g(b)}return y.createElement("a",bc({},h,{href:x||w,onClick:p||o?r:v,ref:n,target:c}))});var Lw;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(Lw||(Lw={}));var zw;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(zw||(zw={}));function _O(e,t){let{target:n,replace:r,state:s,preventScrollReset:o,relative:i,unstable_viewTransition:a}=t===void 0?{}:t,c=Jn(),u=Ir(),d=WS(e,{relative:i});return y.useCallback(f=>{if(sO(f,n)){f.preventDefault();let h=r!==void 0?r:ui(u)===ui(d);c(e,{replace:h,state:s,preventScrollReset:o,relative:i,unstable_viewTransition:a})}},[u,c,d,r,s,n,e,o,i,a])}function SO(e){let t=y.useRef(fg(e)),n=y.useRef(!1),r=Ir(),s=y.useMemo(()=>oO(r.search,n.current?null:t.current),[r.search]),o=Jn(),i=y.useCallback((a,c)=>{const u=fg(typeof a=="function"?a(s):a);n.current=!0,o("?"+u,c)},[o,s]);return[s,i]}var kO={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0};const CO=Uf(kO);var jO=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function Fw(e){var t={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},n=e.match(/<\/?([^\s]+?)[/\s>]/);if(n&&(t.name=n[1],(CO[n[1]]||e.charAt(e.length-2)==="/")&&(t.voidElement=!0),t.name.startsWith("!--"))){var r=e.indexOf("-->");return{type:"comment",comment:r!==-1?e.slice(4,r):""}}for(var s=new RegExp(jO),o=null;(o=s.exec(e))!==null;)if(o[0].trim())if(o[1]){var i=o[1].trim(),a=[i,""];i.indexOf("=")>-1&&(a=i.split("=")),t.attrs[a[0]]=a[1],s.lastIndex--}else o[2]&&(t.attrs[o[2]]=o[3].trim().substring(1,o[3].length-1));return t}var EO=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,NO=/^\s*$/,TO=Object.create(null);function GS(e,t){switch(t.type){case"text":return e+t.content;case"tag":return e+="<"+t.name+(t.attrs?function(n){var r=[];for(var s in n)r.push(s+'="'+n[s]+'"');return r.length?" "+r.join(" "):""}(t.attrs):"")+(t.voidElement?"/>":">"),t.voidElement?e:e+t.children.reduce(GS,"")+"";case"comment":return e+""}}var PO={parse:function(e,t){t||(t={}),t.components||(t.components=TO);var n,r=[],s=[],o=-1,i=!1;if(e.indexOf("<")!==0){var a=e.indexOf("<");r.push({type:"text",content:a===-1?e:e.substring(0,a)})}return e.replace(EO,function(c,u){if(i){if(c!=="")return;i=!1}var d,f=c.charAt(1)!=="/",h=c.startsWith(" - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/favicon-docs.dogecloud.com-1-200x200.svg b/ui/dist/imgs/providers/favicon-docs.dogecloud.com-1-200x200.svg deleted file mode 100644 index 83f1ec47..00000000 --- a/ui/dist/imgs/providers/favicon-docs.dogecloud.com-1-200x200.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ui/dist/imgs/providers/godaddy.svg b/ui/dist/imgs/providers/godaddy.svg index a60b56cd..a859a7ae 100644 --- a/ui/dist/imgs/providers/godaddy.svg +++ b/ui/dist/imgs/providers/godaddy.svg @@ -1,5 +1 @@ - - - - - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/huaweicloud.svg b/ui/dist/imgs/providers/huaweicloud.svg index 68c301eb..552e59e7 100644 --- a/ui/dist/imgs/providers/huaweicloud.svg +++ b/ui/dist/imgs/providers/huaweicloud.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/letsencrypt.svg b/ui/dist/imgs/providers/letsencrypt.svg index d18cedc9..3a6c2312 100644 --- a/ui/dist/imgs/providers/letsencrypt.svg +++ b/ui/dist/imgs/providers/letsencrypt.svg @@ -1,18 +1 @@ - - - - - - - - - - - - - - - - - - + diff --git a/ui/dist/imgs/providers/local.svg b/ui/dist/imgs/providers/local.svg index 46cfc247..2f59af07 100644 --- a/ui/dist/imgs/providers/local.svg +++ b/ui/dist/imgs/providers/local.svg @@ -1,10 +1 @@ - - - - - - - - - - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/namesilo.svg b/ui/dist/imgs/providers/namesilo.svg index 457698fa..e0cc8da4 100644 --- a/ui/dist/imgs/providers/namesilo.svg +++ b/ui/dist/imgs/providers/namesilo.svg @@ -1,8 +1 @@ - - - - - - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/qiniu.svg b/ui/dist/imgs/providers/qiniu.svg index 4088190b..d3b98877 100644 --- a/ui/dist/imgs/providers/qiniu.svg +++ b/ui/dist/imgs/providers/qiniu.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/ssh.png b/ui/dist/imgs/providers/ssh.png deleted file mode 100644 index d43cf03a..00000000 Binary files a/ui/dist/imgs/providers/ssh.png and /dev/null differ diff --git a/ui/dist/imgs/providers/ssh.svg b/ui/dist/imgs/providers/ssh.svg index 97b78788..8dea9e89 100644 --- a/ui/dist/imgs/providers/ssh.svg +++ b/ui/dist/imgs/providers/ssh.svg @@ -1,26 +1 @@ - - - - - - - databases-and-servers/servers/ssh - Created with Sketch. - - - - - - - - - - - - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/tencent.svg b/ui/dist/imgs/providers/tencent.svg index 1f4e8a79..76e54dbb 100644 --- a/ui/dist/imgs/providers/tencent.svg +++ b/ui/dist/imgs/providers/tencent.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/volcengine.svg b/ui/dist/imgs/providers/volcengine.svg deleted file mode 100644 index 32d508d0..00000000 --- a/ui/dist/imgs/providers/volcengine.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - appbar_logo_dark.2 - - - - - - - - - - \ No newline at end of file diff --git a/ui/dist/imgs/providers/wangsu.svg b/ui/dist/imgs/providers/wangsu.svg deleted file mode 100644 index 585b00c5..00000000 --- a/ui/dist/imgs/providers/wangsu.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - wangsu - - - - - - \ No newline at end of file diff --git a/ui/dist/imgs/providers/webhook.svg b/ui/dist/imgs/providers/webhook.svg index ac2e7d9b..2ca5bff3 100644 --- a/ui/dist/imgs/providers/webhook.svg +++ b/ui/dist/imgs/providers/webhook.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/dist/imgs/providers/zerossl.svg b/ui/dist/imgs/providers/zerossl.svg index 4f1afb54..8563aece 100644 --- a/ui/dist/imgs/providers/zerossl.svg +++ b/ui/dist/imgs/providers/zerossl.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/dist/index.html b/ui/dist/index.html index bfc57684..ecc548bb 100644 --- a/ui/dist/index.html +++ b/ui/dist/index.html @@ -1,14 +1,14 @@ - - - - - - - Certimate - Your Trusted SSL Automation Partner - - - - -
- - + + + + + + + Certimate - Your Trusted SSL Automation Partner + + + + +
+ + diff --git a/ui/package-lock.json b/ui/package-lock.json index 6a2feac0..d47094dc 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -55,9 +55,12 @@ "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.19", "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "postcss": "^8.4.40", + "prettier": "^3.3.3", "tailwindcss": "^3.4.7", "typescript": "^5.6.2", "vite": "^5.3.4" @@ -1129,6 +1132,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@radix-ui/number": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@radix-ui/number/-/number-1.1.0.tgz", @@ -3203,6 +3218,48 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.2", "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", @@ -3436,6 +3493,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz", @@ -4598,6 +4661,33 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -5184,6 +5274,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tailwind-merge": { "version": "2.4.0", "resolved": "https://registry.npmmirror.com/tailwind-merge/-/tailwind-merge-2.4.0.tgz", diff --git a/ui/package.json b/ui/package.json index 231fad66..6ff6ad68 100644 --- a/ui/package.json +++ b/ui/package.json @@ -57,9 +57,12 @@ "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.19", "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "postcss": "^8.4.40", + "prettier": "^3.3.3", "tailwindcss": "^3.4.7", "typescript": "^5.6.2", "vite": "^5.3.4" diff --git a/ui/postcss.config.js b/ui/postcss.config.js index 2e7af2b7..2aa7205d 100644 --- a/ui/postcss.config.js +++ b/ui/postcss.config.js @@ -3,4 +3,4 @@ export default { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/ui/public/imgs/providers/aliyun.svg b/ui/public/imgs/providers/aliyun.svg index dedad191..b4f740ee 100644 --- a/ui/public/imgs/providers/aliyun.svg +++ b/ui/public/imgs/providers/aliyun.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/public/imgs/providers/baidu.svg b/ui/public/imgs/providers/baidu.svg deleted file mode 100644 index 5ac20a05..00000000 --- a/ui/public/imgs/providers/baidu.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/public/imgs/providers/baisan.avif b/ui/public/imgs/providers/baisan.avif deleted file mode 100644 index 1313cda9..00000000 Binary files a/ui/public/imgs/providers/baisan.avif and /dev/null differ diff --git a/ui/public/imgs/providers/cloudflare.svg b/ui/public/imgs/providers/cloudflare.svg index 3eecafbd..b6f07b50 100644 --- a/ui/public/imgs/providers/cloudflare.svg +++ b/ui/public/imgs/providers/cloudflare.svg @@ -1,24 +1 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/ui/public/imgs/providers/favicon-docs.dogecloud.com-1-200x200.svg b/ui/public/imgs/providers/favicon-docs.dogecloud.com-1-200x200.svg deleted file mode 100644 index 83f1ec47..00000000 --- a/ui/public/imgs/providers/favicon-docs.dogecloud.com-1-200x200.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ui/public/imgs/providers/godaddy.svg b/ui/public/imgs/providers/godaddy.svg index a60b56cd..a859a7ae 100644 --- a/ui/public/imgs/providers/godaddy.svg +++ b/ui/public/imgs/providers/godaddy.svg @@ -1,5 +1 @@ - - - - - \ No newline at end of file + diff --git a/ui/public/imgs/providers/huaweicloud.svg b/ui/public/imgs/providers/huaweicloud.svg index 68c301eb..552e59e7 100644 --- a/ui/public/imgs/providers/huaweicloud.svg +++ b/ui/public/imgs/providers/huaweicloud.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/public/imgs/providers/letsencrypt.svg b/ui/public/imgs/providers/letsencrypt.svg index d18cedc9..3a6c2312 100644 --- a/ui/public/imgs/providers/letsencrypt.svg +++ b/ui/public/imgs/providers/letsencrypt.svg @@ -1,18 +1 @@ - - - - - - - - - - - - - - - - - - + diff --git a/ui/public/imgs/providers/local.svg b/ui/public/imgs/providers/local.svg index 46cfc247..2f59af07 100644 --- a/ui/public/imgs/providers/local.svg +++ b/ui/public/imgs/providers/local.svg @@ -1,10 +1 @@ - - - - - - - - - - \ No newline at end of file + diff --git a/ui/public/imgs/providers/namesilo.svg b/ui/public/imgs/providers/namesilo.svg index 457698fa..e0cc8da4 100644 --- a/ui/public/imgs/providers/namesilo.svg +++ b/ui/public/imgs/providers/namesilo.svg @@ -1,8 +1 @@ - - - - - - \ No newline at end of file + diff --git a/ui/public/imgs/providers/qiniu.svg b/ui/public/imgs/providers/qiniu.svg index 4088190b..d3b98877 100644 --- a/ui/public/imgs/providers/qiniu.svg +++ b/ui/public/imgs/providers/qiniu.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/public/imgs/providers/ssh.png b/ui/public/imgs/providers/ssh.png deleted file mode 100644 index d43cf03a..00000000 Binary files a/ui/public/imgs/providers/ssh.png and /dev/null differ diff --git a/ui/public/imgs/providers/ssh.svg b/ui/public/imgs/providers/ssh.svg index 97b78788..8dea9e89 100644 --- a/ui/public/imgs/providers/ssh.svg +++ b/ui/public/imgs/providers/ssh.svg @@ -1,26 +1 @@ - - - - - - - databases-and-servers/servers/ssh - Created with Sketch. - - - - - - - - - - - - \ No newline at end of file + diff --git a/ui/public/imgs/providers/tencent.svg b/ui/public/imgs/providers/tencent.svg index 1f4e8a79..76e54dbb 100644 --- a/ui/public/imgs/providers/tencent.svg +++ b/ui/public/imgs/providers/tencent.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/public/imgs/providers/volcengine.svg b/ui/public/imgs/providers/volcengine.svg deleted file mode 100644 index 32d508d0..00000000 --- a/ui/public/imgs/providers/volcengine.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - appbar_logo_dark.2 - - - - - - - - - - \ No newline at end of file diff --git a/ui/public/imgs/providers/wangsu.svg b/ui/public/imgs/providers/wangsu.svg deleted file mode 100644 index 585b00c5..00000000 --- a/ui/public/imgs/providers/wangsu.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - wangsu - - - - - - \ No newline at end of file diff --git a/ui/public/imgs/providers/webhook.svg b/ui/public/imgs/providers/webhook.svg index ac2e7d9b..2ca5bff3 100644 --- a/ui/public/imgs/providers/webhook.svg +++ b/ui/public/imgs/providers/webhook.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/public/imgs/providers/zerossl.svg b/ui/public/imgs/providers/zerossl.svg index 4f1afb54..8563aece 100644 --- a/ui/public/imgs/providers/zerossl.svg +++ b/ui/public/imgs/providers/zerossl.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ui/src/assets/react.svg b/ui/src/assets/react.svg deleted file mode 100644 index 6c87de9b..00000000 --- a/ui/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/src/components/LocaleToggle.tsx b/ui/src/components/LocaleToggle.tsx index f0e4c95d..2385716a 100644 --- a/ui/src/components/LocaleToggle.tsx +++ b/ui/src/components/LocaleToggle.tsx @@ -1,14 +1,8 @@ +import { useTranslation } from "react-i18next"; import { Languages } from "lucide-react"; -import { useTranslation } from "react-i18next"; - import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; export default function LocaleToggle() { const { i18n } = useTranslation(); @@ -23,9 +17,7 @@ export default function LocaleToggle() { {Object.keys(i18n.store.data).map((key) => ( - i18n.changeLanguage(key)}> - {i18n.store.data[key].name as string} - + i18n.changeLanguage(key)}>{i18n.store.data[key].name as string} ))} diff --git a/ui/src/components/Show.tsx b/ui/src/components/Show.tsx index 8c91f216..282addc3 100644 --- a/ui/src/components/Show.tsx +++ b/ui/src/components/Show.tsx @@ -1,14 +1,6 @@ import React from "react"; -const Show = ({ - when, - children, - fallback, -}: { - when: boolean; - children: React.ReactNode; - fallback?: React.ReactNode; -}) => { +const Show = ({ when, children, fallback }: { when: boolean; children: React.ReactNode; fallback?: React.ReactNode }) => { return when ? children : fallback; }; diff --git a/ui/src/components/ThemeProvider.tsx b/ui/src/components/ThemeProvider.tsx index 7b9eeb27..b117f623 100644 --- a/ui/src/components/ThemeProvider.tsx +++ b/ui/src/components/ThemeProvider.tsx @@ -20,15 +20,8 @@ const initialState: ThemeProviderState = { const ThemeProviderContext = createContext(initialState); -export function ThemeProvider({ - children, - defaultTheme = "system", - storageKey = "vite-ui-theme", - ...props -}: ThemeProviderProps) { - const [theme, setTheme] = useState( - () => (localStorage.getItem(storageKey) as Theme) || defaultTheme - ); +export function ThemeProvider({ children, defaultTheme = "system", storageKey = "vite-ui-theme", ...props }: ThemeProviderProps) { + const [theme, setTheme] = useState(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme); useEffect(() => { const root = window.document.documentElement; @@ -36,10 +29,7 @@ export function ThemeProvider({ root.classList.remove("light", "dark"); if (theme === "system") { - const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") - .matches - ? "dark" - : "light"; + const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; root.classList.add(systemTheme); return; @@ -66,8 +56,7 @@ export function ThemeProvider({ export const useTheme = () => { const context = useContext(ThemeProviderContext); - if (context === undefined) - throw new Error("useTheme must be used within a ThemeProvider"); + if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider"); return context; }; diff --git a/ui/src/components/ThemeToggle.tsx b/ui/src/components/ThemeToggle.tsx index 0a57de8b..ef69888f 100644 --- a/ui/src/components/ThemeToggle.tsx +++ b/ui/src/components/ThemeToggle.tsx @@ -1,13 +1,8 @@ -import { Moon, Sun } from "lucide-react"; import { useTranslation } from "react-i18next"; +import { Moon, Sun } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; import { useTheme } from "./ThemeProvider"; export function ThemeToggle() { @@ -24,15 +19,9 @@ export function ThemeToggle() { - setTheme("light")}> - {t("common.theme.light")} - - setTheme("dark")}> - {t("common.theme.dark")} - - setTheme("system")}> - {t("common.theme.system")} - + setTheme("light")}>{t("common.theme.light")} + setTheme("dark")}>{t("common.theme.dark")} + setTheme("system")}>{t("common.theme.system")} ); diff --git a/ui/src/components/certimate/AccessAliyunForm.tsx b/ui/src/components/certimate/AccessAliyunForm.tsx index 11a3ca9b..9ce87a47 100644 --- a/ui/src/components/certimate/AccessAliyunForm.tsx +++ b/ui/src/components/certimate/AccessAliyunForm.tsx @@ -1,41 +1,24 @@ -import { Input } from "@/components/ui/input"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; - -import { zodResolver } from "@hookform/resolvers/zod"; - import z from "zod"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Button } from "@/components/ui/button"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { ClientResponseError } from "pocketbase"; -import { - Access, - accessFormType, - AliyunConfig, - getUsageByConfigType, -} from "@/domain/access"; +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { PbErrorData } from "@/domain/base"; +import { Access, AliyunConfig, accessFormType, getUsageByConfigType } from "@/domain/access"; import { save } from "@/repository/access"; import { useConfig } from "@/providers/config"; -import { ClientResponseError } from "pocketbase"; -import { PbErrorData } from "@/domain/base"; - -const AccessAliyunForm = ({ - data, - op, - onAfterReq, -}: { - data?: Access; +type AccessAliyunFormProps = { op: "add" | "edit" | "copy"; + data?: Access; onAfterReq: () => void; -}) => { +}; + +const AccessAliyunForm = ({ data, op, onAfterReq }: AccessAliyunFormProps) => { const { addAccess, updateAccess } = useConfig(); const { t } = useTranslation(); const formSchema = z.object({ @@ -97,19 +80,17 @@ const AccessAliyunForm = ({ updateAccess(req); return; } - console.log(req); + addAccess(req); } catch (e) { const err = e as ClientResponseError; - Object.entries(err.response.data as PbErrorData).forEach( - ([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - } - ); + Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { + form.setError(key as keyof z.infer, { + type: "manual", + message: value.message, + }); + }); return; } @@ -133,10 +114,7 @@ const AccessAliyunForm = ({ {t("access.authorization.form.name.label")} - + @@ -181,10 +159,7 @@ const AccessAliyunForm = ({ {t("access.authorization.form.access_key_id.label")} - + @@ -199,10 +174,7 @@ const AccessAliyunForm = ({ {t("access.authorization.form.access_key_secret.label")} - + diff --git a/ui/src/components/certimate/AccessCloudflareForm.tsx b/ui/src/components/certimate/AccessCloudflareForm.tsx index d1a5f9c5..c167875b 100644 --- a/ui/src/components/certimate/AccessCloudflareForm.tsx +++ b/ui/src/components/certimate/AccessCloudflareForm.tsx @@ -1,40 +1,24 @@ -import { Input } from "@/components/ui/input"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; - -import { zodResolver } from "@hookform/resolvers/zod"; - import z from "zod"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Button } from "@/components/ui/button"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { ClientResponseError } from "pocketbase"; -import { - Access, - accessFormType, - CloudflareConfig, - getUsageByConfigType, -} from "@/domain/access"; +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { PbErrorData } from "@/domain/base"; +import { Access, accessFormType, CloudflareConfig, getUsageByConfigType } from "@/domain/access"; import { save } from "@/repository/access"; import { useConfig } from "@/providers/config"; -import { ClientResponseError } from "pocketbase"; -import { PbErrorData } from "@/domain/base"; -const AccessCloudflareForm = ({ - data, - op, - onAfterReq, -}: { - data?: Access; +type AccessCloudflareFormProps = { op: "add" | "edit" | "copy"; + data?: Access; onAfterReq: () => void; -}) => { +}; + +const AccessCloudflareForm = ({ data, op, onAfterReq }: AccessCloudflareFormProps) => { const { addAccess, updateAccess } = useConfig(); const { t } = useTranslation(); const formSchema = z.object({ @@ -66,7 +50,6 @@ const AccessCloudflareForm = ({ }); const onSubmit = async (data: z.infer) => { - console.log(data); const req: Access = { id: data.id as string, name: data.name, @@ -94,14 +77,12 @@ const AccessCloudflareForm = ({ } catch (e) { const err = e as ClientResponseError; - Object.entries(err.response.data as PbErrorData).forEach( - ([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - } - ); + Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { + form.setError(key as keyof z.infer, { + type: "manual", + message: value.message, + }); + }); } }; @@ -111,7 +92,6 @@ const AccessCloudflareForm = ({
{ - console.log(e); e.stopPropagation(); form.handleSubmit(onSubmit)(e); }} @@ -124,10 +104,7 @@ const AccessCloudflareForm = ({ {t("access.authorization.form.name.label")} - + @@ -172,12 +149,7 @@ const AccessCloudflareForm = ({ {t("access.authorization.form.cloud_dns_api_token.label")} - + diff --git a/ui/src/components/certimate/AccessEdit.tsx b/ui/src/components/certimate/AccessEdit.tsx index 27b2bac5..387d55e7 100644 --- a/ui/src/components/certimate/AccessEdit.tsx +++ b/ui/src/components/certimate/AccessEdit.tsx @@ -1,51 +1,31 @@ -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { ScrollArea } from "@/components/ui/scroll-area"; - import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { Access, accessTypeMap } from "@/domain/access"; import { cn } from "@/lib/utils"; - -import { Label } from "../ui/label"; -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectTrigger, - SelectValue, -} from "../ui/select"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import { Label } from "@/components/ui/label"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select"; import AccessAliyunForm from "./AccessAliyunForm"; import AccessTencentForm from "./AccessTencentForm"; import AccessHuaweicloudForm from "./AccessHuaweicloudForm"; import AccessQiniuForm from "./AccessQiniuForm"; import AccessCloudflareForm from "./AccessCloudflareForm"; import AccessNamesiloForm from "./AccessNamesiloForm"; -import AccessGodaddyFrom from "./AccessGodaddyForm"; +import AccessGodaddyForm from "./AccessGodaddyForm"; import AccessLocalForm from "./AccessLocalForm"; import AccessSSHForm from "./AccessSSHForm"; -import AccessWebhookForm from "./AccessWebhookFrom"; +import AccessWebhookForm from "./AccessWebhookForm"; +import { Access, accessTypeMap } from "@/domain/access"; -type TargetConfigEditProps = { +type AccessEditProps = { op: "add" | "edit" | "copy"; className?: string; trigger: React.ReactNode; data?: Access; }; -export function AccessEdit({ - trigger, - op, - data, - className, -}: TargetConfigEditProps) { + +const AccessEdit = ({ trigger, op, data, className }: AccessEditProps) => { const [open, setOpen] = useState(false); const { t } = useTranslation(); @@ -123,7 +103,7 @@ export function AccessEdit({ break; case "godaddy": form = ( - { @@ -179,11 +159,7 @@ export function AccessEdit({ - {op == "add" - ? t("access.authorization.add") - : op == "edit" - ? t("access.authorization.edit") - : t("access.authorization.copy")} + {op == "add" ? t("access.authorization.add") : op == "edit" ? t("access.authorization.edit") : t("access.authorization.copy")} @@ -204,16 +180,8 @@ export function AccessEdit({ {t("access.authorization.form.type.list")} {typeKeys.map((key) => ( -
- +
+
{t(accessTypeMap.get(key)?.[0] || "")}
@@ -228,4 +196,6 @@ export function AccessEdit({ ); -} +}; + +export default AccessEdit; diff --git a/ui/src/components/certimate/AccessGodaddyForm.tsx b/ui/src/components/certimate/AccessGodaddyForm.tsx index d3bfb7b2..a550af38 100644 --- a/ui/src/components/certimate/AccessGodaddyForm.tsx +++ b/ui/src/components/certimate/AccessGodaddyForm.tsx @@ -1,40 +1,24 @@ -import { Input } from "@/components/ui/input"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; - -import { zodResolver } from "@hookform/resolvers/zod"; - import z from "zod"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Button } from "@/components/ui/button"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { ClientResponseError } from "pocketbase"; -import { - Access, - accessFormType, - getUsageByConfigType, - GodaddyConfig, -} from "@/domain/access"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { PbErrorData } from "@/domain/base"; +import { Access, accessFormType, getUsageByConfigType, GodaddyConfig } from "@/domain/access"; import { save } from "@/repository/access"; import { useConfig } from "@/providers/config"; -import { ClientResponseError } from "pocketbase"; -import { PbErrorData } from "@/domain/base"; -const AccessGodaddyFrom = ({ - data, - op, - onAfterReq, -}: { - data?: Access; +type AccessGodaddyFormProps = { op: "add" | "edit" | "copy"; + data?: Access; onAfterReq: () => void; -}) => { +}; + +const AccessGodaddyForm = ({ data, op, onAfterReq }: AccessGodaddyFormProps) => { const { addAccess, updateAccess } = useConfig(); const { t } = useTranslation(); const formSchema = z.object({ @@ -72,7 +56,6 @@ const AccessGodaddyFrom = ({ }); const onSubmit = async (data: z.infer) => { - console.log(data); const req: Access = { id: data.id as string, name: data.name, @@ -101,14 +84,12 @@ const AccessGodaddyFrom = ({ } catch (e) { const err = e as ClientResponseError; - Object.entries(err.response.data as PbErrorData).forEach( - ([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - } - ); + Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { + form.setError(key as keyof z.infer, { + type: "manual", + message: value.message, + }); + }); } }; @@ -118,7 +99,6 @@ const AccessGodaddyFrom = ({ { - console.log(e); e.stopPropagation(); form.handleSubmit(onSubmit)(e); }} @@ -131,10 +111,7 @@ const AccessGodaddyFrom = ({ {t("access.authorization.form.name.label")} - + @@ -179,10 +156,7 @@ const AccessGodaddyFrom = ({ {t("access.authorization.form.godaddy_api_key.label")} - + @@ -197,12 +171,7 @@ const AccessGodaddyFrom = ({ {t("access.authorization.form.godaddy_api_secret.label")} - + @@ -220,4 +189,4 @@ const AccessGodaddyFrom = ({ ); }; -export default AccessGodaddyFrom; +export default AccessGodaddyForm; diff --git a/ui/src/components/certimate/AccessGroupEdit.tsx b/ui/src/components/certimate/AccessGroupEdit.tsx index c32cb335..8f809fd3 100644 --- a/ui/src/components/certimate/AccessGroupEdit.tsx +++ b/ui/src/components/certimate/AccessGroupEdit.tsx @@ -1,31 +1,18 @@ -import { cn } from "@/lib/utils"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "../ui/dialog"; - +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useForm } from "react-hook-form"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "../ui/form"; -import { Input } from "../ui/input"; -import { Button } from "../ui/button"; -import { useConfig } from "@/providers/config"; -import { update } from "@/repository/access_group"; import { ClientResponseError } from "pocketbase"; + +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; import { PbErrorData } from "@/domain/base"; -import { useState } from "react"; -import { useTranslation } from "react-i18next"; +import { update } from "@/repository/access_group"; +import { useConfig } from "@/providers/config"; type AccessGroupEditProps = { className?: string; @@ -65,14 +52,12 @@ const AccessGroupEdit = ({ className, trigger }: AccessGroupEditProps) => { } catch (e) { const err = e as ClientResponseError; - Object.entries(err.response.data as PbErrorData).forEach( - ([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - } - ); + Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { + form.setError(key as keyof z.infer, { + type: "manual", + message: value.message, + }); + }); } }; @@ -102,11 +87,7 @@ const AccessGroupEdit = ({ className, trigger }: AccessGroupEditProps) => { {t("access.group.form.name.label")} - + diff --git a/ui/src/components/certimate/AccessGroupList.tsx b/ui/src/components/certimate/AccessGroupList.tsx index 84e53967..a5b97998 100644 --- a/ui/src/components/certimate/AccessGroupList.tsx +++ b/ui/src/components/certimate/AccessGroupList.tsx @@ -1,4 +1,7 @@ -import AccessGroupEdit from "@/components/certimate/AccessGroupEdit"; +import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import { Group } from "lucide-react"; + import Show from "@/components/Show"; import { AlertDialog, @@ -12,24 +15,14 @@ import { AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "@/components/ui/card"; +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { ScrollArea } from "@/components/ui/scroll-area"; +import { useToast } from "@/components/ui/use-toast"; +import AccessGroupEdit from "./AccessGroupEdit"; import { getProviderInfo } from "@/domain/access"; import { getErrMessage } from "@/lib/error"; import { useConfig } from "@/providers/config"; import { remove } from "@/repository/access_group"; -import { Group } from "lucide-react"; -import { useToast } from "@/components/ui/use-toast"; - -import { useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; const AccessGroupList = () => { const { @@ -68,13 +61,8 @@ const AccessGroupList = () => { -
- {t("access.group.domains.nodata")} -
- {t("access.group.add")}} - className="mt-3" - /> +
{t("access.group.domains.nodata")}
+ {t("access.group.add")}} className="mt-3" />
@@ -87,9 +75,7 @@ const AccessGroupList = () => { {accessGroup.name} {t("access.group.total", { - total: accessGroup.expand - ? accessGroup.expand.access.length - : 0, + total: accessGroup.expand ? accessGroup.expand.access.length : 0, })} @@ -100,19 +86,11 @@ const AccessGroupList = () => {
- provider + provider
-
- {access.name} -
-
- {getProviderInfo(access.configType)![0]} -
+
{access.name}
+
{getProviderInfo(access.configType)![0]}
@@ -131,24 +109,15 @@ const AccessGroupList = () => {
- 0 - ? true - : false - } - > + 0 ? true : false}>
- +
void; -}) => { +}; + +const AccessTencentForm = ({ data, op, onAfterReq }: AccessTencentFormProps) => { const { addAccess, updateAccess } = useConfig(); const { t } = useTranslation(); const formSchema = z.object({ @@ -100,14 +84,12 @@ const AccessTencentForm = ({ } catch (e) { const err = e as ClientResponseError; - Object.entries(err.response.data as PbErrorData).forEach( - ([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - } - ); + Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { + form.setError(key as keyof z.infer, { + type: "manual", + message: value.message, + }); + }); } }; @@ -129,10 +111,7 @@ const AccessTencentForm = ({ {t("access.authorization.form.name.label")} - + @@ -177,10 +156,7 @@ const AccessTencentForm = ({ {t("access.authorization.form.secret_id.label")} - + @@ -195,10 +171,7 @@ const AccessTencentForm = ({ {t("access.authorization.form.secret_key.label")} - + diff --git a/ui/src/components/certimate/AccessWebhookFrom.tsx b/ui/src/components/certimate/AccessWebhookForm.tsx similarity index 81% rename from ui/src/components/certimate/AccessWebhookFrom.tsx rename to ui/src/components/certimate/AccessWebhookForm.tsx index dc508bb5..6cde4c59 100644 --- a/ui/src/components/certimate/AccessWebhookFrom.tsx +++ b/ui/src/components/certimate/AccessWebhookForm.tsx @@ -1,40 +1,24 @@ -import { Input } from "@/components/ui/input"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; - -import { zodResolver } from "@hookform/resolvers/zod"; - import z from "zod"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Button } from "@/components/ui/button"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { ClientResponseError } from "pocketbase"; -import { - Access, - accessFormType, - getUsageByConfigType, - WebhookConfig, -} from "@/domain/access"; +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { PbErrorData } from "@/domain/base"; +import { Access, accessFormType, getUsageByConfigType, WebhookConfig } from "@/domain/access"; import { save } from "@/repository/access"; import { useConfig } from "@/providers/config"; -import { ClientResponseError } from "pocketbase"; -import { PbErrorData } from "@/domain/base"; -const WebhookForm = ({ - data, - op, - onAfterReq, -}: { - data?: Access; +type AccessWebhookFormProps = { op: "add" | "edit" | "copy"; + data?: Access; onAfterReq: () => void; -}) => { +}; + +const AccessWebhookForm = ({ data, op, onAfterReq }: AccessWebhookFormProps) => { const { addAccess, updateAccess } = useConfig(); const { t } = useTranslation(); const formSchema = z.object({ @@ -90,14 +74,12 @@ const WebhookForm = ({ } catch (e) { const err = e as ClientResponseError; - Object.entries(err.response.data as PbErrorData).forEach( - ([key, value]) => { - form.setError(key as keyof z.infer, { - type: "manual", - message: value.message, - }); - } - ); + Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => { + form.setError(key as keyof z.infer, { + type: "manual", + message: value.message, + }); + }); } }; @@ -107,7 +89,6 @@ const WebhookForm = ({ { - console.log(e); e.stopPropagation(); form.handleSubmit(onSubmit)(e); }} @@ -120,10 +101,7 @@ const WebhookForm = ({ {t("access.authorization.form.name.label")} - + @@ -168,10 +146,7 @@ const WebhookForm = ({ {t("access.authorization.form.webhook_url.label")} - + @@ -189,4 +164,4 @@ const WebhookForm = ({ ); }; -export default WebhookForm; +export default AccessWebhookForm; diff --git a/ui/src/components/certimate/DeployList.tsx b/ui/src/components/certimate/DeployList.tsx index 4fb70cde..92424e96 100644 --- a/ui/src/components/certimate/DeployList.tsx +++ b/ui/src/components/certimate/DeployList.tsx @@ -1,50 +1,23 @@ -import { - createContext, - useCallback, - useContext, - useEffect, - useState, -} from "react"; -import { Button } from "../ui/button"; -import { EditIcon, Plus, Trash2 } from "lucide-react"; -import { - DeployConfig, - KVType, - targetTypeKeys, - targetTypeMap, -} from "@/domain/domain"; -import Show from "../Show"; -import { Alert, AlertDescription } from "../ui/alert"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "../ui/dialog"; - -import { Label } from "../ui/label"; -import { useConfig } from "@/providers/config"; -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectTrigger, - SelectValue, -} from "../ui/select"; -import { accessTypeMap } from "@/domain/access"; +import { createContext, useCallback, useContext, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import { AccessEdit } from "./AccessEdit"; -import { Input } from "../ui/input"; -import { Textarea } from "../ui/textarea"; -import KVList from "./KVList"; +import { z } from "zod"; import { produce } from "immer"; import { nanoid } from "nanoid"; -import { z } from "zod"; +import { EditIcon, Plus, Trash2 } from "lucide-react"; + +import Show from "@/components/Show"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Textarea } from "@/components/ui/textarea"; +import AccessEdit from "./AccessEdit"; +import KVList from "./KVList"; +import { DeployConfig, KVType, targetTypeKeys, targetTypeMap } from "@/domain/domain"; +import { accessTypeMap } from "@/domain/access"; +import { useConfig } from "@/providers/config"; type DeployEditContextProps = { deploy: DeployConfig; @@ -53,9 +26,7 @@ type DeployEditContextProps = { setError: (error: Record) => void; }; -const DeployEditContext = createContext( - {} as DeployEditContextProps -); +const DeployEditContext = createContext({} as DeployEditContextProps); export const useDeployEditContext = () => { return useContext(DeployEditContext); @@ -156,11 +127,14 @@ const DeployList = ({ deploys, onChange }: DeployListProps) => { ); }; +export default DeployList; + type DeployItemProps = { item: DeployConfig; onDelete: () => void; onSave: (deploy: DeployConfig) => void; }; + const DeployItem = ({ item, onDelete, onSave }: DeployItemProps) => { const { config: { accesses }, @@ -232,11 +206,8 @@ type DeployEditDialogProps = { deployConfig?: DeployConfig; onSave: (deploy: DeployConfig) => void; }; -const DeployEditDialog = ({ - trigger, - deployConfig, - onSave, -}: DeployEditDialogProps) => { + +const DeployEditDialog = ({ trigger, deployConfig, onSave }: DeployEditDialogProps) => { const { config: { accesses }, } = useConfig(); @@ -265,13 +236,14 @@ const DeployEditDialog = ({ useEffect(() => { const temp = locDeployConfig.type.split("-"); - console.log(temp); + let t; if (temp && temp.length > 1) { t = temp[1]; } else { t = locDeployConfig.type; } + setDeployType(t as TargetType); setError({}); }, [locDeployConfig.type]); @@ -366,22 +338,15 @@ const DeployEditDialog = ({ }} > - + - - {t("domain.deployment.form.type.list")} - + {t("domain.deployment.form.type.list")} {targetTypeKeys.map((item) => (
- +
{t(targetTypeMap.get(item)?.[0] ?? "")}
@@ -415,24 +380,15 @@ const DeployEditDialog = ({ }} > - + - - {t("domain.deployment.form.access.list")} - + {t("domain.deployment.form.access.list")} {targetAccesses.map((item) => (
- +
{item.name}
@@ -468,29 +424,30 @@ type TargetType = "ssh" | "cdn" | "webhook" | "local" | "oss" | "dcdn"; type DeployEditProps = { type: TargetType; }; + const DeployEdit = ({ type }: DeployEditProps) => { const getDeploy = () => { switch (type) { case "ssh": - return ; + return ; case "local": - return ; + return ; case "cdn": - return ; + return ; case "dcdn": - return ; + return ; case "oss": - return ; + return ; case "webhook": - return ; + return ; default: - return ; + return ; } }; return getDeploy(); }; -const DeploySSH = () => { +const DeployToSSH = () => { const { t } = useTranslation(); const { setError } = useDeployEditContext(); @@ -536,9 +493,7 @@ const DeploySSH = () => {
{ @@ -558,9 +513,7 @@ const DeploySSH = () => { -
- {t("settings.notification.template.variables.tips.content")} -
+
{t("settings.notification.template.variables.tips.content")}
diff --git a/ui/src/components/notify/Telegram.tsx b/ui/src/components/notify/Telegram.tsx index 53911e8d..593359ba 100644 --- a/ui/src/components/notify/Telegram.tsx +++ b/ui/src/components/notify/Telegram.tsx @@ -1,15 +1,16 @@ -import { Input } from "../ui/input"; -import { Button } from "../ui/button"; -import { Switch } from "../ui/switch"; -import { Label } from "../ui/label"; -import { useNotify } from "@/providers/notify"; -import { NotifyChannels, NotifyChannelTelegram } from "@/domain/settings"; import { useEffect, useState } from "react"; -import { update } from "@/repository/settings"; -import { getErrMessage } from "@/lib/error"; -import { useToast } from "../ui/use-toast"; import { useTranslation } from "react-i18next"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Switch } from "@/components/ui/switch"; +import { useToast } from "@/components/ui/use-toast"; +import { getErrMessage } from "@/lib/error"; +import { NotifyChannels, NotifyChannelTelegram } from "@/domain/settings"; +import { update } from "@/repository/settings"; +import { useNotify } from "@/providers/notify"; + type TelegramSetting = { id: string; name: string; @@ -80,9 +81,7 @@ const Telegram = () => { toast({ title: t("common.save.failed.message"), - description: `${t( - "settings.notification.config.failed.message" - )}: ${msg}`, + description: `${t("settings.notification.config.failed.message")}: ${msg}`, variant: "destructive", }); } @@ -132,9 +131,7 @@ const Telegram = () => { }); }} /> - +
diff --git a/ui/src/components/notify/Webhook.tsx b/ui/src/components/notify/Webhook.tsx index 83bc451a..187c3527 100644 --- a/ui/src/components/notify/Webhook.tsx +++ b/ui/src/components/notify/Webhook.tsx @@ -1,16 +1,17 @@ -import { Input } from "../ui/input"; -import { Button } from "../ui/button"; -import { Switch } from "../ui/switch"; -import { Label } from "../ui/label"; -import { useNotify } from "@/providers/notify"; -import { NotifyChannels, NotifyChannelWebhook } from "@/domain/settings"; import { useEffect, useState } from "react"; -import { update } from "@/repository/settings"; -import { getErrMessage } from "@/lib/error"; -import { useToast } from "../ui/use-toast"; -import { isValidURL } from "@/lib/url"; import { useTranslation } from "react-i18next"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Switch } from "@/components/ui/switch"; +import { useToast } from "@/components/ui/use-toast"; +import { getErrMessage } from "@/lib/error"; +import { isValidURL } from "@/lib/url"; +import { NotifyChannels, NotifyChannelWebhook } from "@/domain/settings"; +import { update } from "@/repository/settings"; +import { useNotify } from "@/providers/notify"; + type WebhookSetting = { id: string; name: string; @@ -89,9 +90,7 @@ const Webhook = () => { toast({ title: t("common.save.failed.message"), - description: `${t( - "settings.notification.config.failed.message" - )}: ${msg}`, + description: `${t("settings.notification.config.failed.message")}: ${msg}`, variant: "destructive", }); } @@ -127,9 +126,7 @@ const Webhook = () => { }); }} /> - +
diff --git a/ui/src/components/ui/accordion.tsx b/ui/src/components/ui/accordion.tsx index 21887361..13d3fec9 100644 --- a/ui/src/components/ui/accordion.tsx +++ b/ui/src/components/ui/accordion.tsx @@ -6,16 +6,9 @@ import { cn } from "@/lib/utils"; const Accordion = AccordionPrimitive.Root; -const AccordionItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +const AccordionItem = React.forwardRef, React.ComponentPropsWithoutRef>( + ({ className, ...props }, ref) => +); AccordionItem.displayName = "AccordionItem"; const AccordionTrigger = React.forwardRef< @@ -25,10 +18,7 @@ const AccordionTrigger = React.forwardRef< svg]:rotate-180", - className - )} + className={cn("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", className)} {...props} > {children} diff --git a/ui/src/components/ui/alert-dialog.tsx b/ui/src/components/ui/alert-dialog.tsx index 8722561c..3edeed91 100644 --- a/ui/src/components/ui/alert-dialog.tsx +++ b/ui/src/components/ui/alert-dialog.tsx @@ -1,14 +1,14 @@ -import * as React from "react" -import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" +import * as React from "react"; +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"; -import { cn } from "@/lib/utils" -import { buttonVariants } from "@/components/ui/button" +import { cn } from "@/lib/utils"; +import { buttonVariants } from "@/components/ui/button"; -const AlertDialog = AlertDialogPrimitive.Root +const AlertDialog = AlertDialogPrimitive.Root; -const AlertDialogTrigger = AlertDialogPrimitive.Trigger +const AlertDialogTrigger = AlertDialogPrimitive.Trigger; -const AlertDialogPortal = AlertDialogPrimitive.Portal +const AlertDialogPortal = AlertDialogPrimitive.Portal; const AlertDialogOverlay = React.forwardRef< React.ElementRef, @@ -22,8 +22,8 @@ const AlertDialogOverlay = React.forwardRef< {...props} ref={ref} /> -)) -AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName +)); +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; const AlertDialogContent = React.forwardRef< React.ElementRef, @@ -40,89 +40,44 @@ const AlertDialogContent = React.forwardRef< {...props} /> -)) -AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName +)); +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName; -const AlertDialogHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogHeader.displayName = "AlertDialogHeader" +const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( +
+); +AlertDialogHeader.displayName = "AlertDialogHeader"; -const AlertDialogFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogFooter.displayName = "AlertDialogFooter" +const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( +
+); +AlertDialogFooter.displayName = "AlertDialogFooter"; const AlertDialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName +>(({ className, ...props }, ref) => ); +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; const AlertDialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogDescription.displayName = - AlertDialogPrimitive.Description.displayName +>(({ className, ...props }, ref) => ); +AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName; const AlertDialogAction = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName +>(({ className, ...props }, ref) => ); +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName; const AlertDialogCancel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +)); +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName; export { AlertDialog, @@ -136,4 +91,4 @@ export { AlertDialogDescription, AlertDialogAction, AlertDialogCancel, -} +}; diff --git a/ui/src/components/ui/alert.tsx b/ui/src/components/ui/alert.tsx index 29bd44f0..3e828361 100644 --- a/ui/src/components/ui/alert.tsx +++ b/ui/src/components/ui/alert.tsx @@ -9,8 +9,7 @@ const alertVariants = cva( variants: { variant: { default: "bg-background text-foreground", - destructive: - "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", }, }, defaultVariants: { @@ -19,40 +18,18 @@ const alertVariants = cva( } ); -const Alert = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & VariantProps ->(({ className, variant, ...props }, ref) => ( -
-)); +const Alert = React.forwardRef & VariantProps>( + ({ className, variant, ...props }, ref) =>
+); Alert.displayName = "Alert"; -const AlertTitle = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
+const AlertTitle = React.forwardRef>(({ className, ...props }, ref) => ( +
)); AlertTitle.displayName = "AlertTitle"; -const AlertDescription = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
+const AlertDescription = React.forwardRef>(({ className, ...props }, ref) => ( +
)); AlertDescription.displayName = "AlertDescription"; diff --git a/ui/src/components/ui/badge.tsx b/ui/src/components/ui/badge.tsx index f000e3ef..8910ffb8 100644 --- a/ui/src/components/ui/badge.tsx +++ b/ui/src/components/ui/badge.tsx @@ -1,19 +1,16 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const badgeVariants = cva( "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", { variants: { variant: { - default: - "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", - secondary: - "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", - destructive: - "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", outline: "text-foreground", }, }, @@ -21,16 +18,12 @@ const badgeVariants = cva( variant: "default", }, } -) +); -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps {} +export interface BadgeProps extends React.HTMLAttributes, VariantProps {} function Badge({ className, variant, ...props }: BadgeProps) { - return ( -
- ) + return
; } -export { Badge, badgeVariants } +export { Badge, badgeVariants }; diff --git a/ui/src/components/ui/breadcrumb.tsx b/ui/src/components/ui/breadcrumb.tsx index 71a5c325..c9813bda 100644 --- a/ui/src/components/ui/breadcrumb.tsx +++ b/ui/src/components/ui/breadcrumb.tsx @@ -1,115 +1,57 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { ChevronRight, MoreHorizontal } from "lucide-react" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const Breadcrumb = React.forwardRef< HTMLElement, React.ComponentPropsWithoutRef<"nav"> & { - separator?: React.ReactNode + separator?: React.ReactNode; } ->(({ ...props }, ref) =>