From 56bdf5388dfffb85e21fe5bc785455bc7891dccb Mon Sep 17 00:00:00 2001 From: Sibuxiangx Date: Sun, 3 Aug 2025 16:50:56 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=E5=88=9D=E6=AC=A1=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 10 + .gitattributes | 121 + .github/workflows/deploy-docs.yml | 109 + .gitignore | 422 +++ .markdownlint.json | 31 + LICENSE | 21 + README.md | 193 ++ config/__init__.py | 12 + config/logger.py | 68 + config/manager.py | 177 ++ config/models.py | 151 + database/__init__.py | 4 + database/base.py | 6 + database/creator.py | 79 + database/train_plan.py | 0 database/user.py | 52 + docs/.vitepress/components/SwaggerUI.vue | 200 ++ docs/.vitepress/config.ts | 75 + docs/.vitepress/theme/custom.css | 29 + docs/.vitepress/theme/index.ts | 17 + docs/api/index.md | 18 + docs/config.md | 232 ++ docs/contributing.md | 5 + docs/deploy.md | 5 + docs/disclaimer.md | 119 + docs/getting-started.md | 123 + docs/index.md | 91 + docs/public/images/logo.jpg | Bin 0 -> 11122 bytes docs/public/openapi.json | 2758 ++++++++++++++++++ docs/public/swagger-ui-bundle.js | 2 + docs/public/swagger-ui-standalone-preset.js | 2 + docs/public/swagger-ui.css | 3 + logo.jpg | Bin 0 -> 11122 bytes main.py | 70 + openapi.json | 2758 ++++++++++++++++++ package.json | 20 + pdm.lock | 1103 +++++++ provider/aufe/aac/__init__.py | 287 ++ provider/aufe/aac/depends.py | 66 + provider/aufe/aac/model.py | 105 + provider/aufe/client.py | 1176 ++++++++ provider/aufe/jwc/__init__.py | 1328 +++++++++ provider/aufe/jwc/depends.py | 36 + provider/aufe/jwc/model.py | 296 ++ provider/aufe/labor_club/__init__.py | 0 provider/aufe/labor_club/depends.py | 0 provider/aufe/labor_club/model.py | 0 provider/loveac/authme.py | 89 + provider/loveac/usersync.py | 0 pyproject.toml | 33 + router/aac/__init__.py | 77 + router/aac/model.py | 16 + router/common_model.py | 100 + router/invite/__init__.py | 118 + router/invite/model.py | 39 + router/jwc/__init__.py | 605 ++++ router/jwc/evaluate.py | 670 +++++ router/jwc/evaluate_model.py | 95 + router/jwc/model.py | 122 + router/login/__init__.py | 109 + router/login/model.py | 31 + router/user/__init__.py | 242 ++ router/user/model.py | 79 + utils/__init__.py | 6 + utils/file_manager.py | 322 +++ utils/s3_client.py | 370 +++ yarn.lock | 2876 +++++++++++++++++++ 67 files changed, 18379 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/workflows/deploy-docs.yml create mode 100644 .gitignore create mode 100644 .markdownlint.json create mode 100644 LICENSE create mode 100644 README.md create mode 100644 config/__init__.py create mode 100644 config/logger.py create mode 100644 config/manager.py create mode 100644 config/models.py create mode 100644 database/__init__.py create mode 100644 database/base.py create mode 100644 database/creator.py create mode 100644 database/train_plan.py create mode 100644 database/user.py create mode 100644 docs/.vitepress/components/SwaggerUI.vue create mode 100644 docs/.vitepress/config.ts create mode 100644 docs/.vitepress/theme/custom.css create mode 100644 docs/.vitepress/theme/index.ts create mode 100644 docs/api/index.md create mode 100644 docs/config.md create mode 100644 docs/contributing.md create mode 100644 docs/deploy.md create mode 100644 docs/disclaimer.md create mode 100644 docs/getting-started.md create mode 100644 docs/index.md create mode 100644 docs/public/images/logo.jpg create mode 100644 docs/public/openapi.json create mode 100644 docs/public/swagger-ui-bundle.js create mode 100644 docs/public/swagger-ui-standalone-preset.js create mode 100644 docs/public/swagger-ui.css create mode 100644 logo.jpg create mode 100644 main.py create mode 100644 openapi.json create mode 100644 package.json create mode 100644 pdm.lock create mode 100644 provider/aufe/aac/__init__.py create mode 100644 provider/aufe/aac/depends.py create mode 100644 provider/aufe/aac/model.py create mode 100644 provider/aufe/client.py create mode 100644 provider/aufe/jwc/__init__.py create mode 100644 provider/aufe/jwc/depends.py create mode 100644 provider/aufe/jwc/model.py create mode 100644 provider/aufe/labor_club/__init__.py create mode 100644 provider/aufe/labor_club/depends.py create mode 100644 provider/aufe/labor_club/model.py create mode 100644 provider/loveac/authme.py create mode 100644 provider/loveac/usersync.py create mode 100644 pyproject.toml create mode 100644 router/aac/__init__.py create mode 100644 router/aac/model.py create mode 100644 router/common_model.py create mode 100644 router/invite/__init__.py create mode 100644 router/invite/model.py create mode 100644 router/jwc/__init__.py create mode 100644 router/jwc/evaluate.py create mode 100644 router/jwc/evaluate_model.py create mode 100644 router/jwc/model.py create mode 100644 router/login/__init__.py create mode 100644 router/login/model.py create mode 100644 router/user/__init__.py create mode 100644 router/user/model.py create mode 100644 utils/__init__.py create mode 100644 utils/file_manager.py create mode 100644 utils/s3_client.py create mode 100644 yarn.lock diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1ed453a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.{js,json,yml}] +charset = utf-8 +indent_style = space +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..43c3bda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,121 @@ +# LoveAC Project .gitattributes +# 语言检测和统计配置 + +# ============================================== +# 语言检测配置 +# ============================================== + +# 主要编程语言 +*.py linguist-language=Python +*.ts linguist-language=TypeScript +*.js linguist-language=JavaScript +*.vue linguist-language=Vue + +# 配置和数据文件 +*.json linguist-language=JSON +*.yaml linguist-language=YAML +*.yml linguist-language=YAML +*.toml linguist-language=TOML +*.ini linguist-language=INI + +# 文档文件 +*.md linguist-documentation +*.rst linguist-documentation +*.txt linguist-documentation + +# 忽略自动生成的文件 +pdm.lock linguist-generated +yarn.lock linguist-generated +package-lock.json linguist-generated +.pnp.cjs linguist-generated +.pnp.loader.mjs linguist-generated + +# 忽略第三方和依赖文件 +node_modules/ linguist-vendored +__pycache__/ linguist-generated +.venv/ linguist-vendored +venv/ linguist-vendored +.idea/ linguist-vendored +.vscode/ linguist-vendored + +# 忽略构建输出 +dist/ linguist-generated +build/ linguist-generated +docs/.vitepress/dist/ linguist-generated + +# 忽略日志和缓存 +*.log linguist-generated +logs/ linguist-generated +.cache/ linguist-generated + +# 忽略自动生成的API文档 +docs/api/ linguist-generated=true +openapi.json linguist-generated + +# ============================================== +# 行结束符配置 +# ============================================== + +# 默认行为:自动检测,签出时转换为平台默认 +* text=auto + +# 强制LF行结束符的文件 +*.py text eol=lf +*.js text eol=lf +*.ts text eol=lf +*.vue text eol=lf +*.json text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.md text eol=lf +*.txt text eol=lf +*.sh text eol=lf + +# 强制CRLF行结束符的文件 +*.bat text eol=crlf +*.cmd text eol=crlf + +# 二进制文件 +*.jpg binary +*.jpeg binary +*.png binary +*.gif binary +*.ico binary +*.pdf binary +*.zip binary +*.tar.gz binary +*.db binary +*.sqlite binary +*.sqlite3 binary + +# ============================================== +# 差异查看配置 +# ============================================== + +# 图片文件使用外部工具查看差异 +*.png diff=exif +*.jpg diff=exif +*.jpeg diff=exif +*.gif diff=exif + +# 文档文件的差异配置 +*.md diff=markdown +*.rst diff=markdown + +# ============================================== +# 合并配置 +# ============================================== + +# 配置文件冲突时使用union合并策略 +*.md merge=union +CHANGELOG.md merge=union +README.md merge=union + +# ============================================== +# 过滤器配置 +# ============================================== + +# 敏感信息过滤 +config.json filter=remove-secrets +*.key filter=remove-secrets +*.pem filter=remove-secrets \ No newline at end of file diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..9ce0874 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,109 @@ +name: 部署文档 + +on: + push: + branches: + - main + paths: + - 'docs/**' + - 'openapi.json' + - 'package.json' + - 'yarn.lock' + - '.github/workflows/deploy-docs.yml' + + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages-${{ github.ref }} + cancel-in-progress: true + +jobs: + # 验证和检查作业 + validate: + runs-on: ubuntu-latest + + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: 设置Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + - name: 启用Yarn + run: corepack enable + + - name: 安装依赖 + run: yarn install --frozen-lockfile + + - name: 验证OpenAPI规范 + run: yarn swagger:validate + + - name: 检查Markdown文档 + run: yarn lint:docs + continue-on-error: true + + # 构建作业 + build: + runs-on: ubuntu-latest + needs: validate + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 设置Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + - name: 启用Yarn + run: corepack enable + + - name: 安装依赖 + run: yarn install --frozen-lockfile + + - name: 复制OpenAPI文件到public目录 + run: | + mkdir -p docs/public + cp openapi.json docs/public/ + + - name: 构建文档 + run: yarn docs:build + env: + NODE_ENV: production + + - name: 设置Pages + uses: actions/configure-pages@v4 + + - name: 上传构建产物 + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # 部署作业 + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + + steps: + - name: 部署到GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48f2146 --- /dev/null +++ b/.gitignore @@ -0,0 +1,422 @@ +# ===================================================== +# LoveAC Project .gitignore +# ===================================================== + +# ===== 敏感信息和配置文件 ===== +# 配置文件(包含数据库密码等敏感信息) +config.json +config_local.json +config_prod.json +config_dev.json +.env +.env.* +!.env.example + +# 密钥和证书文件 +*.key +*.pem +*.p12 +*.pfx +*.crt +*.cer +secrets/ +keys/ + +# ===== 日志文件 ===== +# 所有日志文件 +logs/ +*.log +*.log.* +log/ +log_* + +# ===== 数据库文件 ===== +# SQLite 数据库 +*.db +*.sqlite +*.sqlite3 + +# 数据库备份 +*.sql +*.dump +backup/ +backups/ + +# ===== 用户数据和上传文件 ===== +# 用户上传的文件 +data/ +uploads/ +media/ +static/uploads/ +user_data/ + + +# 文档和视频文件 +*.pdf +*.doc +*.docx +*.mp4 +*.avi +*.mov + +# ===== Python 相关 ===== +# 字节码文件 +__pycache__/ +*.py[cod] +*$py.class +*.so + +# 分发/打包 +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# 单元测试/覆盖率报告 +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# 虚拟环境 +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# ===== IDE 和编辑器 ===== +# VSCode +.vscode/ +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# PyCharm +.idea/ +*.swp +*.swo + +# Vim +*~ +.*.swp +.*.swo + +# Emacs +.#* + +# Sublime Text +*.sublime-project +*.sublime-workspace + +# ===== 系统文件 ===== +# macOS +.DS_Store +.AppleDouble +.LSOverride +Icon? +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Windows +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.cab +*.msi +*.msix +*.msm +*.msp +*.lnk + +# Linux +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +# ===== 临时文件和缓存 ===== +# 临时文件 +*.tmp +*.temp +*.swp +*.swo +temp/ +tmp/ +.cache/ + +# 缓存文件 +cache/ +.cache/ +*.cache + +# ===== 开发工具 ===== +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# 包管理 +# pdm +.pdm.toml +__pypackages__/ + +# Celery +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# ===== 部署相关 ===== +# Docker +.dockerignore +Dockerfile.local +docker-compose.override.yml + +# Kubernetes +*.yaml.local +*.yml.local + +# Terraform +*.tfstate +*.tfstate.* +.terraform/ +.terraform.lock.hcl + +# ===== 其他 ===== +# 压缩文件 +*.zip +*.tar.gz +*.rar +*.7z + +# 备份文件 +*.bak +*.backup +*.old +*~ + +# 测试数据 +test_data/ +mock_data/ +sample_data/ + +# 性能分析 +*.prof +*.pstats + +# 安全扫描报告 +security_report.* +vulnerability_report.* + +# ===== Node.js 相关 ===== +# npm +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Yarn v2+ +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage +.grunt + +# Bower dependency directory +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons +build/Release + +# Dependency directories +jspm_packages/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# parcel-bundler cache +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + + +# Storybook build outputs +.out +.storybook-out +storybook-static + +# Rollup.js default build output +dist/ + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# VitePress specific +docs/.vitepress/dist +docs/.vitepress/cache +.temp + +# ===== 文档相关 ===== +# 自动生成的API文档 +docs/api/*.md +!docs/api/index.md + +# VitePress构建输出 +docs/.vitepress/dist/ +docs/.vitepress/cache/ +docs/.vitepress/public/ + +# ===== 语言统计和分析 ===== +# GitHub Linguist (注意:不要忽略.gitattributes文件本身) + +# Language statistics +.linguist-* +language-stats.json +languages.json + +# Code analysis +.codeclimate.yml +.codacy.yml +sonar-project.properties +.sonarqube/ + +# Dependency analysis +dependency-check-report.* +.dependency-check/ + +# License scan +license-report.* +.license-report/ + +# Security analysis +.snyk +.github/dependabot.yml \ No newline at end of file diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..b3206ce --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,31 @@ +{ + "default": true, + "MD013": { + "line_length": 120, + "code_blocks": false, + "tables": false + }, + "MD024": { + "siblings_only": true + }, + "MD033": { + "allowed_elements": [ + "div", + "script", + "template", + "style", + "br", + "img", + "span", + "a", + "strong", + "em", + "code", + "pre" + ] + }, + "MD041": false, + "MD025": { + "front_matter_title": "^\\s*title\\s*[:=]" + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3227307 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 LoveACE Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..eba20cd --- /dev/null +++ b/README.md @@ -0,0 +1,193 @@ +# LoveACE - 财大教务自动化工具 + +
+ +LoveAC Logo + +**简化学生教务操作,提高使用效率** + +[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![Python Version](https://img.shields.io/badge/python-3.12-blue.svg)](https://python.org) +[![FastAPI](https://img.shields.io/badge/FastAPI-0.115+-green.svg)](https://fastapi.tiangolo.com) +[![Documentation](https://img.shields.io/badge/docs-VitePress-brightgreen.svg)] + + +
+ +## 🚀 项目简介 + +LoveACE 是一个面向安徽财经大学的教务系统自动化工具,专为安徽财经大学教务OA系统设计。通过RESTful API接口,提供自动评教(开发中)、课表查询、成绩查询等功能,大幅简化学生的教务操作流程。 + +### ✨ 主要特性 + +- **🔐 安全认证**: 基于邀请码的用户注册系统,确保使用安全 +- **📚 教务集成**: 深度集成教务系统,支持学业信息、培养方案查询 +- **⭐ 智能评教**: 全自动评教系统,支持任务管理和进度监控 +- **💯 积分查询**: 爱安财系统集成,实时查询积分和明细 +- **🚀 高性能**: 基于FastAPI构建,支持异步处理和高并发 +- **📖 完整文档**: 提供详细的API文档和部署指南 + +### 🛠️ 技术栈 + +- **后端框架**: [FastAPI](https://fastapi.tiangolo.com/) - 现代、快速的Python Web框架 +- **数据库**: [SQLAlchemy](https://sqlalchemy.org/) (异步) - 强大的ORM工具 +- **HTTP客户端**: 基于[aiohttp](https://aiohttp.readthedocs.io/)的自定义异步客户端 +- **日志系统**: [richuru](https://github.com/GreyElaina/richuru) - rich + loguru的完美结合 +- **文档系统**: [VitePress](https://vitepress.dev/) - 现代化的文档生成工具 + +## 📦 快速开始 + +### 前置条件 + +- **Python 3.12+** +- **PDM** +- **MySQL** 数据库 + +### 安装部署 + +```bash +# 1. 克隆项目 +git clone https://github.com/LoveACE-Team/LoveACE.git +cd LoveACE + +# 2. 安装依赖 +pdm install + +# 3. 配置环境 +python main.py +# 首次启动会生成默认配置,随后自行编辑 config.json 填写数据库配置和其他设置 + +# 4. 启动服务 +python main.py +``` + +服务启动后访问(以实际为准): +- **API服务**: http://localhost:8000 +- **API文档**: http://localhost:8000/docs + +## 📚 文档 + +### 在线文档 +访问我们的在线文档获取完整指南:**https://LoveACE-team.github.io/LoveACE** + +### 文档内容 +- **📖 快速开始**: 安装和基本使用指南 +- **⚙️ 配置指南**: 详细的配置选项说明 +- **🚀 部署指南**: 生产环境部署教程 +- **📡 API文档**: 交互式API文档 (基于OpenAPI) +- **🤝 贡献指南**: 如何参与项目开发 +- **⚖️ 免责声明**: 使用须知和免责条款 + +### 本地构建文档 + +```bash +# 安装文档依赖 +yarn install + +# 启动开发服务器 +yarn docs:dev + +# 构建静态文档 +yarn docs:build +``` + +## 🏗️ 项目结构 + +``` +LoveAC/ +├── 📁 database/ # 数据库相关代码 +│ ├── creator.py # 数据库会话管理 +│ ├── base.py # 基础模型定义 +│ └── user.py # 用户数据模型 +├── 📁 provider/ # 服务提供者 +│ ├── aufe/ # 安徽财经大学服务 +│ │ ├── client.py # 基础HTTP客户端 +│ │ ├── jwc/ # 教务系统集成 +│ │ └── aac/ # 爱安财系统集成 +│ └── loveac/ # 内部服务 +├── 📁 router/ # API路由定义 +│ ├── common_model.py # 通用响应模型 +│ ├── invite/ # 邀请码相关路由 +│ ├── login/ # 登录认证路由 +│ ├── jwc/ # 教务系统路由 +│ └── aac/ # 爱安财系统路由 +├── 📁 utils/ # 工具函数 +├── 📁 config/ # 配置管理 +├── 📁 docs/ # 项目文档 +├── 📄 main.py # 应用入口文件 +├── 📄 config.json # 配置文件 +├── 📄 openapi.json # OpenAPI规范文件(FastAPI生成) +└── 📄 pyproject.toml # 项目依赖配置 +``` + +## 🔧 配置说明 + +### 数据库配置 +```json +{ + "database": { + "url": "mysql+aiomysql://username:password@host:port/database", + "pool_size": 10, + "max_overflow": 20 + } +} +``` + +### 应用配置 +```json +{ + "app": { + "host": "0.0.0.0", + "port": 8000, + "debug": false, + "cors_allow_origins": ["*"] + } +} +``` + +完整配置选项请参考 [配置指南](https://LoveACE-team.github.io/LoveACE/config)。 + +## 🚀 部署 + +详细部署指南请参考 [部署文档](https://LoveACE-team.github.io/LoveACE/deploy)。 + +## 🤝 贡献 + +我们欢迎所有形式的贡献!在参与之前,请阅读我们的 [贡献指南](https://LoveACE-team.github.io/LoveACE/contributing)。 + +### 贡献方式 + +- 🐛 **Bug报告**: [创建Issue](https://github.com/LoveACE-Team/LoveACE/issues/new) +- 💡 **功能建议**: [发起Issue](https://github.com/LoveACE-Team/LoveACE/issues/new) +- 📝 **代码贡献**: 提交Pull Request +- 📖 **文档改进**: 帮助完善文档 + +## ⚖️ 免责声明 + +**重要提醒**: 本软件仅供学习和个人使用,请在使用前仔细阅读 [免责声明](https://LoveACE-team.github.io/LoveACE/disclaimer)。 + +- ✅ 本软件为教育目的开发的开源项目 +- ⚠️ 使用时请遵守学校相关规定和法律法规 +- 🛡️ 请妥善保管个人账户信息 +- ❌ 不得用于任何商业用途 + +## 📞 支持与联系 + +- 📧 **邮箱**: [sibuxiang@proton.me](mailto:sibuxiang@proton.me) +- 🐛 **Bug报告**: [GitHub Issues](https://github.com/LoveACE-Team/LoveACE/issues) +- 💬 **讨论交流**: [GitHub Discussions](https://github.com/LoveACE-Team/LoveACE/discussions) +- 📖 **在线文档**: [项目文档](https://LoveACE-team.github.io/LoveACE) + +## 📄 许可证 + +本项目采用 [MIT许可证](LICENSE) 开源。 + +--- + +
+ +**如果这个项目对你有帮助,请给它一个 ⭐️** + +Made with ❤️ by [Sibuxiangx](https://github.com/Sibuxiangx) + +
\ No newline at end of file diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 0000000..fad458c --- /dev/null +++ b/config/__init__.py @@ -0,0 +1,12 @@ +from .manager import config_manager, Settings +from .models import DatabaseConfig, AUFEConfig, S3Config, LogConfig, AppConfig + +__all__ = [ + "config_manager", + "Settings", + "DatabaseConfig", + "AUFEConfig", + "S3Config", + "LogConfig", + "AppConfig" +] \ No newline at end of file diff --git a/config/logger.py b/config/logger.py new file mode 100644 index 0000000..9c4e13a --- /dev/null +++ b/config/logger.py @@ -0,0 +1,68 @@ +import sys +from pathlib import Path +from richuru import install +from loguru import logger +from typing import Any, Dict + +from .manager import config_manager + + +def setup_logger(): + """根据配置文件设置loguru日志""" + install() + settings = config_manager.get_settings() + log_config = settings.log + + # 移除默认的logger配置 + logger.remove() + + # 确保日志目录存在 + log_dir = Path(log_config.file_path).parent + log_dir.mkdir(parents=True, exist_ok=True) + + # 设置控制台输出 + if log_config.console_output: + logger.add( + sys.stderr, + format=log_config.format, + level=log_config.level.value, + backtrace=log_config.backtrace, + diagnose=log_config.diagnose, + ) + + # 设置主日志文件 + logger.add( + log_config.file_path, + format=log_config.format, + level=log_config.level.value, + rotation=log_config.rotation, + retention=log_config.retention, + compression=log_config.compression, + backtrace=log_config.backtrace, + diagnose=log_config.diagnose, + ) + + # 设置额外的日志记录器 + for extra_logger in log_config.additional_loggers: + # 确保额外日志目录存在 + extra_log_dir = Path(extra_logger["file_path"]).parent + extra_log_dir.mkdir(parents=True, exist_ok=True) + + logger.add( + extra_logger["file_path"], + format=log_config.format, + level=extra_logger.get("level", log_config.level.value), + rotation=extra_logger.get("rotation", log_config.rotation), + retention=extra_logger.get("retention", log_config.retention), + compression=extra_logger.get("compression", log_config.compression), + backtrace=log_config.backtrace, + diagnose=log_config.diagnose, + filter=extra_logger.get("filter"), + ) + + logger.info("日志系统初始化完成") + + +def get_logger(): + """获取配置好的logger实例""" + return logger \ No newline at end of file diff --git a/config/manager.py b/config/manager.py new file mode 100644 index 0000000..c0402d6 --- /dev/null +++ b/config/manager.py @@ -0,0 +1,177 @@ +import json +import os +from pathlib import Path +from typing import Any, Dict, Optional +from loguru import logger +from pydantic import ValidationError + +from .models import Settings + + +class ConfigManager: + """配置文件管理器""" + + def __init__(self, config_file: str = "config.json"): + self.config_file = Path(config_file) + self._settings: Optional[Settings] = None + self._ensure_config_dir() + + def _ensure_config_dir(self): + """确保配置文件目录存在""" + self.config_file.parent.mkdir(parents=True, exist_ok=True) + + def _create_default_config(self) -> Settings: + """创建默认配置""" + logger.info("正在创建默认配置文件...") + return Settings() + + def _save_config(self, settings: Settings): + """保存配置到文件""" + try: + config_dict = settings.dict() + with open(self.config_file, 'w', encoding='utf-8') as f: + json.dump(config_dict, f, indent=2, ensure_ascii=False) + logger.info(f"配置已保存到 {self.config_file}") + except Exception as e: + logger.error(f"保存配置文件失败: {e}") + raise + + def _load_config(self) -> Settings: + """从文件加载配置""" + if not self.config_file.exists(): + logger.warning(f"配置文件 {self.config_file} 不存在,将创建默认配置") + settings = self._create_default_config() + self._save_config(settings) + return settings + + try: + with open(self.config_file, 'r', encoding='utf-8') as f: + config_data = json.load(f) + + # 验证并创建Settings对象 + settings = Settings(**config_data) + logger.info(f"成功加载配置文件: {self.config_file}") + return settings + + except json.JSONDecodeError as e: + logger.error(f"配置文件JSON格式错误: {e}") + raise + except ValidationError as e: + logger.error(f"配置文件验证失败: {e}") + raise + except Exception as e: + logger.error(f"加载配置文件失败: {e}") + raise + + def get_settings(self) -> Settings: + """获取配置设置""" + if self._settings is None: + self._settings = self._load_config() + return self._settings + + def reload_config(self) -> Settings: + """重新加载配置""" + logger.info("正在重新加载配置...") + self._settings = self._load_config() + return self._settings + + def update_config(self, **kwargs) -> Settings: + """更新配置""" + settings = self.get_settings() + + # 创建新的配置字典 + config_dict = settings.dict() + + # 更新指定的配置项 + for key, value in kwargs.items(): + if '.' in key: + # 支持嵌套键,如 'database.url' + keys = key.split('.') + current = config_dict + for k in keys[:-1]: + if k not in current: + current[k] = {} + current = current[k] + current[keys[-1]] = value + else: + config_dict[key] = value + + try: + # 验证更新后的配置 + new_settings = Settings(**config_dict) + self._save_config(new_settings) + self._settings = new_settings + logger.info("配置更新成功") + return new_settings + except ValidationError as e: + logger.error(f"配置更新失败,验证错误: {e}") + raise + + def validate_config(self) -> bool: + """验证配置完整性""" + try: + settings = self.get_settings() + + # 检查关键配置项 + issues = [] + + # 检查数据库配置 + if not settings.database.url: + issues.append("数据库URL未配置") + + # 检查S3配置(如果需要使用) + if settings.s3.bucket_name and not settings.s3.access_key_id: + issues.append("S3配置不完整:缺少access_key_id") + if settings.s3.bucket_name and not settings.s3.secret_access_key: + issues.append("S3配置不完整:缺少secret_access_key") + + # 检查日志配置 + log_dir = Path(settings.log.file_path).parent + if not log_dir.exists(): + try: + log_dir.mkdir(parents=True, exist_ok=True) + logger.info(f"创建日志目录: {log_dir}") + except Exception as e: + issues.append(f"无法创建日志目录 {log_dir}: {e}") + + if issues: + logger.warning("配置验证发现问题:") + for issue in issues: + logger.warning(f" - {issue}") + return False + + logger.info("配置验证通过") + return True + + except Exception as e: + logger.error(f"配置验证失败: {e}") + return False + + def get_config_summary(self) -> Dict[str, Any]: + """获取配置摘要(隐藏敏感信息)""" + settings = self.get_settings() + config_dict = settings.dict() + + # 隐藏敏感信息 + sensitive_keys = [ + 'database.url', + 's3.access_key_id', + 's3.secret_access_key' + ] + + def hide_sensitive(data: Dict[str, Any], keys: list, prefix: str = ""): + for key, value in data.items(): + current_key = f"{prefix}.{key}" if prefix else key + if current_key in sensitive_keys: + if isinstance(value, str) and value: + data[key] = value[:8] + "..." if len(value) > 8 else "***" + elif isinstance(value, dict): + hide_sensitive(value, keys, current_key) + + summary = config_dict.copy() + hide_sensitive(summary, sensitive_keys) + return summary + + +# 全局配置管理器实例 +config_manager = ConfigManager() \ No newline at end of file diff --git a/config/models.py b/config/models.py new file mode 100644 index 0000000..a7f7260 --- /dev/null +++ b/config/models.py @@ -0,0 +1,151 @@ +from typing import List, Dict, Any, Optional +from pydantic import BaseModel, Field, field_validator +from enum import Enum + + +class LogLevel(str, Enum): + """日志级别枚举""" + TRACE = "TRACE" + DEBUG = "DEBUG" + INFO = "INFO" + SUCCESS = "SUCCESS" + WARNING = "WARNING" + ERROR = "ERROR" + CRITICAL = "CRITICAL" + + +class DatabaseConfig(BaseModel): + """数据库配置""" + url: str = Field( + default="mysql+aiomysql://root:123456@localhost:3306/loveac", + description="数据库连接URL" + ) + echo: bool = Field(default=False, description="是否启用SQL日志") + pool_size: int = Field(default=10, description="连接池大小") + max_overflow: int = Field(default=20, description="连接池最大溢出") + pool_timeout: int = Field(default=30, description="连接池超时时间(秒)") + pool_recycle: int = Field(default=3600, description="连接回收时间(秒)") + + +class AUFEConfig(BaseModel): + """AUFE连接配置""" + default_timeout: int = Field(default=30, description="默认超时时间(秒)") + max_retries: int = Field(default=3, description="最大重试次数") + max_reconnect_retries: int = Field(default=2, description="最大重连次数") + activity_timeout: int = Field(default=300, description="活动超时时间(秒)") + monitor_interval: int = Field(default=60, description="监控间隔(秒)") + retry_base_delay: float = Field(default=1.0, description="重试基础延迟(秒)") + retry_max_delay: float = Field(default=60.0, description="重试最大延迟(秒)") + retry_exponential_base: float = Field(default=2, description="重试指数基数") + + # UAAP配置 + uaap_base_url: str = Field( + default="http://uaap-aufe-edu-cn.vpn2.aufe.edu.cn:8118/cas", + description="UAAP基础URL" + ) + uaap_login_url: str = Field( + default="http://uaap-aufe-edu-cn.vpn2.aufe.edu.cn:8118/cas/login?service=http%3A%2F%2Fjwcxk2.aufe.edu.cn%2Fj_spring_cas_security_check", + description="UAAP登录URL" + ) + + # 默认请求头 + default_headers: Dict[str, str] = Field( + default_factory=lambda: { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" + }, + description="默认请求头" + ) + + +class S3Config(BaseModel): + """S3客户端配置""" + access_key_id: str = Field(default="", description="S3访问密钥ID") + secret_access_key: str = Field(default="", description="S3秘密访问密钥") + endpoint_url: Optional[str] = Field(default=None, description="S3终端节点URL") + region_name: str = Field(default="us-east-1", description="S3区域名称") + bucket_name: str = Field(default="", description="默认存储桶名称") + use_ssl: bool = Field(default=True, description="是否使用SSL") + signature_version: str = Field(default="s3v4", description="签名版本") + + @field_validator('access_key_id', 'secret_access_key', 'bucket_name') + @classmethod + def validate_required_fields(cls, v): + """验证必填字段""" + # 允许为空,但应在运行时检查 + return v + + +class LogConfig(BaseModel): + """日志配置""" + level: LogLevel = Field(default=LogLevel.INFO, description="日志级别") + format: str = Field( + default="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}", + description="日志格式" + ) + file_path: str = Field(default="logs/app.log", description="日志文件路径") + rotation: str = Field(default="10 MB", description="日志轮转大小") + retention: str = Field(default="30 days", description="日志保留时间") + compression: str = Field(default="zip", description="日志压缩格式") + backtrace: bool = Field(default=True, description="是否启用回溯") + diagnose: bool = Field(default=True, description="是否启用诊断") + console_output: bool = Field(default=True, description="是否输出到控制台") + + # 额外的日志文件配置 + additional_loggers: List[Dict[str, Any]] = Field( + default_factory=lambda: [ + { + "file_path": "logs/debug.log", + "level": "DEBUG", + "rotation": "10 MB" + }, + { + "file_path": "logs/error.log", + "level": "ERROR", + "rotation": "10 MB" + } + ], + description="额外的日志记录器配置" + ) + + +class AppConfig(BaseModel): + """应用程序配置""" + title: str = Field(default="LoveAC API", description="应用标题") + description: str = Field(default="LoveACAPI API", description="应用描述") + version: str = Field(default="1.0.0", description="应用版本") + debug: bool = Field(default=False, description="是否启用调试模式") + + # CORS配置 + cors_allow_origins: List[str] = Field( + default_factory=lambda: ["*"], + description="允许的CORS来源" + ) + cors_allow_credentials: bool = Field(default=True, description="是否允许CORS凭据") + cors_allow_methods: List[str] = Field( + default_factory=lambda: ["*"], + description="允许的CORS方法" + ) + cors_allow_headers: List[str] = Field( + default_factory=lambda: ["*"], + description="允许的CORS头部" + ) + + # 服务器配置 + host: str = Field(default="0.0.0.0", description="服务器主机") + port: int = Field(default=8000, description="服务器端口") + workers: int = Field(default=1, description="工作进程数") + + +class Settings(BaseModel): + """主配置类""" + database: DatabaseConfig = Field(default_factory=DatabaseConfig) + aufe: AUFEConfig = Field(default_factory=AUFEConfig) + s3: S3Config = Field(default_factory=S3Config) + log: LogConfig = Field(default_factory=LogConfig) + app: AppConfig = Field(default_factory=AppConfig) + + class Config: + json_encoders = { + # 为枚举类型提供JSON编码器 + LogLevel: lambda v: v.value + } \ No newline at end of file diff --git a/database/__init__.py b/database/__init__.py new file mode 100644 index 0000000..bb60065 --- /dev/null +++ b/database/__init__.py @@ -0,0 +1,4 @@ +from .creator import db_manager, get_db_session +from .base import Base + +__all__ = ["db_manager", "get_db_session", "Base"] diff --git a/database/base.py b/database/base.py new file mode 100644 index 0000000..7d80ade --- /dev/null +++ b/database/base.py @@ -0,0 +1,6 @@ +from sqlalchemy.ext.asyncio import AsyncAttrs +from sqlalchemy.orm import DeclarativeBase + + +class Base(AsyncAttrs, DeclarativeBase): + pass diff --git a/database/creator.py b/database/creator.py new file mode 100644 index 0000000..7853628 --- /dev/null +++ b/database/creator.py @@ -0,0 +1,79 @@ +from typing import AsyncGenerator +from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker +from .base import Base +from config import config_manager +from loguru import logger + + +class DatabaseManager: + def __init__(self): + self.engine = None + self.async_session_maker = None + self._config = None + + def _get_db_config(self): + """获取数据库配置""" + if self._config is None: + self._config = config_manager.get_settings().database + return self._config + + async def init_db(self): + """初始化数据库连接""" + db_config = self._get_db_config() + + logger.info("正在初始化数据库连接...") + try: + self.engine = create_async_engine( + db_config.url, + echo=db_config.echo, + pool_size=db_config.pool_size, + max_overflow=db_config.max_overflow, + pool_timeout=db_config.pool_timeout, + pool_recycle=db_config.pool_recycle, + future=True + ) + + + self.async_session_maker = async_sessionmaker( + self.engine, class_=AsyncSession, expire_on_commit=False + ) + + # 创建所有表 + async with self.engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + except Exception as e: + logger.error(f"数据库连接初始化失败: {e}") + logger.error(f"数据库连接URL: {db_config.url}") + logger.error(f"数据库连接配置: {db_config}") + logger.error(f"请启动config_tui.py来配置数据库连接") + raise + logger.info("数据库连接初始化完成") + + async def close_db(self): + """关闭数据库连接""" + if self.engine: + logger.info("正在关闭数据库连接...") + await self.engine.dispose() + logger.info("数据库连接已关闭") + + async def get_session(self) -> AsyncGenerator[AsyncSession, None]: + """获取数据库会话""" + if not self.async_session_maker: + raise RuntimeError("Database not initialized. Call init_db() first.") + + async with self.async_session_maker() as session: + try: + yield session + finally: + await session.close() + + +# 全局数据库管理器实例 +db_manager = DatabaseManager() + + +# FastAPI 依赖函数 +async def get_db_session() -> AsyncGenerator[AsyncSession, None]: + """获取数据库会话的依赖函数,用于FastAPI路由""" + async for session in db_manager.get_session(): + yield session diff --git a/database/train_plan.py b/database/train_plan.py new file mode 100644 index 0000000..e69de29 diff --git a/database/user.py b/database/user.py new file mode 100644 index 0000000..6acc422 --- /dev/null +++ b/database/user.py @@ -0,0 +1,52 @@ +import datetime +from typing import Optional + +from sqlalchemy import func, String, Text +from sqlalchemy.orm import Mapped +from sqlalchemy.orm import mapped_column +from database.base import Base + + +class User(Base): + __tablename__ = "user_table" + id: Mapped[int] = mapped_column(primary_key=True) + userid: Mapped[str] = mapped_column(String(100), unique=True, nullable=False) + password: Mapped[str] = mapped_column(String(255), nullable=False) + easyconnect_password: Mapped[str] = mapped_column(String(255), nullable=False) + create_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now()) + + +class UserProfile(Base): + __tablename__ = "user_profile_table" + id: Mapped[int] = mapped_column(primary_key=True) + userid: Mapped[str] = mapped_column(String(100), unique=True, nullable=False) + avatar_filename: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, comment="用户头像文件名") + background_filename: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, comment="用户背景文件名") + nickname: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="用户昵称") + settings_filename: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, comment="用户设置文件名") + create_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now()) + update_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now(), onupdate=func.now()) + + +class Invite(Base): + __tablename__ = "invite_table" + id: Mapped[int] = mapped_column(primary_key=True) + invite_code: Mapped[str] = mapped_column(String(50), unique=True, nullable=False) + create_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now()) + + +class AuthME(Base): + __tablename__ = "authme_table" + id: Mapped[int] = mapped_column(primary_key=True) + userid: Mapped[str] = mapped_column(String(100), nullable=False, index=True) + authme_token: Mapped[str] = mapped_column(String(500), unique=True, nullable=False) + device_id: Mapped[str] = mapped_column(String(100), nullable=False, comment="设备/会话标识符") + create_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now()) + + +class AACTicket(Base): + __tablename__ = "aac_ticket_table" + id: Mapped[int] = mapped_column(primary_key=True) + userid: Mapped[str] = mapped_column(String(100), unique=True, nullable=False) + aac_token: Mapped[str] = mapped_column(String(500), nullable=False) + create_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now()) diff --git a/docs/.vitepress/components/SwaggerUI.vue b/docs/.vitepress/components/SwaggerUI.vue new file mode 100644 index 0000000..48ba291 --- /dev/null +++ b/docs/.vitepress/components/SwaggerUI.vue @@ -0,0 +1,200 @@ + + + + + \ No newline at end of file diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000..c101b63 --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,75 @@ +import { defineConfig } from 'vitepress' + +export default defineConfig({ + title: 'LoveACE', + description: '教务系统自动化工具', + lang: 'zh-CN', + + themeConfig: { + logo: '/images/logo.jpg', + + nav: [ + { text: '首页', link: '/' }, + { text: 'API文档', link: '/api/' }, + { text: '配置', link: '/config' }, + { text: '部署', link: '/deploy' }, + { text: '贡献', link: '/contributing' } + ], + + sidebar: { + '/': [ + { + text: '指南', + items: [ + { text: '介绍', link: '/' }, + { text: '快速开始', link: '/getting-started' }, + { text: '配置', link: '/config' }, + { text: '部署指南', link: '/deploy' } + ] + }, + { + text: 'API文档', + items: [ + { text: 'API交互式文档', link: '/api/' } + ] + }, + { + text: '其他', + items: [ + { text: '贡献指南', link: '/contributing' }, + { text: '免责声明', link: '/disclaimer' } + ] + } + ] + }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/LoveACE-Team/LoveACE' } + ], + + footer: { + message: '基于 MIT 许可发布', + copyright: 'Copyright © 2025 LoveACE' + }, + + search: { + provider: 'local' + }, + + lastUpdated: { + text: '最后更新于', + formatOptions: { + dateStyle: 'short', + timeStyle: 'medium' + } + } + }, + + head: [ + ['link', { rel: 'icon', href: '/images/logo.jpg' }] + ], + + markdown: { + lineNumbers: true + } +}) \ No newline at end of file diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 0000000..1ae6ce1 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,29 @@ +/* 自定义样式文件 */ + +/* 确保SwaggerUI容器有足够的高度 */ +.swagger-container { + min-height: 600px; + width: 100%; +} + +/* SwaggerUI组件的容器样式 */ +.api-docs-container { + background: var(--vp-c-bg); + border-radius: 8px; + padding: 20px; + margin: 20px 0; +} + +/* 为API文档页面添加特殊样式 */ +.api-page .content-container { + max-width: none !important; + padding: 0 !important; +} + +/* 响应式调整 */ +@media (max-width: 960px) { + .api-docs-container { + padding: 10px; + margin: 10px 0; + } +} \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..2a3ff9e --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,17 @@ +import { h } from 'vue' +import DefaultTheme from 'vitepress/theme' +import SwaggerUI from '../components/SwaggerUI.vue' +import './custom.css' + +export default { + extends: DefaultTheme, + Layout: () => { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + }) + }, + enhanceApp({ app, router, siteData }) { + // 注册全局组件 + app.component('SwaggerUI', SwaggerUI) + } +} \ No newline at end of file diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000..fbd2b43 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,18 @@ +--- +layout: page +title: LoveACE API 文档 +description: 基于 OpenAPI 3.1 规范的交互式 API 文档 +--- + + + +
+ +
\ No newline at end of file diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000..8e5799a --- /dev/null +++ b/docs/config.md @@ -0,0 +1,232 @@ +# 配置指南 + +LoveACE使用JSON格式的配置文件来管理各种设置。本文档详细介绍了所有可用的配置选项。 + +## 配置文件位置 + +配置文件应位于项目根目录下,命名为`config.json`。您可以从`config.example.json`复制并修改。 + +## 完整配置示例 + +```json +{ + "database": { + "url": "mysql+aiomysql://username:password@host:port/database", + "echo": false, + "pool_size": 10, + "max_overflow": 20, + "pool_timeout": 30, + "pool_recycle": 3600 + }, + "aufe": { + "default_timeout": 30, + "max_retries": 3, + "max_reconnect_retries": 2, + "activity_timeout": 300, + "monitor_interval": 60, + "retry_base_delay": 1.0, + "retry_max_delay": 60.0, + "retry_exponential_base": 2.0, + "uaap_base_url": "http://uaap-aufe-edu-cn.vpn2.aufe.edu.cn:8118/cas", + "uaap_login_url": "http://uaap-aufe-edu-cn.vpn2.aufe.edu.cn:8118/cas/login?service=http%3A%2F%2Fjwcxk2.aufe.edu.cn%2Fj_spring_cas_security_check", + "default_headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" + } + }, + "s3": { + "access_key_id": "YOUR_ACCESS_KEY_ID", + "secret_access_key": "YOUR_SECRET_ACCESS_KEY", + "endpoint_url": null, + "region_name": "us-east-1", + "bucket_name": "YOUR_BUCKET_NAME", + "use_ssl": true, + "signature_version": "s3v4" + }, + "log": { + "level": "INFO", + "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}", + "file_path": "logs/app.log", + "rotation": "10 MB", + "retention": "30 days", + "compression": "zip", + "backtrace": true, + "diagnose": true, + "console_output": true, + "additional_loggers": [ + { + "file_path": "logs/debug.log", + "level": "DEBUG", + "rotation": "10 MB" + }, + { + "file_path": "logs/error.log", + "level": "ERROR", + "rotation": "10 MB" + } + ] + }, + "app": { + "title": "LoveAC API", + "description": "LoveACAPI API", + "version": "1.0.0", + "debug": false, + "cors_allow_origins": ["*"], + "cors_allow_credentials": true, + "cors_allow_methods": ["*"], + "cors_allow_headers": ["*"], + "host": "0.0.0.0", + "port": 8000, + "workers": 1 + } +} +``` + +## 配置项详解 + +### 数据库配置 (database) + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `url` | string | - | 数据库连接URL,支持MySQL、SQLite等 | +| `echo` | boolean | false | 是否打印SQL语句到日志 | +| `pool_size` | integer | 10 | 连接池大小 | +| `max_overflow` | integer | 20 | 连接池最大溢出数量 | +| `pool_timeout` | integer | 30 | 获取连接超时时间(秒) | +| `pool_recycle` | integer | 3600 | 连接回收时间(秒) | + +#### 数据库URL格式 + +**MySQL**: +``` +mysql+aiomysql://用户名:密码@主机:端口/数据库名 +``` + +**SQLite**: +``` +sqlite+aiosqlite:///path/to/database.db +``` + +### AUFE配置 (aufe) + +安徽财经大学教务系统相关配置。 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `default_timeout` | integer | 30 | 默认请求超时时间(秒) | +| `max_retries` | integer | 3 | 最大重试次数 | +| `max_reconnect_retries` | integer | 2 | 最大重连次数 | +| `activity_timeout` | integer | 300 | 活动超时时间(秒) | +| `monitor_interval` | integer | 60 | 监控间隔(秒) | +| `retry_base_delay` | float | 1.0 | 重试基础延迟(秒) | +| `retry_max_delay` | float | 60.0 | 重试最大延迟(秒) | +| `retry_exponential_base` | float | 2.0 | 重试指数基数 | +| `uaap_base_url` | string | - | UAAP基础URL | +| `uaap_login_url` | string | - | UAAP登录URL | +| `default_headers` | object | - | 默认HTTP请求头 | + +### S3存储配置 (s3) + +用于文件存储的S3兼容服务配置。 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `access_key_id` | string | - | S3访问密钥ID | +| `secret_access_key` | string | - | S3访问密钥 | +| `endpoint_url` | string | null | 自定义端点URL(用于S3兼容服务) | +| `region_name` | string | us-east-1 | 区域名称 | +| `bucket_name` | string | - | 存储桶名称 | +| `use_ssl` | boolean | true | 是否使用SSL | +| `signature_version` | string | s3v4 | 签名版本 | + +### 日志配置 (log) + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `level` | string | INFO | 日志级别 | +| `format` | string | - | 日志格式 | +| `file_path` | string | logs/app.log | 主日志文件路径 | +| `rotation` | string | 10 MB | 日志轮转大小 | +| `retention` | string | 30 days | 日志保留时间 | +| `compression` | string | zip | 压缩格式 | +| `backtrace` | boolean | true | 是否包含回溯信息 | +| `diagnose` | boolean | true | 是否包含诊断信息 | +| `console_output` | boolean | true | 是否输出到控制台 | +| `additional_loggers` | array | - | 额外的日志记录器配置 | + +#### 日志级别 + +- `DEBUG`: 调试信息 +- `INFO`: 一般信息 +- `WARNING`: 警告信息 +- `ERROR`: 错误信息 +- `CRITICAL`: 严重错误 + +### 应用配置 (app) + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `title` | string | LoveAC API | 应用标题 | +| `description` | string | - | 应用描述 | +| `version` | string | 1.0.0 | 应用版本 | +| `debug` | boolean | false | 是否启用调试模式 | +| `cors_allow_origins` | array | ["*"] | 允许的CORS源 | +| `cors_allow_credentials` | boolean | true | 是否允许携带凭证 | +| `cors_allow_methods` | array | ["*"] | 允许的HTTP方法 | +| `cors_allow_headers` | array | ["*"] | 允许的HTTP头 | +| `host` | string | 0.0.0.0 | 绑定主机 | +| `port` | integer | 8000 | 绑定端口 | +| `workers` | integer | 1 | 工作进程数 | + +## 环境特定配置 + +### 开发环境 + +```json +{ + "app": { + "debug": true, + "workers": 1 + }, + "log": { + "level": "DEBUG", + "console_output": true + }, + "database": { + "echo": true + } +} +``` + +### 生产环境 + +```json +{ + "app": { + "debug": false, + "workers": 4, + "cors_allow_origins": ["https://yourdomain.com"] + }, + "log": { + "level": "INFO", + "console_output": false + }, + "database": { + "echo": false, + "pool_size": 20 + } +} +``` + +## 配置验证 + +启动应用时,系统会自动验证配置文件的格式和必需参数。如果配置有误,应用将无法启动并显示相应的错误信息。 + +## 动态配置 + +某些配置项支持运行时修改,无需重启服务: + +- 日志级别 +- CORS设置 +- 部分AUFE配置 + +动态配置修改可通过管理API进行(需要管理员权限)。 \ No newline at end of file diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..63bdf65 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,5 @@ +# 贡献指南 + +感谢您对LoveACE项目的关注!我们欢迎所有形式的贡献,包括但不限于代码贡献、文档改进、问题报告和功能建议。 + +## In Progress \ No newline at end of file diff --git a/docs/deploy.md b/docs/deploy.md new file mode 100644 index 0000000..c3abe01 --- /dev/null +++ b/docs/deploy.md @@ -0,0 +1,5 @@ +# 部署指南 + +本指南介绍如何在生产环境中部署LoveACE教务系统自动化工具。 + +## In Progress \ No newline at end of file diff --git a/docs/disclaimer.md b/docs/disclaimer.md new file mode 100644 index 0000000..bb4d177 --- /dev/null +++ b/docs/disclaimer.md @@ -0,0 +1,119 @@ +# 免责声明 + +## 重要声明 + +**请在使用LoveACE(以下简称"本软件")之前仔细阅读本免责声明。使用本软件即表示您已阅读、理解并同意接受本声明的所有条款。** + +## 软件性质与用途 + +1. **教育目的**: 本软件是为教育和学习目的而开发的开源项目,旨在帮助学生简化教务系统操作流程。 + +2. **个人使用**: 本软件仅供个人学习和使用,不得用于任何商业目的。 + +3. **实验性质**: 本软件处于开发阶段,可能存在功能不完善、数据不准确等问题。 + +## 使用风险与责任 + +### 用户责任 + +1. **合规使用**: 用户有责任确保使用本软件的行为符合所在地区的法律法规以及学校的相关规定。 + +2. **账户安全**: 用户应妥善保管自己的账户信息,因账户信息泄露造成的损失由用户自行承担。 + +3. **数据备份**: 用户应自行备份重要数据,开发者不对数据丢失承担责任。 + +4. **风险评估**: 用户在使用本软件前应充分评估可能的风险,并自行决定是否使用。 + +### 开发者免责 + +1. **不保证性**: 开发者不保证本软件的功能完整性、准确性、可靠性或及时性。 + +2. **服务中断**: 开发者不对因软件故障、网络问题、服务器维护等原因导致的服务中断承担责任。 + +3. **数据损失**: 开发者不对使用本软件过程中可能出现的数据丢失、损坏或泄露承担责任。 + +4. **第三方影响**: 开发者不对因第三方服务(如学校教务系统)变更而导致的软件功能异常承担责任。 + +## 技术限制 + +1. **兼容性**: 本软件可能无法与所有系统环境兼容,用户应在支持的环境中使用。 + +2. **性能表现**: 软件的性能表现可能因硬件配置、网络环境等因素而有所差异。 + +3. **功能限制**: 本软件的功能可能受到目标系统的限制,某些功能可能无法正常使用。 + +## 隐私与数据安全 + +1. **数据收集**: 本软件可能收集必要的用户数据以提供服务,但不会收集与服务无关的个人信息。 + +2. **数据存储**: 用户数据存储在用户自行配置的数据库中,开发者不保存用户的敏感信息。 + +3. **数据传输**: 数据传输过程中可能存在被截获的风险,用户应采取适当的安全措施。 + +4. **第三方访问**: 开发者承诺不会主动向第三方泄露用户数据,但不能保证在所有情况下数据的绝对安全。 + +## 法律合规 + +1. **遵守法律**: 用户使用本软件时应遵守所在地区的相关法律法规。 + +2. **学校规定**: 用户应确保使用本软件的行为符合所在学校(此处指安徽财经大学)的规章制度(详阅最新版安徽财经大学本科生学生手册)。 + +3. **禁止行为**: + - 不得使用本软件进行任何违法活动 + - 不得利用本软件进行恶意攻击或破坏行为 + - 不得将本软件用于商业目的 + - 不得传播或分享他人的账户信息 + +## 知识产权 + +1. **开源许可**: 本软件基于MIT许可证开源,用户应遵守相关许可条款。 + +2. **版权声明**: 本软件的版权归原作者所有,未经授权不得用于商业用途。 + +3. **商标权**: 涉及的第三方商标权归其所有者所有,本软件的使用不代表对这些商标的任何权利主张。 + +## 服务变更与终止 + +1. **功能变更**: 开发者保留随时修改、升级或终止软件功能的权利,恕不另行通知。 + +2. **服务终止**: 开发者可能因技术、法律或其他原因终止软件服务,用户应提前做好数据备份。 + +3. **协议更新**: 本免责声明可能随时更新,建议用户定期查看最新版本。 + +## 争议解决 + +1. **友好协商**: 因使用本软件产生的争议,双方应首先通过友好协商解决。 + +2. **法律途径**: 如协商无果,争议应按照开发者所在地的法律法规通过法律途径解决。 + +## 紧急情况处理 + +如果在使用过程中遇到以下情况,请立即停止使用: + +1. 收到学校或相关部门的警告 +2. 发现账户异常或疑似被盗用 +3. 软件出现严重错误或异常行为 +4. 怀疑数据泄露或安全问题 + +## 联系方式 + +如果您对本免责声明有任何疑问,或在使用过程中遇到问题,请通过以下方式联系: + +- **邮箱**: sibuxiang@proton.me +- **GitHub Issues**: [https://github.com/LoveACE-Team/LoveACE/issues](https://github.com/LoveACE-Team/LoveACE/issues) + +## 最终条款 + +1. **完整协议**: 本免责声明构成完整的协议,取代之前的所有口头或书面协议。 + +2. **协议效力**: 如本协议的任何条款被认定为无效或不可执行,其余条款仍然有效。 + +3. **生效时间**: 本免责声明自用户首次使用本软件时生效。 + +--- + +**最后更新时间**: 2025/8/3 + +**版本**: v1.0 + +**请注意**: 本免责声明可能会不定期更新,继续使用本软件即表示您接受更新后的条款。 \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..d7c7e5f --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,123 @@ +# 快速开始 + +本指南将帮助您快速设置并运行LoveACE教务系统自动化工具。 + +## 前置条件 + +在开始之前,请确保您的系统已安装: + +- **Python 3.12** +- **PDM** (Python Dependency Manager) +- **MySQL** 或其他支持的数据库 + +## 安装步骤 + +### 1. 克隆项目 + +```bash +git clone https://github.com/LoveACE-Team/LoveACE.git +cd LoveACE +``` + +### 2. 安装依赖 + +使用PDM安装项目依赖: + +```bash +pdm install +``` + +### 3. 配置环境 + +启动 App 生成配置文件并编辑: + +```bash +python main.py +``` + +编辑`config.json`文件,配置以下关键参数: + +```json +{ + "database": { + "url": "mysql+aiomysql://username:password@host:port/database" + }, + "app": { + "host": "0.0.0.0", + "port": 8000 + } +} +``` + +### 4. 初始化数据库 + +项目会在首次运行时自动创建数据库表结构。 + +### 5. 启动服务 + +```bash +python main.py --reload +``` + +服务启动后,您可以访问: + +- **API服务**: http://localhost:8000 +- **API文档**: http://localhost:8000/docs +- **Redoc文档**: http://localhost:8000/redoc + +## 验证安装 + +访问健康检查接口验证服务是否正常运行: + +```bash +curl http://localhost:8000/health +``` + +如果一切正常,您应该看到类似以下的响应: + +```json +{ + "code": 200, + "message": "服务运行正常", + "data": { + "status": "healthy", + "timestamp": "2024-01-01T12:00:00Z" + } +} +``` + +## 下一步 + +- 查看 [配置指南](/config) 了解详细配置选项 +- 阅读 [API文档](/api/) 了解可用接口 +- 参考 [部署指南](/deploy) 进行生产环境部署 + +## 常见问题 + +### 数据库连接失败 + +检查`config.json`中的数据库配置是否正确,确保: +- 数据库服务已启动 +- 用户名密码正确 +- 网络连接正常 + +### 端口被占用 + +如果8000端口被占用,可以在配置文件中修改端口: + +```json +{ + "app": { + "port": 8080 + } +} +``` + +### 依赖安装失败 + +确保使用Python 3.12,并尝试清理缓存: + +```bash +pdm cache clear +pdm install +``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..2ee4572 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,91 @@ +--- +layout: home + +hero: + name: "LoveACE" + text: "教务系统自动化工具" + tagline: "简化学生教务操作,提高使用效率" + image: + src: /images/logo.jpg + alt: LoveACE Logo + actions: + - theme: brand + text: 快速开始 + link: /getting-started + - theme: alt + text: API文档 + link: /api/ + +features: + - icon: 🔐 + title: 用户认证与授权 + details: 支持邀请码注册和用户登录,确保系统安全 + - icon: 📚 + title: 教务系统集成 + details: 学业信息查询、培养方案信息查询、课程列表查询 + - icon: ⭐ + title: 自动评教系统(开发中) + details: 支持评教任务的初始化、开始、暂停、终止和状态查询 + - icon: 💯 + title: 爱安财系统 + details: 总分信息查询和分数明细列表查询 + - icon: 🚀 + title: 高性能架构 + details: 基于FastAPI和异步SQLAlchemy构建,支持高并发访问 + - icon: 📖 + title: 完整文档 + details: 提供详细的API文档、配置指南和部署教程 +--- + +## 技术栈 + +- **后端框架**: FastAPI +- **数据库ORM**: SQLAlchemy (异步) +- **HTTP客户端**: 基于aiohttp的自定义客户端 +- **日志系统**: richuru (rich + loguru) + +## 快速体验 + +```bash +# 克隆项目 +git clone https://github.com/LoveACE-Team/LoveACE.git +cd LoveACE + +# 安装依赖 +pdm install + +# 配置数据库 +启动 App 生成配置文件并编辑: + +```bash +python main.py +``` + +编辑`config.json`文件,配置以下关键参数: + +```json +{ + "database": { + "url": "mysql+aiomysql://username:password@host:port/database" + }, + "app": { + "host": "0.0.0.0", + "port": 8000 + } +} + +# 启动服务 +uvicorn main:app --reload +``` + +## 社区 + +如果您有任何问题或建议,欢迎: + +- 📝 [提交Issue](https://github.com/LoveACE-Team/LoveACE/issues) +- 🔀 [发起Pull Request](https://github.com/LoveACE-Team/LoveACE/pulls) +- 💬 加入讨论组 + +## 许可证 + +本项目采用 MIT 许可证开源。详情请查看 [LICENSE](https://github.com/LoveACE-Team/LoveACE/blob/main/LICENSE) 文件。 \ No newline at end of file diff --git a/docs/public/images/logo.jpg b/docs/public/images/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0c6e832e5f826d36cb28ede8e805c8b512f3c281 GIT binary patch literal 11122 zcmc(F2UJtt7Um713n)!Nz@VTs5$R0`pmdcEQdN49E+8NTP*9PM6p<2Xf)wdNiV+o1 zO6VX2L=70}y#zus7yZ?L-ps7`&wI1hWUWJTN$$C4pS$zY8q-P zS{fP}Iyzc<1~x{90|yv5Sy&IU@f?L6<2lOB&C7pAfcL~{K5lM7S)tQs#igXAU;^?= zauVmxNJ>dS=;-Je4lr;qGIB^9=RPj+fBhoA2AF9f36KORy&x1&N-Am^S~~gzhX4u)6iPt}rJ|yw1b-O^k)a;76 zg`K^Fqm#3XtM5%e|A1S8L3i#(M%}yrAUY}eQA%oB`s0k;y!?W~XGO)&tEy{i>rnMC z8{WKq*V@+p{zFIqz~IpE$j8yKFJEy})8FvlXJ%Jc*VZ>Sx3&p85CHnq9PsZ?gZ^d@ zGiVP5B_))SX5StNMF2RU%#>8e#i?0T4QQ@=v!0L$r)5)1d|KH;$0upH%x>$`M}L@K z>dVQMeUpAz^v?{6_>V05ZP0If$YTHl6awBbC^G;DHeCgC!|4CNjw0KJC`S>lsqoBe zy_8AtG}c#=wc4$!E&-cmWZ=|9{ZdBpx%j<;=_U8bN9;WuatjvPM>VtVmt@y-AZbi= zOD3yzSUV?DFuu{%{0~`<_(t+vvcKBRJy4=C3h^Eo@1>fvoUG|E>cmE3d^1qy{*|?l z3U$LP=@)3^@yk0Vt*=o2^i@8WX*!%KTGhS95~12CfAO}ES&O$XQ_o8k+1obuP_7Jz zi6UIdzyORGOa{t~#y;&88fM#!GvMWmYQEgG|MCiefoUF z4B;@k>M@bMo!hUs&Yq+p03_)tbsG)}MEk;0v6Y$2Aw?8jNAKk*v`@SDgbevti9Wr> zulwN04HbKoO&%F|VTP^|Mc`kM6cBI1PWP#^0S5o&Fu8Rahw}N}rOh!l6rJbfbh4>+ z;!#BX=M3NloEUj;cWzI_qRNR3Bvg=r5JZ8SK9w68*j`OuCfQcH`F}f=F_C8ok(=8n zB?I#>$v`vg+y2UCb5`cjOYu`~GLs}_TQYDPp^)?yqkEHST1$YNRsTeqpK44c;25SL z{JNeD#6Lz%!ZEd{%WSY+pNtpV#J7j7+ljY3Nd(eONI?M^Xs<@RLL`)C4EK`(+$eey z{@(Nw;HF9jc#}yugvE!lU=y)IN*?no411SMNS!&meIzHMAVn7$Sfzt4imjJs)Jos2 zcxUgZM)OqKG)zH3I5sOYb?t~xK6^Xm&@3RB8~tC87fLlww_E5QF%(m7K;wi`#k_Wj z%j0&ORwfOCKyI`kMPY8t<}9-=&mPcYXTGd@w*G#4CV&%g*(hreSD`X&td9SXq=h?W z=-Z|j)Tj>FUGO|^SeYNjnt6i^%o&v~$aY;=k(p?2;r>?p9ZB7O^j-L&>zb;U!KJ?l zD&35GPA9+($^KfU+yf`BB$EizXmxV(y2+H0M*47$q$4BiqwI_FQIk9JA4i5>&a=7&hhmq3pmzd1(9lVDGN1%s86dHR{91#^2@^U=B!>MyXNkYR_qdw%XgFgWBj7s7V%@^}DBvwq z9`&8No#SgcL-8$kya5qZ8sE#v_c z%Z1I!wE;4~1OH-RW25bP_5!`C)v9nx<^gYU&C`I@$_5*x5LGwdVtO&jOWDX&gvtK! zh`oR!EnmQAH;s;&#oOIqH1?+jlwPSh=~DXWA#;MUH>bG`fJi`i3k{j@Q^|Ve0MU2OS6nf z%4T~#v(6Mvhm_tvQiDLx4b|0Kx;fT*wW;Jg1o?u2Qs{zMS)W{leG@|UX?aX}bFt$x zy?gbkbcSVPH!{8d#b z?7c~>2+0!h8c}A328|kpADj|y1NTl8{TV(SCS>)$EVKJJ_SV$&Y;SsQ^{lc%EOo(i z3(0^N84x#^1TQk5b8nUXR2q1VOQbI(+q_?M3qn#iU-&j&H$ZVtm^wA+RdL;r*??%b zbHhlriaKNiG(>l2ur8f!G4_lYEVfGqdV8te z(Zt)Wq-~NP`pRK&=hlww;t0cgfPD)YIPMQ-9(0+T=|$M;5zj5`&T#EN0yg$Pz~yFi zOmKV}XR4g<7$zx&-X?f%9b9A21O4R~7%=sS6!{aeOomcM1H87GD!dU8nj$F(X1MoZ z&p^KtHsHise1Y!fEjT^~vGx907yvLpUQ>jfT`VJY3tqxjNoLySH#F~FR6W;RFOTuH z=wb8lS;>PLN^1W)2g$IjD>}zUa+Jr2e|IxXG%-*s0+?PK_EJ;*mFD~k3K2h(T*)a~ zZT@$6v$chV-rv7N`&1JN7B!|Pf4Pw5&9*23+in(drH*LeX#t}1>h{5nGGSMZM7*sq zzMNWU5Mnsnxgc?GP3E&5N4MkHcu0oYZh*ZVXRF5`!s!m_Ry&xDqk*=7U6YS;qs?I( z?XH70wYxH8Ajf~+zg36#?x70?5ekQL^N|b(;M|?=9dvY9AscA@$yYg4nGEk z&oRB!l%CV?U&Ji%etkg({uE+nuX<>REAb=(TS)dn0uHvfDo9b*TohzbDE0Q46B2!sA#6bJt|a|o5saCBA}%w856()|NYK$XDV1j-`q?@;=rm)|El zQ(&B9ufNubo_RHZp2DJd)>ICw@PB5=Fr?2sq&b{Jvorn7iVT#(bbzR6K_tbm@kq!c zEC-oiav0sJ!oI_8a5;I;F65FS=)Y3o=bA@3G4uMAWWf0jDOeMXI{KihhDAf#4eFO; zV_^LkF9?FbH)o1&HUkx^|7Q3uoQ^xYs>oC?Al+*wuR!WOUG%0w!@TUz)J*0DBR-elt1Hy6my=y!Alu~~yZP;x`wx2g&sU-;m4~@B`2-eD` zxWtxOkta@0^8SuW5|`cbhtN};vR}x+Q~GbtK=DFB!X*|u?lUWGxVTy>ZBNiFal|Wl z7U22cmei&UKQa?CJlid(>SoVA(!h(5v|k=P9ef&lpI;|SIk&D>k<;_`3!#J?m;lyE z*cXGc8d0C5Du*p-X7*6A3NyCNwk}$x&43~^nEveu0=EI5OD8!#$Ib5 z>V5uM6MzAi86xa%@s;ag{;iX7CbSU2mMEVPL5is(iQ`%Z?BURJ(Us;3SBW9AyY~pu zsk3f1S;Xc~SHAn(-`vrsj%CkrxYhG5aPqDRY37CZ(Yn_o8jHqqo1-&V7(U69tZ#vjl&?qTaa94628zG=Z{_8d;~14gM^ zv76MhhnbWN=+4fb>@WW`ljh$L+fD3Us9Uo}Ez(42aYM7erWYPaY!ZGY_u=Xal6Jul zU9EFXun&;dESC`dyy zPGsB6XX52R_^d_D#FLcBz;G$}z0c&0W*eEnn3B1;2-N!S!3si7(^+E9`D3CGh>G2$G+3%PvI1pQDOOy2&yrgkIj9S!ikwzdVmW@f_i*xA&0@@R6i-qJh-Fv9BtN0Iywi&EJs%w=baiLB0X&rfXbZQ`ayKXnxacL9JzIB&!mHruZv7(9Nx$jIO^v%c_k z4Qf?z`Nish`zU7QP?{Gqs-4~TWk;oxf@PO=3vam`lCeQJ!&SfWIo0h-zzg11t`AXX z`)9-0lfOYbEKGT#>5F8KbWk*a7c3K-f3X9CcO1CovoR}ytTn+XyH|n~3jd-piR?vT zNr51JX(zgtc6)owCzPDl9hiPkoYTqMuTujNL+> zk2WXEoosEM*#%8d?QuW-u_raMGSdkvt*bi(uW6bbCxqI-ANu>|T%S=n`uDu^Z|U{V zT8$+*g*rzaaGEqv8=bn4$B8*BBK;_j{dxow<4u#SK&PYX{9m5<`^Kz%Kr)Q|+LiG> zWR#_*%Zb>YbPaRWc@d^^3s)oacXqLMymd?Iu$4_D<0V}^7R#bqRE#n)3n|7S-80d` z?{@l3eX#x7SY1eDyvfRxcDXO-d zBf)fTvbOuucOUSGt-ceXh->!V8f$KQO3^BOflX$57%!)ZuzTt>bap&^XC;B!d!{(Y?!S#OcJQ?)r~3H+FJ@ur(v1FU}a!;?gCZ zsKVNz%C#T5J*7C-o+h1J|CH~vR-U7a8en(NkImgROQoZ*s`FoK3$1}v{yUU4el|cP zjOodG1iP2i=u>-cn(fJecL}kxj&MK>coIR$=Y`Ryg13ZF)$1{M#%PRLgUjuw{7+Uj zWOwwbUi`t~IfZh<(R-yiTWjDMCbrSq>7{N-)Indvc=wUkWglq^mQloJFiXKVUHfGM z`=?^w6#8;O5+t*|yZ5=?$u&d`-1i&KX~l`N=i*K@@V%&XX<gFV2 z8(bV0Q4pHbyFeNUnrZal6OiliwlHd)y4;8NSHz7apC9m;U$W8u`Y}oZxk!^4e}2L8 zh`7e}lrCq>>+-^q{bAz!%t_eI5&;VK{-C%Sil6U@5tnp5GG%)q;;rkVSZ@gTF zviExVtC!e0uEeq@IM|MYf}--5H$|Lsb03G}Hy59P(GA>fLxSk2@H!?siU^9Txn=XK!_J;R`!`|5U)|?Oc zxHF;wfn0F*2y zKxee?JH4#U%ECTa+-}7j{ecYJb?qbtfyfhbaJei)5XwbjE)gTl!S~kTZ)#58upRg; zegV^A8Guohe+}y|?NgyL$#^4FAR#Fy&>O#8Vq*Ap=0I~DS1==T^8;)z2#E09PQ`s7 zG+`PEGwVBpo0~<}XR5FtJ^1RhKnC3B;JS(3N>Qwg36=H;qkj?XwYhvxB|o)Y+P2vB zN7IE2oL8ZvJm6ck@PUOjQ|vMmyujx9Fl=QSh9h>H{~%Bd1Y2vR3l&LSm-}Ifam}w% zJjP5jChV_4tDKOuUTf( zc0>i{P&IgIlO91(UtSQX!JV*ne8q=mWdOk4*vL~YU&l-xD6uU^M z`L*|#ncmjpW(dY3W@yJp0%?sRnTxGIge=3KLKfgQRuk(HWwj)a(NG*5da_qS1}-92 zmPoa*G4whZ+Q-0+(x*;g|37{MY8T9%-V7XTg>gy~vK5@fxx-v@U!EsRR#bfY=&!=+ zsTg`AL~&@sNQX4AiVm431d_P%a$B3l0u^gDPwl?pXiLzZg^EsNVWR3%MncZ{+HBko z9LyOZh6AVJ)nyql*{;r1%(y>vWURdRXYtH#IJ-69Pr15f@1$6%aEv1JiAHXQ zl{;3g3*9?c6^WnAnQm9ML&s2v-^A_t5%c6OJjdVBMpc2Mi`qK2@$84V+9+*4tEoo}Ns#7(|| zPgO-wbo5uwwW)6I^tsCL_Gv4Ju2oC7Bdlszd-EI`V2iKWb=$IRga{=Aj-~E@{0zwy zuQfzj7dL`3pgZ@5decPi^#WnIHE`N*%&~ee&!?Ag%w|w5i?B%ZtQm0qC#p?bw5{d(ZTw| zBx_=2?AOpWyk?k*?CS^PUbb8Lm(`l6(<6n$!+_Tmsr!x9l27AGO~-qMPF8jU2EV<^ z_*(cGe{1<`Q}_b|cj9Nvih$BfHj_rF3l<*=nCF3oG-r$+y1(u_lIbY^5=f`D&nX_t zdO3a&9=`d!cIZ|bNfnfvK|&syOuYYsShkNbM~ln%9RojUmfBFrdM~C za4!aCE+=VEHGF*R=Fe+?MwN#^oE<-_PJO!;+xS8r$slVO_dck&rB$XbzoxcR`$Twh zk}mU}YvfSFW6e?h2KTA*D~@5phPhxbd?=3E?fU$Dufw3=#u?3x!rHR>2L+K5uUYcN z&qV_zdynB;dBmP=&2o@k34scZp@%=9muh$vsUvwO|gTI2K)?3 zgLi(^)-GvA7<-uG$-MTHN4&aqHvOF?X4!&L`F46KPURhFK$=UugCv0T-bAJrb*QGI z@Ct=-3G4g9F)JO}z2dr?*e3UG;7Y@TLX`6ekZA|E_*N?_;q8N#Lii5u(%7UwX&jCk1ISuIs;l=1WSra9pX%T$o!BR;QLFr{=YZ%(C@k4TM5d!1E*yZ!{Q_4o%^x!%qEHrCqzts!Vm|hQevGX}6?pe`XxKbnJ<*mQS7x-MV`{ z;97Df6&_W4^X4d@xt;U4!xeVE!K1+1tVq@0I8NT~K`c2Tk{nUUcHX$t_(NVOEV7-&~w&d7jvQF3oaM z)Z<;k0efa_d`B4Tt{EvER7ocHT=iskb+;66H=|{Ib3Et%bUsShoP82=bM)(xl&FXA z!|f&-Iq}CfPO|A!-%f+MrYy)TbTT)}&-CcMd4fkclJK678}S(Lg*{<8_|%!nCDcZl z>^@cwfmn&81-o1Whc02gd@~*IUahiV&cd?gT-*Y!cD4X5ze>DG1|lgo$JAJFDb}|b zbpxiL=8&@|xeC_Qcrq}g30?x}-ll9#AT6Q3SkV3I^pw`ar%od#J?B(d0@0)Bm)LI} zgzC&-gbvEjb2B}{1A8YEC(YN&mD%LlJ{U6y_XL|p**V)Y`%PsZfl*Of%tEwYVepV1 zfew5K2QIdPLF}2>+gNI;(O?$O8n5mAX(}P<{kLvqx%-Dqruheb4hm%ts=5X)vJvrW za=5mL;y?+a<{hj5I5(d2d5+ue!5!u9UHC&eOdu#dU;JC+>Tk7$>0Qrn7vf_)fUl2# zwfIWs?l#_UjPkn=OFQ_Q6BiAj{6aQeC<244UShn}%hE;*#J+jFZxfGph$vl_)S-;w z;taifR(Rtdbu#}|XL6iHueOt@_Jmtfo(?3bw_JM|Lt;y-d*M4hFD!$XCkn?5v$QZL zKBnafmxAOuDO#ynzowLtD`8J@3gl@z$#W%X^fNuElhSP26Yp*JQjH0xZRW!!l2>6k z16?w}dO8p;mNtUm3C+;~p7*DF<|nG~EBX=L3^4)q_Z!2&dR?2JVe@dc^{_c;fUr8xoD|sfCa`yDQ zMJffmXNUsrePj6djrr3_E)KrAiIt&Jtj>(~{AHf;l1CE0^CO2l#&=sE;@G;u?i*9d zkNfWCSY_W7JAVOU37Qlq*LpZ05&O76!0^!4z4e7zDlU zGYOYSj6_F1ZdN#Jq2G!S3}t)?{@-|@FiG0$Llh9Fx2;cACid4O1J=(sy_A|xa!2So zMOXgAWb`jBHyN#AV?ms7Fi33ZCr3BYYn@=-3&&}0hP)tx!PgGz-x-1ws6U5;m6omh zxhcCT*$|xTylAQ9Sr=A*2EP-9xnUv*r!g>`#fZ1aKrHOfbf(To+FVpL1HlcY6nLrt zq(4!XSDdc(pZZFzka&^QvmcdLw^u+(r&=8_{rfSzdI5n?Bb`IEfs}_G{rf0>e)lS2 z8bnXnN{JMxKK(h&+f^PR1tRwK-)`_Rgg-}biqz@zz^1$IfA%obzedl0dyF8D{tus2 Bj1K?+ literal 0 HcmV?d00001 diff --git a/docs/public/openapi.json b/docs/public/openapi.json new file mode 100644 index 0000000..019d798 --- /dev/null +++ b/docs/public/openapi.json @@ -0,0 +1,2758 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "LoveAC API", + "description": "LoveACAPI API", + "version": "1.0.0" + }, + "paths": { + "/api/v1/user/veryfy_invite_code": { + "post": { + "summary": "验证邀请码", + "description": "验证邀请码\n:param data: InviteRequest\n:return: InviteResponse", + "operationId": "verify_invite_code_api_v1_user_veryfy_invite_code_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InviteRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InviteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/user/register": { + "post": { + "summary": "注册新用户", + "description": "注册新用户\n:param data: RegisterRequest\n:return: RegisterResponse", + "operationId": "register_user_api_v1_user_register_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegisterRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegisterResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_academic_info": { + "post": { + "summary": "获取学业信息", + "description": "获取学术信息(课程数量、绩点等)", + "operationId": "fetch_academic_info_api_v1_jwc_fetch_academic_info_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/AcademicInfoResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Academic Info Api V1 Jwc Fetch Academic Info Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_education_plan_info": { + "post": { + "summary": "获取培养方案信息", + "description": "获取培养方案信息", + "operationId": "fetch_education_plan_info_api_v1_jwc_fetch_education_plan_info_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/TrainingPlanInfoResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Education Plan Info Api V1 Jwc Fetch Education Plan Info Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_evaluation_course_list": { + "post": { + "summary": "获取评教课程列表", + "description": "获取评教课程列表", + "operationId": "fetch_evaluation_course_list_api_v1_jwc_fetch_evaluation_course_list_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CourseListResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Evaluation Course List Api V1 Jwc Fetch Evaluation Course List Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_exam_info": { + "post": { + "summary": "获取考试信息", + "description": "获取考试信息,包括校统考和其他考试", + "operationId": "fetch_exam_info_api_v1_jwc_fetch_exam_info_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/ExamInfoAPIResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Exam Info Api V1 Jwc Fetch Exam Info Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/evaluation/initialize": { + "post": { + "summary": "初始化评价任务", + "description": "初始化评价任务,获取课程列表", + "operationId": "initialize_evaluation_task_api_v1_jwc_evaluation_initialize_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/InitializeResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + } + ], + "title": "Response Initialize Evaluation Task Api V1 Jwc Evaluation Initialize Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/evaluation/start": { + "post": { + "summary": "开始评价任务", + "description": "开始评价任务", + "operationId": "start_evaluation_task_api_v1_jwc_evaluation_start_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/TaskOperationResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + } + ], + "title": "Response Start Evaluation Task Api V1 Jwc Evaluation Start Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/evaluation/terminate": { + "post": { + "summary": "终止评价任务", + "description": "终止评价任务", + "operationId": "terminate_evaluation_task_api_v1_jwc_evaluation_terminate_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/TaskOperationResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + } + ], + "title": "Response Terminate Evaluation Task Api V1 Jwc Evaluation Terminate Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/evaluation/status": { + "post": { + "summary": "获取评价任务状态", + "description": "获取评价任务状态", + "operationId": "get_evaluation_task_status_api_v1_jwc_evaluation_status_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/EvaluationStatsResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + } + ], + "title": "Response Get Evaluation Task Status Api V1 Jwc Evaluation Status Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/evaluation/current": { + "post": { + "summary": "获取当前评价课程信息", + "description": "获取当前评价课程信息", + "operationId": "get_current_course_info_api_v1_jwc_evaluation_current_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CurrentCourseInfoResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + } + ], + "title": "Response Get Current Course Info Api V1 Jwc Evaluation Current Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_all_terms": { + "post": { + "summary": "获取所有学期信息", + "description": "获取所有可查询的学期信息", + "operationId": "fetch_all_terms_api_v1_jwc_fetch_all_terms_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/AllTermsResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch All Terms Api V1 Jwc Fetch All Terms Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_term_score": { + "post": { + "summary": "获取指定学期成绩", + "description": "获取指定学期的成绩信息", + "operationId": "fetch_term_score_api_v1_jwc_fetch_term_score_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Body_fetch_term_score_api_v1_jwc_fetch_term_score_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/TermScoreAPIResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Term Score Api V1 Jwc Fetch Term Score Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/jwc/fetch_course_schedule": { + "post": { + "summary": "获取课表信息", + "description": "获取聚合的课表信息,包含:\n- 课程基本信息(课程名、教师、学分等)\n- 上课时间和地点信息\n- 时间段详情\n- 学期信息\n\n特殊处理:\n- 自动过滤无用字段\n- 标记没有具体时间安排的课程\n- 清理教师姓名中的特殊字符", + "operationId": "fetch_course_schedule_api_v1_jwc_fetch_course_schedule_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Body_fetch_course_schedule_api_v1_jwc_fetch_course_schedule_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/ScheduleResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Course Schedule Api V1 Jwc Fetch Course Schedule Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/user/login": { + "post": { + "summary": "用户登录", + "description": "用户登录\n:param data: LoginRequest\n:return: LoginResponse", + "operationId": "login_user_api_v1_user_login_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/user/authme": { + "post": { + "summary": "验证登录状态", + "description": "验证token是否有效,返回登录状态\n:param data: AuthmeRequest\n:return: AuthmeResponse", + "operationId": "check_auth_status_api_v1_user_authme_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/router__login__model__AuthmeResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/aac/fetch_score_info": { + "post": { + "summary": "获取爱安财总分信息", + "description": "获取爱安财系统的总分信息", + "operationId": "fetch_score_info_api_v1_aac_fetch_score_info_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/ScoreInfoResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Score Info Api V1 Aac Fetch Score Info Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/aac/fetch_score_list": { + "post": { + "summary": "获取爱安财分数明细列表", + "description": "获取爱安财系统的分数明细列表", + "operationId": "fetch_score_list_api_v1_aac_fetch_score_list_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthmeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/ScoreListResponse" + }, + { + "$ref": "#/components/schemas/provider__loveac__authme__AuthmeResponse" + }, + { + "$ref": "#/components/schemas/ErrorResponse" + } + ], + "title": "Response Fetch Score List Api V1 Aac Fetch Score List Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/user/profile/get": { + "post": { + "summary": "获取用户资料", + "description": "获取用户资料\n:param data: GetUserProfileRequest\n:return: UserProfileResponse", + "operationId": "get_user_profile_api_v1_user_profile_get_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetUserProfileRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/user/profile/update": { + "post": { + "summary": "更新用户资料", + "description": "更新用户资料\n:param data: UpdateUserProfileRequest\n:return: UserProfileResponse", + "operationId": "update_user_profile_api_v1_user_profile_update_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserProfileRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AcademicInfo": { + "properties": { + "count": { + "type": "integer", + "title": "Count", + "default": 0 + }, + "countNotPass": { + "type": "integer", + "title": "Countnotpass", + "default": 0 + }, + "gpa": { + "type": "number", + "title": "Gpa", + "default": 0 + } + }, + "type": "object", + "title": "AcademicInfo", + "description": "学术信息数据模型 - 兼容旧版API" + }, + "AcademicInfoResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/AcademicInfo" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "AcademicInfoResponse", + "description": "学业信息响应" + }, + "AllTermsResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Data", + "description": "响应数据" + } + }, + "type": "object", + "title": "AllTermsResponse", + "description": "所有学期信息响应" + }, + "AuthMeData": { + "properties": { + "authme_token": { + "type": "string", + "title": "Authme Token", + "description": "AuthMe Token" + } + }, + "type": "object", + "required": [ + "authme_token" + ], + "title": "AuthMeData", + "description": "认证令牌数据" + }, + "AuthmeRequest": { + "properties": { + "token": { + "type": "string", + "title": "Token" + } + }, + "type": "object", + "required": [ + "token" + ], + "title": "AuthmeRequest" + }, + "AuthmeStatusData": { + "properties": { + "is_logged_in": { + "type": "boolean", + "title": "Is Logged In", + "description": "是否处于登录状态" + }, + "userid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Userid", + "description": "用户ID" + } + }, + "type": "object", + "required": [ + "is_logged_in" + ], + "title": "AuthmeStatusData", + "description": "认证状态数据" + }, + "Body_fetch_course_schedule_api_v1_jwc_fetch_course_schedule_post": { + "properties": { + "request": { + "$ref": "#/components/schemas/FetchScheduleRequest" + }, + "AuthmeRequest": { + "$ref": "#/components/schemas/AuthmeRequest" + } + }, + "type": "object", + "required": [ + "request", + "AuthmeRequest" + ], + "title": "Body_fetch_course_schedule_api_v1_jwc_fetch_course_schedule_post" + }, + "Body_fetch_term_score_api_v1_jwc_fetch_term_score_post": { + "properties": { + "request": { + "$ref": "#/components/schemas/FetchTermScoreRequest" + }, + "AuthmeRequest": { + "$ref": "#/components/schemas/AuthmeRequest" + } + }, + "type": "object", + "required": [ + "request", + "AuthmeRequest" + ], + "title": "Body_fetch_term_score_api_v1_jwc_fetch_term_score_post" + }, + "Course": { + "properties": { + "id": { + "anyOf": [ + { + "$ref": "#/components/schemas/CourseId" + }, + { + "type": "null" + } + ] + }, + "questionnaire": { + "anyOf": [ + { + "$ref": "#/components/schemas/Questionnaire" + }, + { + "type": "null" + } + ] + }, + "evaluatedPeople": { + "type": "string", + "title": "Evaluatedpeople", + "default": "" + }, + "isEvaluated": { + "type": "string", + "title": "Isevaluated", + "default": "" + }, + "evaluationContent": { + "type": "string", + "title": "Evaluationcontent", + "default": "" + } + }, + "type": "object", + "title": "Course", + "description": "课程基本信息" + }, + "CourseId": { + "properties": { + "evaluatedPeople": { + "type": "string", + "title": "Evaluatedpeople", + "default": "" + }, + "coureSequenceNumber": { + "type": "string", + "title": "Couresequencenumber", + "default": "" + }, + "evaluationContentNumber": { + "type": "string", + "title": "Evaluationcontentnumber", + "default": "" + } + }, + "type": "object", + "title": "CourseId", + "description": "课程ID信息" + }, + "CourseInfo": { + "properties": { + "course_id": { + "type": "string", + "title": "Course Id", + "description": "课程ID", + "default": "" + }, + "course_name": { + "type": "string", + "title": "Course Name", + "description": "课程名称", + "default": "" + }, + "teacher_name": { + "type": "string", + "title": "Teacher Name", + "description": "教师姓名", + "default": "" + }, + "is_evaluated": { + "type": "string", + "title": "Is Evaluated", + "description": "是否已评价", + "default": "" + }, + "evaluation_content": { + "type": "string", + "title": "Evaluation Content", + "description": "评价内容", + "default": "" + } + }, + "type": "object", + "title": "CourseInfo", + "description": "课程信息响应模型" + }, + "CourseListResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/Course" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Data", + "description": "响应数据" + } + }, + "type": "object", + "title": "CourseListResponse", + "description": "评教课程列表响应" + }, + "CourseTimeLocation": { + "properties": { + "class_day": { + "type": "integer", + "title": "Class Day", + "description": "上课星期几(1-7)" + }, + "class_sessions": { + "type": "integer", + "title": "Class Sessions", + "description": "上课节次" + }, + "continuing_session": { + "type": "integer", + "title": "Continuing Session", + "description": "持续节次数" + }, + "class_week": { + "type": "string", + "title": "Class Week", + "description": "上课周次(24位二进制字符串)" + }, + "week_description": { + "type": "string", + "title": "Week Description", + "description": "上课周次描述" + }, + "campus_name": { + "type": "string", + "title": "Campus Name", + "description": "校区名称" + }, + "teaching_building_name": { + "type": "string", + "title": "Teaching Building Name", + "description": "教学楼名称" + }, + "classroom_name": { + "type": "string", + "title": "Classroom Name", + "description": "教室名称" + } + }, + "type": "object", + "required": [ + "class_day", + "class_sessions", + "continuing_session", + "class_week", + "week_description", + "campus_name", + "teaching_building_name", + "classroom_name" + ], + "title": "CourseTimeLocation", + "description": "课程时间地点模型" + }, + "CurrentCourseInfoData": { + "properties": { + "is_evaluating": { + "type": "boolean", + "title": "Is Evaluating", + "description": "是否正在评价", + "default": false + }, + "course_name": { + "type": "string", + "title": "Course Name", + "description": "课程名称", + "default": "" + }, + "teacher_name": { + "type": "string", + "title": "Teacher Name", + "description": "教师姓名", + "default": "" + }, + "progress_text": { + "type": "string", + "title": "Progress Text", + "description": "进度文本", + "default": "" + }, + "countdown_seconds": { + "type": "integer", + "title": "Countdown Seconds", + "description": "倒计时秒数", + "default": 0 + }, + "current_index": { + "type": "integer", + "title": "Current Index", + "description": "当前索引", + "default": -1 + }, + "total_pending": { + "type": "integer", + "title": "Total Pending", + "description": "总待评价数", + "default": 0 + } + }, + "type": "object", + "title": "CurrentCourseInfoData", + "description": "当前评价课程信息数据模型" + }, + "CurrentCourseInfoResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/CurrentCourseInfoData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "CurrentCourseInfoResponse", + "description": "当前评价课程信息响应模型" + }, + "ErrorResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "type": "null", + "title": "Data", + "description": "响应数据" + } + }, + "type": "object", + "title": "ErrorResponse", + "description": "专用错误响应模型" + }, + "EvaluationStatsData": { + "properties": { + "total_courses": { + "type": "integer", + "title": "Total Courses", + "description": "总课程数", + "default": 0 + }, + "pending_courses": { + "type": "integer", + "title": "Pending Courses", + "description": "待评价课程数", + "default": 0 + }, + "success_count": { + "type": "integer", + "title": "Success Count", + "description": "成功评价数", + "default": 0 + }, + "fail_count": { + "type": "integer", + "title": "Fail Count", + "description": "失败评价数", + "default": 0 + }, + "current_index": { + "type": "integer", + "title": "Current Index", + "description": "当前评价索引", + "default": 0 + }, + "status": { + "$ref": "#/components/schemas/TaskStatusEnum", + "description": "任务状态", + "default": "idle" + }, + "current_countdown": { + "type": "integer", + "title": "Current Countdown", + "description": "当前倒计时", + "default": 0 + }, + "start_time": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Start Time", + "description": "开始时间" + }, + "end_time": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "End Time", + "description": "结束时间" + }, + "error_message": { + "type": "string", + "title": "Error Message", + "description": "错误消息", + "default": "" + }, + "course_list": { + "items": { + "$ref": "#/components/schemas/CourseInfo" + }, + "type": "array", + "title": "Course List", + "description": "课程列表" + } + }, + "type": "object", + "title": "EvaluationStatsData", + "description": "评价统计信息数据模型" + }, + "EvaluationStatsResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/EvaluationStatsData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "EvaluationStatsResponse", + "description": "评价统计信息响应模型" + }, + "ExamInfoAPIResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/ExamInfoResponse" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "ExamInfoAPIResponse", + "description": "考试信息响应" + }, + "ExamInfoResponse": { + "properties": { + "exams": { + "items": { + "$ref": "#/components/schemas/UnifiedExamInfo" + }, + "type": "array", + "title": "Exams" + }, + "total_count": { + "type": "integer", + "title": "Total Count", + "default": 0 + } + }, + "type": "object", + "title": "ExamInfoResponse", + "description": "考试信息统一响应模型" + }, + "FetchScheduleRequest": { + "properties": { + "plan_code": { + "type": "string", + "title": "Plan Code", + "description": "培养方案代码,如:2024-2025-2-1" + } + }, + "type": "object", + "required": [ + "plan_code" + ], + "title": "FetchScheduleRequest", + "description": "获取课表请求模型" + }, + "FetchTermScoreRequest": { + "properties": { + "term_id": { + "type": "string", + "title": "Term Id", + "description": "学期ID,如:2024-2025-2-1" + }, + "course_code": { + "type": "string", + "title": "Course Code", + "description": "课程代码(可选,用于筛选)", + "default": "" + }, + "course_name": { + "type": "string", + "title": "Course Name", + "description": "课程名称(可选,用于筛选)", + "default": "" + }, + "page_num": { + "type": "integer", + "minimum": 1.0, + "title": "Page Num", + "description": "页码,默认为1", + "default": 1 + }, + "page_size": { + "type": "integer", + "maximum": 100.0, + "minimum": 1.0, + "title": "Page Size", + "description": "每页大小,默认为50", + "default": 50 + } + }, + "type": "object", + "required": [ + "term_id" + ], + "title": "FetchTermScoreRequest", + "description": "获取学期成绩请求模型" + }, + "GetUserProfileRequest": { + "properties": { + "token": { + "type": "string", + "title": "Token", + "description": "用户认证token" + } + }, + "type": "object", + "required": [ + "token" + ], + "title": "GetUserProfileRequest", + "description": "获取用户资料请求模型" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "InitializeData": { + "properties": { + "total_courses": { + "type": "integer", + "title": "Total Courses", + "description": "总课程数", + "default": 0 + }, + "pending_courses": { + "type": "integer", + "title": "Pending Courses", + "description": "待评价课程数", + "default": 0 + }, + "course_list": { + "items": { + "$ref": "#/components/schemas/CourseInfo" + }, + "type": "array", + "title": "Course List", + "description": "课程列表" + } + }, + "type": "object", + "title": "InitializeData", + "description": "初始化数据模型" + }, + "InitializeResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/InitializeData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "InitializeResponse", + "description": "初始化响应模型" + }, + "InviteRequest": { + "properties": { + "invite_code": { + "type": "string", + "title": "Invite Code", + "description": "邀请码" + } + }, + "type": "object", + "required": [ + "invite_code" + ], + "title": "InviteRequest" + }, + "InviteResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/InviteTokenData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "InviteResponse", + "description": "邀请响应" + }, + "InviteTokenData": { + "properties": { + "invite_token": { + "type": "string", + "title": "Invite Token", + "description": "邀请密钥" + } + }, + "type": "object", + "required": [ + "invite_token" + ], + "title": "InviteTokenData", + "description": "邀请令牌数据" + }, + "LoginRequest": { + "properties": { + "userid": { + "type": "string", + "title": "Userid", + "description": "学号" + }, + "password": { + "type": "string", + "title": "Password", + "description": "密码" + }, + "easyconnect_password": { + "type": "string", + "title": "Easyconnect Password", + "description": "VPN密码" + } + }, + "type": "object", + "required": [ + "userid", + "password", + "easyconnect_password" + ], + "title": "LoginRequest" + }, + "LoginResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/AuthMeData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "LoginResponse", + "description": "登录响应" + }, + "LoveACScoreCategory": { + "properties": { + "ID": { + "type": "string", + "title": "Id", + "default": "" + }, + "ShowNum": { + "type": "integer", + "title": "Shownum", + "default": 0 + }, + "TypeName": { + "type": "string", + "title": "Typename", + "default": "" + }, + "TotalScore": { + "type": "number", + "title": "Totalscore", + "default": 0.0 + }, + "children": { + "items": { + "$ref": "#/components/schemas/LoveACScoreItem" + }, + "type": "array", + "title": "Children", + "default": [] + } + }, + "type": "object", + "title": "LoveACScoreCategory", + "description": "爱安财分数类别" + }, + "LoveACScoreInfo": { + "properties": { + "TotalScore": { + "type": "number", + "title": "Totalscore", + "default": 0.0 + }, + "IsTypeAdopt": { + "type": "boolean", + "title": "Istypeadopt", + "default": false + }, + "TypeAdoptResult": { + "type": "string", + "title": "Typeadoptresult", + "default": "" + } + }, + "type": "object", + "title": "LoveACScoreInfo", + "description": "爱安财总分信息" + }, + "LoveACScoreItem": { + "properties": { + "ID": { + "type": "string", + "title": "Id", + "default": "" + }, + "Title": { + "type": "string", + "title": "Title", + "default": "" + }, + "TypeName": { + "type": "string", + "title": "Typename", + "default": "" + }, + "UserNo": { + "type": "string", + "title": "Userno", + "default": "" + }, + "Score": { + "type": "number", + "title": "Score", + "default": 0.0 + }, + "AddTime": { + "type": "string", + "title": "Addtime", + "default": "" + } + }, + "type": "object", + "title": "LoveACScoreItem", + "description": "爱安财分数明细条目" + }, + "Questionnaire": { + "properties": { + "questionnaireNumber": { + "type": "string", + "title": "Questionnairenumber", + "default": "" + }, + "questionnaireName": { + "type": "string", + "title": "Questionnairename", + "default": "" + } + }, + "type": "object", + "title": "Questionnaire", + "description": "问卷信息" + }, + "RegisterRequest": { + "properties": { + "userid": { + "type": "string", + "title": "Userid", + "description": "学号" + }, + "password": { + "type": "string", + "title": "Password", + "description": "密码" + }, + "easyconnect_password": { + "type": "string", + "title": "Easyconnect Password", + "description": "易联密码" + }, + "invite_token": { + "type": "string", + "title": "Invite Token", + "description": "邀请码" + } + }, + "type": "object", + "required": [ + "userid", + "password", + "easyconnect_password", + "invite_token" + ], + "title": "RegisterRequest" + }, + "RegisterResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/AuthMeData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "RegisterResponse", + "description": "注册响应" + }, + "ScheduleCourse": { + "properties": { + "course_name": { + "type": "string", + "title": "Course Name", + "description": "课程名称" + }, + "course_code": { + "type": "string", + "title": "Course Code", + "description": "课程代码" + }, + "course_sequence": { + "type": "string", + "title": "Course Sequence", + "description": "课程序号" + }, + "teacher_name": { + "type": "string", + "title": "Teacher Name", + "description": "授课教师" + }, + "course_properties": { + "type": "string", + "title": "Course Properties", + "description": "课程性质" + }, + "exam_type": { + "type": "string", + "title": "Exam Type", + "description": "考试类型" + }, + "unit": { + "type": "number", + "title": "Unit", + "description": "学分" + }, + "time_locations": { + "items": { + "$ref": "#/components/schemas/CourseTimeLocation" + }, + "type": "array", + "title": "Time Locations", + "description": "时间地点列表" + }, + "is_no_schedule": { + "type": "boolean", + "title": "Is No Schedule", + "description": "是否无具体时间安排", + "default": false + } + }, + "type": "object", + "required": [ + "course_name", + "course_code", + "course_sequence", + "teacher_name", + "course_properties", + "exam_type", + "unit", + "time_locations" + ], + "title": "ScheduleCourse", + "description": "课表课程模型" + }, + "ScheduleData": { + "properties": { + "total_units": { + "type": "number", + "title": "Total Units", + "description": "总学分" + }, + "time_slots": { + "items": { + "$ref": "#/components/schemas/TimeSlot" + }, + "type": "array", + "title": "Time Slots", + "description": "时间段列表" + }, + "courses": { + "items": { + "$ref": "#/components/schemas/ScheduleCourse" + }, + "type": "array", + "title": "Courses", + "description": "课程列表" + }, + "semester_info": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Semester Info", + "description": "学期信息" + } + }, + "type": "object", + "required": [ + "total_units", + "time_slots", + "courses", + "semester_info" + ], + "title": "ScheduleData", + "description": "课表数据模型" + }, + "ScheduleResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/ScheduleData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "ScheduleResponse", + "description": "课表响应模型" + }, + "ScoreInfoResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/LoveACScoreInfo" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "ScoreInfoResponse", + "description": "爱安财总分信息响应" + }, + "ScoreListResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/LoveACScoreCategory" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Data", + "description": "响应数据" + } + }, + "type": "object", + "title": "ScoreListResponse", + "description": "爱安财分数明细列表响应" + }, + "ScoreRecord": { + "properties": { + "sequence": { + "type": "integer", + "title": "Sequence", + "description": "序号", + "default": 0 + }, + "term_id": { + "type": "string", + "title": "Term Id", + "description": "学期ID", + "default": "" + }, + "course_code": { + "type": "string", + "title": "Course Code", + "description": "课程代码", + "default": "" + }, + "course_class": { + "type": "string", + "title": "Course Class", + "description": "课程班级", + "default": "" + }, + "course_name_cn": { + "type": "string", + "title": "Course Name Cn", + "description": "课程名称(中文)", + "default": "" + }, + "course_name_en": { + "type": "string", + "title": "Course Name En", + "description": "课程名称(英文)", + "default": "" + }, + "credits": { + "type": "string", + "title": "Credits", + "description": "学分", + "default": "" + }, + "hours": { + "type": "integer", + "title": "Hours", + "description": "学时", + "default": 0 + }, + "course_type": { + "type": "string", + "title": "Course Type", + "description": "课程性质", + "default": "" + }, + "exam_type": { + "type": "string", + "title": "Exam Type", + "description": "考试性质", + "default": "" + }, + "score": { + "type": "string", + "title": "Score", + "description": "成绩", + "default": "" + }, + "retake_score": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retake Score", + "description": "重修成绩" + }, + "makeup_score": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Makeup Score", + "description": "补考成绩" + } + }, + "type": "object", + "title": "ScoreRecord", + "description": "成绩记录模型" + }, + "TaskOperationData": { + "properties": { + "task_status": { + "$ref": "#/components/schemas/TaskStatusEnum", + "description": "任务状态", + "default": "idle" + } + }, + "type": "object", + "title": "TaskOperationData", + "description": "任务操作数据模型" + }, + "TaskOperationResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/TaskOperationData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "TaskOperationResponse", + "description": "任务操作响应模型" + }, + "TaskStatusEnum": { + "type": "string", + "enum": [ + "idle", + "initializing", + "running", + "paused", + "completed", + "failed", + "terminated" + ], + "title": "TaskStatusEnum", + "description": "任务状态枚举" + }, + "TermScoreAPIResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/TermScoreResponse" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "TermScoreAPIResponse", + "description": "学期成绩响应" + }, + "TermScoreResponse": { + "properties": { + "page_size": { + "type": "integer", + "title": "Page Size", + "description": "每页大小", + "default": 50 + }, + "page_num": { + "type": "integer", + "title": "Page Num", + "description": "页码", + "default": 1 + }, + "total_count": { + "type": "integer", + "title": "Total Count", + "description": "总记录数", + "default": 0 + }, + "records": { + "items": { + "$ref": "#/components/schemas/ScoreRecord" + }, + "type": "array", + "title": "Records", + "description": "成绩记录列表" + } + }, + "type": "object", + "title": "TermScoreResponse", + "description": "学期成绩响应模型" + }, + "TimeSlot": { + "properties": { + "session": { + "type": "integer", + "title": "Session", + "description": "节次" + }, + "session_name": { + "type": "string", + "title": "Session Name", + "description": "节次名称" + }, + "start_time": { + "type": "string", + "title": "Start Time", + "description": "开始时间,格式:HHMM" + }, + "end_time": { + "type": "string", + "title": "End Time", + "description": "结束时间,格式:HHMM" + }, + "time_length": { + "type": "string", + "title": "Time Length", + "description": "时长(分钟)" + }, + "djjc": { + "type": "integer", + "title": "Djjc", + "description": "大节节次" + } + }, + "type": "object", + "required": [ + "session", + "session_name", + "start_time", + "end_time", + "time_length", + "djjc" + ], + "title": "TimeSlot", + "description": "时间段模型" + }, + "TrainingPlanInfo": { + "properties": { + "pyfa": { + "type": "string", + "title": "Pyfa", + "default": "" + }, + "term": { + "type": "string", + "title": "Term", + "default": "" + }, + "courseCount": { + "type": "integer", + "title": "Coursecount", + "default": 0 + }, + "major": { + "type": "string", + "title": "Major", + "default": "" + }, + "grade": { + "type": "string", + "title": "Grade", + "default": "" + } + }, + "type": "object", + "title": "TrainingPlanInfo", + "description": "培养方案信息模型 - 兼容旧版API" + }, + "TrainingPlanInfoResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/TrainingPlanInfo" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "TrainingPlanInfoResponse", + "description": "培养方案信息响应" + }, + "UnifiedExamInfo": { + "properties": { + "course_name": { + "type": "string", + "title": "Course Name", + "default": "" + }, + "exam_date": { + "type": "string", + "title": "Exam Date", + "default": "" + }, + "exam_time": { + "type": "string", + "title": "Exam Time", + "default": "" + }, + "exam_location": { + "type": "string", + "title": "Exam Location", + "default": "" + }, + "exam_type": { + "type": "string", + "title": "Exam Type", + "default": "" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "type": "object", + "title": "UnifiedExamInfo", + "description": "统一考试信息模型 - 对外提供的统一格式" + }, + "UpdateUserProfileRequest": { + "properties": { + "token": { + "type": "string", + "title": "Token", + "description": "用户认证token" + }, + "avatar": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Avatar", + "description": "用户头像base64编码数据" + }, + "background": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Background", + "description": "用户背景base64编码数据" + }, + "nickname": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Nickname", + "description": "用户昵称" + }, + "settings": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserSettings" + }, + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Settings", + "description": "用户设置对象或JSON字符串" + } + }, + "type": "object", + "required": [ + "token" + ], + "title": "UpdateUserProfileRequest", + "description": "更新用户资料请求模型" + }, + "UserSettings": { + "properties": { + "theme": { + "type": "string", + "title": "Theme", + "description": "主题模式" + }, + "lightModeOpacity": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Lightmodeopacity", + "description": "浅色模式透明度" + }, + "lightModeBrightness": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Lightmodebrightness", + "description": "浅色模式亮度" + }, + "darkModeOpacity": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Darkmodeopacity", + "description": "深色模式透明度" + }, + "darkModeBrightness": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Darkmodebrightness", + "description": "深色模式亮度" + }, + "backgroundBlur": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Backgroundblur", + "description": "背景模糊强度" + } + }, + "type": "object", + "required": [ + "theme", + "lightModeOpacity", + "lightModeBrightness", + "darkModeOpacity", + "darkModeBrightness", + "backgroundBlur" + ], + "title": "UserSettings", + "description": "用户设置模型" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "provider__loveac__authme__AuthmeResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code" + }, + "message": { + "type": "string", + "title": "Message" + } + }, + "type": "object", + "required": [ + "code", + "message" + ], + "title": "AuthmeResponse" + }, + "router__login__model__AuthmeResponse": { + "properties": { + "code": { + "type": "integer", + "title": "Code", + "description": "状态码", + "default": 200 + }, + "message": { + "type": "string", + "title": "Message", + "description": "提示信息", + "default": "成功" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/AuthmeStatusData" + }, + { + "type": "null" + } + ], + "description": "响应数据" + } + }, + "type": "object", + "title": "AuthmeResponse", + "description": "AuthMe验证响应" + } + } + } +} \ No newline at end of file diff --git a/docs/public/swagger-ui-bundle.js b/docs/public/swagger-ui-bundle.js new file mode 100644 index 0000000..3d9b7bd --- /dev/null +++ b/docs/public/swagger-ui-bundle.js @@ -0,0 +1,2 @@ +/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */ +!function webpackUniversalModuleDefinition(s,o){"object"==typeof exports&&"object"==typeof module?module.exports=o():"function"==typeof define&&define.amd?define([],o):"object"==typeof exports?exports.SwaggerUIBundle=o():s.SwaggerUIBundle=o()}(this,(()=>(()=>{var s={251:(s,o)=>{o.read=function(s,o,i,a,u){var _,w,x=8*u-a-1,C=(1<>1,L=-7,B=i?u-1:0,$=i?-1:1,V=s[o+B];for(B+=$,_=V&(1<<-L)-1,V>>=-L,L+=x;L>0;_=256*_+s[o+B],B+=$,L-=8);for(w=_&(1<<-L)-1,_>>=-L,L+=a;L>0;w=256*w+s[o+B],B+=$,L-=8);if(0===_)_=1-j;else{if(_===C)return w?NaN:1/0*(V?-1:1);w+=Math.pow(2,a),_-=j}return(V?-1:1)*w*Math.pow(2,_-a)},o.write=function(s,o,i,a,u,_){var w,x,C,j=8*_-u-1,L=(1<>1,$=23===u?Math.pow(2,-24)-Math.pow(2,-77):0,V=a?0:_-1,U=a?1:-1,z=o<0||0===o&&1/o<0?1:0;for(o=Math.abs(o),isNaN(o)||o===1/0?(x=isNaN(o)?1:0,w=L):(w=Math.floor(Math.log(o)/Math.LN2),o*(C=Math.pow(2,-w))<1&&(w--,C*=2),(o+=w+B>=1?$/C:$*Math.pow(2,1-B))*C>=2&&(w++,C/=2),w+B>=L?(x=0,w=L):w+B>=1?(x=(o*C-1)*Math.pow(2,u),w+=B):(x=o*Math.pow(2,B-1)*Math.pow(2,u),w=0));u>=8;s[i+V]=255&x,V+=U,x/=256,u-=8);for(w=w<0;s[i+V]=255&w,V+=U,w/=256,j-=8);s[i+V-U]|=128*z}},462:(s,o,i)=>{"use strict";var a=i(40975);s.exports=a},659:(s,o,i)=>{var a=i(51873),u=Object.prototype,_=u.hasOwnProperty,w=u.toString,x=a?a.toStringTag:void 0;s.exports=function getRawTag(s){var o=_.call(s,x),i=s[x];try{s[x]=void 0;var a=!0}catch(s){}var u=w.call(s);return a&&(o?s[x]=i:delete s[x]),u}},694:(s,o,i)=>{"use strict";i(91599);var a=i(37257);i(12560),s.exports=a},953:(s,o,i)=>{"use strict";s.exports=i(53375)},1733:s=>{var o=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;s.exports=function asciiWords(s){return s.match(o)||[]}},1882:(s,o,i)=>{var a=i(72552),u=i(23805);s.exports=function isFunction(s){if(!u(s))return!1;var o=a(s);return"[object Function]"==o||"[object GeneratorFunction]"==o||"[object AsyncFunction]"==o||"[object Proxy]"==o}},1907:(s,o,i)=>{"use strict";var a=i(41505),u=Function.prototype,_=u.call,w=a&&u.bind.bind(_,_);s.exports=a?w:function(s){return function(){return _.apply(s,arguments)}}},2205:function(s,o,i){var a;a=void 0!==i.g?i.g:this,s.exports=function(s){if(s.CSS&&s.CSS.escape)return s.CSS.escape;var cssEscape=function(s){if(0==arguments.length)throw new TypeError("`CSS.escape` requires an argument.");for(var o,i=String(s),a=i.length,u=-1,_="",w=i.charCodeAt(0);++u=1&&o<=31||127==o||0==u&&o>=48&&o<=57||1==u&&o>=48&&o<=57&&45==w?"\\"+o.toString(16)+" ":0==u&&1==a&&45==o||!(o>=128||45==o||95==o||o>=48&&o<=57||o>=65&&o<=90||o>=97&&o<=122)?"\\"+i.charAt(u):i.charAt(u):_+="�";return _};return s.CSS||(s.CSS={}),s.CSS.escape=cssEscape,cssEscape}(a)},2209:(s,o,i)=>{"use strict";var a,u=i(9404),_=function productionTypeChecker(){invariant(!1,"ImmutablePropTypes type checking code is stripped in production.")};_.isRequired=_;var w=function getProductionTypeChecker(){return _};function getPropType(s){var o=typeof s;return Array.isArray(s)?"array":s instanceof RegExp?"object":s instanceof u.Iterable?"Immutable."+s.toSource().split(" ")[0]:o}function createChainableTypeChecker(s){function checkType(o,i,a,u,_,w){for(var x=arguments.length,C=Array(x>6?x-6:0),j=6;j>",null!=i[a]?s.apply(void 0,[i,a,u,_,w].concat(C)):o?new Error("Required "+_+" `"+w+"` was not specified in `"+u+"`."):void 0}var o=checkType.bind(null,!1);return o.isRequired=checkType.bind(null,!0),o}function createIterableSubclassTypeChecker(s,o){return function createImmutableTypeChecker(s,o){return createChainableTypeChecker((function validate(i,a,u,_,w){var x=i[a];if(!o(x)){var C=getPropType(x);return new Error("Invalid "+_+" `"+w+"` of type `"+C+"` supplied to `"+u+"`, expected `"+s+"`.")}return null}))}("Iterable."+s,(function(s){return u.Iterable.isIterable(s)&&o(s)}))}(a={listOf:w,mapOf:w,orderedMapOf:w,setOf:w,orderedSetOf:w,stackOf:w,iterableOf:w,recordOf:w,shape:w,contains:w,mapContains:w,orderedMapContains:w,list:_,map:_,orderedMap:_,set:_,orderedSet:_,stack:_,seq:_,record:_,iterable:_}).iterable.indexed=createIterableSubclassTypeChecker("Indexed",u.Iterable.isIndexed),a.iterable.keyed=createIterableSubclassTypeChecker("Keyed",u.Iterable.isKeyed),s.exports=a},2404:(s,o,i)=>{var a=i(60270);s.exports=function isEqual(s,o){return a(s,o)}},2523:s=>{s.exports=function baseFindIndex(s,o,i,a){for(var u=s.length,_=i+(a?1:-1);a?_--:++_{"use strict";var a=i(45951),u=Object.defineProperty;s.exports=function(s,o){try{u(a,s,{value:o,configurable:!0,writable:!0})}catch(i){a[s]=o}return o}},2694:(s,o,i)=>{"use strict";var a=i(6925);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,s.exports=function(){function shim(s,o,i,u,_,w){if(w!==a){var x=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw x.name="Invariant Violation",x}}function getShim(){return shim}shim.isRequired=shim;var s={array:shim,bigint:shim,bool:shim,func:shim,number:shim,object:shim,string:shim,symbol:shim,any:shim,arrayOf:getShim,element:shim,elementType:shim,instanceOf:getShim,node:shim,objectOf:getShim,oneOf:getShim,oneOfType:getShim,shape:getShim,exact:getShim,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return s.PropTypes=s,s}},2874:s=>{s.exports={}},2875:(s,o,i)=>{"use strict";var a=i(23045),u=i(80376);s.exports=Object.keys||function keys(s){return a(s,u)}},2955:(s,o,i)=>{"use strict";var a,u=i(65606);function _defineProperty(s,o,i){return(o=function _toPropertyKey(s){var o=function _toPrimitive(s,o){if("object"!=typeof s||null===s)return s;var i=s[Symbol.toPrimitive];if(void 0!==i){var a=i.call(s,o||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===o?String:Number)(s)}(s,"string");return"symbol"==typeof o?o:String(o)}(o))in s?Object.defineProperty(s,o,{value:i,enumerable:!0,configurable:!0,writable:!0}):s[o]=i,s}var _=i(86238),w=Symbol("lastResolve"),x=Symbol("lastReject"),C=Symbol("error"),j=Symbol("ended"),L=Symbol("lastPromise"),B=Symbol("handlePromise"),$=Symbol("stream");function createIterResult(s,o){return{value:s,done:o}}function readAndResolve(s){var o=s[w];if(null!==o){var i=s[$].read();null!==i&&(s[L]=null,s[w]=null,s[x]=null,o(createIterResult(i,!1)))}}function onReadable(s){u.nextTick(readAndResolve,s)}var V=Object.getPrototypeOf((function(){})),U=Object.setPrototypeOf((_defineProperty(a={get stream(){return this[$]},next:function next(){var s=this,o=this[C];if(null!==o)return Promise.reject(o);if(this[j])return Promise.resolve(createIterResult(void 0,!0));if(this[$].destroyed)return new Promise((function(o,i){u.nextTick((function(){s[C]?i(s[C]):o(createIterResult(void 0,!0))}))}));var i,a=this[L];if(a)i=new Promise(function wrapForNext(s,o){return function(i,a){s.then((function(){o[j]?i(createIterResult(void 0,!0)):o[B](i,a)}),a)}}(a,this));else{var _=this[$].read();if(null!==_)return Promise.resolve(createIterResult(_,!1));i=new Promise(this[B])}return this[L]=i,i}},Symbol.asyncIterator,(function(){return this})),_defineProperty(a,"return",(function _return(){var s=this;return new Promise((function(o,i){s[$].destroy(null,(function(s){s?i(s):o(createIterResult(void 0,!0))}))}))})),a),V);s.exports=function createReadableStreamAsyncIterator(s){var o,i=Object.create(U,(_defineProperty(o={},$,{value:s,writable:!0}),_defineProperty(o,w,{value:null,writable:!0}),_defineProperty(o,x,{value:null,writable:!0}),_defineProperty(o,C,{value:null,writable:!0}),_defineProperty(o,j,{value:s._readableState.endEmitted,writable:!0}),_defineProperty(o,B,{value:function value(s,o){var a=i[$].read();a?(i[L]=null,i[w]=null,i[x]=null,s(createIterResult(a,!1))):(i[w]=s,i[x]=o)},writable:!0}),o));return i[L]=null,_(s,(function(s){if(s&&"ERR_STREAM_PREMATURE_CLOSE"!==s.code){var o=i[x];return null!==o&&(i[L]=null,i[w]=null,i[x]=null,o(s)),void(i[C]=s)}var a=i[w];null!==a&&(i[L]=null,i[w]=null,i[x]=null,a(createIterResult(void 0,!0))),i[j]=!0})),s.on("readable",onReadable.bind(null,i)),i}},3110:(s,o,i)=>{const a=i(5187),u=i(85015),_=i(98023),w=i(53812),x=i(23805),C=i(85105),j=i(86804);class Namespace{constructor(s){this.elementMap={},this.elementDetection=[],this.Element=j.Element,this.KeyValuePair=j.KeyValuePair,s&&s.noDefault||this.useDefault(),this._attributeElementKeys=[],this._attributeElementArrayKeys=[]}use(s){return s.namespace&&s.namespace({base:this}),s.load&&s.load({base:this}),this}useDefault(){return this.register("null",j.NullElement).register("string",j.StringElement).register("number",j.NumberElement).register("boolean",j.BooleanElement).register("array",j.ArrayElement).register("object",j.ObjectElement).register("member",j.MemberElement).register("ref",j.RefElement).register("link",j.LinkElement),this.detect(a,j.NullElement,!1).detect(u,j.StringElement,!1).detect(_,j.NumberElement,!1).detect(w,j.BooleanElement,!1).detect(Array.isArray,j.ArrayElement,!1).detect(x,j.ObjectElement,!1),this}register(s,o){return this._elements=void 0,this.elementMap[s]=o,this}unregister(s){return this._elements=void 0,delete this.elementMap[s],this}detect(s,o,i){return void 0===i||i?this.elementDetection.unshift([s,o]):this.elementDetection.push([s,o]),this}toElement(s){if(s instanceof this.Element)return s;let o;for(let i=0;i{const o=s[0].toUpperCase()+s.substr(1);this._elements[o]=this.elementMap[s]}))),this._elements}get serialiser(){return new C(this)}}C.prototype.Namespace=Namespace,s.exports=Namespace},3121:(s,o,i)=>{"use strict";var a=i(65482),u=Math.min;s.exports=function(s){var o=a(s);return o>0?u(o,9007199254740991):0}},3209:(s,o,i)=>{var a=i(91596),u=i(53320),_=i(36306),w="__lodash_placeholder__",x=128,C=Math.min;s.exports=function mergeData(s,o){var i=s[1],j=o[1],L=i|j,B=L<131,$=j==x&&8==i||j==x&&256==i&&s[7].length<=o[8]||384==j&&o[7].length<=o[8]&&8==i;if(!B&&!$)return s;1&j&&(s[2]=o[2],L|=1&i?0:4);var V=o[3];if(V){var U=s[3];s[3]=U?a(U,V,o[4]):V,s[4]=U?_(s[3],w):o[4]}return(V=o[5])&&(U=s[5],s[5]=U?u(U,V,o[6]):V,s[6]=U?_(s[5],w):o[6]),(V=o[7])&&(s[7]=V),j&x&&(s[8]=null==s[8]?o[8]:C(s[8],o[8])),null==s[9]&&(s[9]=o[9]),s[0]=o[0],s[1]=L,s}},3650:(s,o,i)=>{var a=i(74335)(Object.keys,Object);s.exports=a},3656:(s,o,i)=>{s=i.nmd(s);var a=i(9325),u=i(89935),_=o&&!o.nodeType&&o,w=_&&s&&!s.nodeType&&s,x=w&&w.exports===_?a.Buffer:void 0,C=(x?x.isBuffer:void 0)||u;s.exports=C},4509:(s,o,i)=>{var a=i(12651);s.exports=function mapCacheHas(s){return a(this,s).has(s)}},4640:s=>{"use strict";var o=String;s.exports=function(s){try{return o(s)}catch(s){return"Object"}}},4664:(s,o,i)=>{var a=i(79770),u=i(63345),_=Object.prototype.propertyIsEnumerable,w=Object.getOwnPropertySymbols,x=w?function(s){return null==s?[]:(s=Object(s),a(w(s),(function(o){return _.call(s,o)})))}:u;s.exports=x},4901:(s,o,i)=>{var a=i(72552),u=i(30294),_=i(40346),w={};w["[object Float32Array]"]=w["[object Float64Array]"]=w["[object Int8Array]"]=w["[object Int16Array]"]=w["[object Int32Array]"]=w["[object Uint8Array]"]=w["[object Uint8ClampedArray]"]=w["[object Uint16Array]"]=w["[object Uint32Array]"]=!0,w["[object Arguments]"]=w["[object Array]"]=w["[object ArrayBuffer]"]=w["[object Boolean]"]=w["[object DataView]"]=w["[object Date]"]=w["[object Error]"]=w["[object Function]"]=w["[object Map]"]=w["[object Number]"]=w["[object Object]"]=w["[object RegExp]"]=w["[object Set]"]=w["[object String]"]=w["[object WeakMap]"]=!1,s.exports=function baseIsTypedArray(s){return _(s)&&u(s.length)&&!!w[a(s)]}},4993:(s,o,i)=>{"use strict";var a=i(16946),u=i(74239);s.exports=function(s){return a(u(s))}},5187:s=>{s.exports=function isNull(s){return null===s}},5419:s=>{s.exports=function(s,o,i,a){var u=new Blob(void 0!==a?[a,s]:[s],{type:i||"application/octet-stream"});if(void 0!==window.navigator.msSaveBlob)window.navigator.msSaveBlob(u,o);else{var _=window.URL&&window.URL.createObjectURL?window.URL.createObjectURL(u):window.webkitURL.createObjectURL(u),w=document.createElement("a");w.style.display="none",w.href=_,w.setAttribute("download",o),void 0===w.download&&w.setAttribute("target","_blank"),document.body.appendChild(w),w.click(),setTimeout((function(){document.body.removeChild(w),window.URL.revokeObjectURL(_)}),200)}}},5556:(s,o,i)=>{s.exports=i(2694)()},5861:(s,o,i)=>{var a=i(55580),u=i(68223),_=i(32804),w=i(76545),x=i(28303),C=i(72552),j=i(47473),L="[object Map]",B="[object Promise]",$="[object Set]",V="[object WeakMap]",U="[object DataView]",z=j(a),Y=j(u),Z=j(_),ee=j(w),ie=j(x),ae=C;(a&&ae(new a(new ArrayBuffer(1)))!=U||u&&ae(new u)!=L||_&&ae(_.resolve())!=B||w&&ae(new w)!=$||x&&ae(new x)!=V)&&(ae=function(s){var o=C(s),i="[object Object]"==o?s.constructor:void 0,a=i?j(i):"";if(a)switch(a){case z:return U;case Y:return L;case Z:return B;case ee:return $;case ie:return V}return o}),s.exports=ae},6048:s=>{s.exports=function negate(s){if("function"!=typeof s)throw new TypeError("Expected a function");return function(){var o=arguments;switch(o.length){case 0:return!s.call(this);case 1:return!s.call(this,o[0]);case 2:return!s.call(this,o[0],o[1]);case 3:return!s.call(this,o[0],o[1],o[2])}return!s.apply(this,o)}}},6205:s=>{s.exports={ROOT:0,GROUP:1,POSITION:2,SET:3,RANGE:4,REPETITION:5,REFERENCE:6,CHAR:7}},6233:(s,o,i)=>{const a=i(6048),u=i(10316),_=i(92340);class ArrayElement extends u{constructor(s,o,i){super(s||[],o,i),this.element="array"}primitive(){return"array"}get(s){return this.content[s]}getValue(s){const o=this.get(s);if(o)return o.toValue()}getIndex(s){return this.content[s]}set(s,o){return this.content[s]=this.refract(o),this}remove(s){const o=this.content.splice(s,1);return o.length?o[0]:null}map(s,o){return this.content.map(s,o)}flatMap(s,o){return this.map(s,o).reduce(((s,o)=>s.concat(o)),[])}compactMap(s,o){const i=[];return this.forEach((a=>{const u=s.bind(o)(a);u&&i.push(u)})),i}filter(s,o){return new _(this.content.filter(s,o))}reject(s,o){return this.filter(a(s),o)}reduce(s,o){let i,a;void 0!==o?(i=0,a=this.refract(o)):(i=1,a="object"===this.primitive()?this.first.value:this.first);for(let o=i;o{s.bind(o)(i,this.refract(a))}))}shift(){return this.content.shift()}unshift(s){this.content.unshift(this.refract(s))}push(s){return this.content.push(this.refract(s)),this}add(s){this.push(s)}findElements(s,o){const i=o||{},a=!!i.recursive,u=void 0===i.results?[]:i.results;return this.forEach(((o,i,_)=>{a&&void 0!==o.findElements&&o.findElements(s,{results:u,recursive:a}),s(o,i,_)&&u.push(o)})),u}find(s){return new _(this.findElements(s,{recursive:!0}))}findByElement(s){return this.find((o=>o.element===s))}findByClass(s){return this.find((o=>o.classes.includes(s)))}getById(s){return this.find((o=>o.id.toValue()===s)).first}includes(s){return this.content.some((o=>o.equals(s)))}contains(s){return this.includes(s)}empty(){return new this.constructor([])}"fantasy-land/empty"(){return this.empty()}concat(s){return new this.constructor(this.content.concat(s.content))}"fantasy-land/concat"(s){return this.concat(s)}"fantasy-land/map"(s){return new this.constructor(this.map(s))}"fantasy-land/chain"(s){return this.map((o=>s(o)),this).reduce(((s,o)=>s.concat(o)),this.empty())}"fantasy-land/filter"(s){return new this.constructor(this.content.filter(s))}"fantasy-land/reduce"(s,o){return this.content.reduce(s,o)}get length(){return this.content.length}get isEmpty(){return 0===this.content.length}get first(){return this.getIndex(0)}get second(){return this.getIndex(1)}get last(){return this.getIndex(this.length-1)}}ArrayElement.empty=function empty(){return new this},ArrayElement["fantasy-land/empty"]=ArrayElement.empty,"undefined"!=typeof Symbol&&(ArrayElement.prototype[Symbol.iterator]=function symbol(){return this.content[Symbol.iterator]()}),s.exports=ArrayElement},6499:(s,o,i)=>{"use strict";var a=i(1907),u=0,_=Math.random(),w=a(1..toString);s.exports=function(s){return"Symbol("+(void 0===s?"":s)+")_"+w(++u+_,36)}},6925:s=>{"use strict";s.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},7057:(s,o,i)=>{"use strict";var a=i(11470).charAt,u=i(90160),_=i(64932),w=i(60183),x=i(59550),C="String Iterator",j=_.set,L=_.getterFor(C);w(String,"String",(function(s){j(this,{type:C,string:u(s),index:0})}),(function next(){var s,o=L(this),i=o.string,u=o.index;return u>=i.length?x(void 0,!0):(s=a(i,u),o.index+=s.length,x(s,!1))}))},7309:(s,o,i)=>{var a=i(62006)(i(24713));s.exports=a},7376:s=>{"use strict";s.exports=!0},7463:(s,o,i)=>{"use strict";var a=i(98828),u=i(62250),_=/#|\.prototype\./,isForced=function(s,o){var i=x[w(s)];return i===j||i!==C&&(u(o)?a(o):!!o)},w=isForced.normalize=function(s){return String(s).replace(_,".").toLowerCase()},x=isForced.data={},C=isForced.NATIVE="N",j=isForced.POLYFILL="P";s.exports=isForced},7666:(s,o,i)=>{var a=i(84851),u=i(953);function _extends(){var o;return s.exports=_extends=a?u(o=a).call(o):function(s){for(var o=1;o{const a=i(6205);o.wordBoundary=()=>({type:a.POSITION,value:"b"}),o.nonWordBoundary=()=>({type:a.POSITION,value:"B"}),o.begin=()=>({type:a.POSITION,value:"^"}),o.end=()=>({type:a.POSITION,value:"$"})},8068:s=>{"use strict";var o=(()=>{var s=Object.defineProperty,o=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable,__defNormalProp=(o,i,a)=>i in o?s(o,i,{enumerable:!0,configurable:!0,writable:!0,value:a}):o[i]=a,__spreadValues=(s,o)=>{for(var i in o||(o={}))u.call(o,i)&&__defNormalProp(s,i,o[i]);if(a)for(var i of a(o))_.call(o,i)&&__defNormalProp(s,i,o[i]);return s},__publicField=(s,o,i)=>__defNormalProp(s,"symbol"!=typeof o?o+"":o,i),w={};((o,i)=>{for(var a in i)s(o,a,{get:i[a],enumerable:!0})})(w,{DEFAULT_OPTIONS:()=>C,DEFAULT_UUID_LENGTH:()=>x,default:()=>B});var x=6,C={dictionary:"alphanum",shuffle:!0,debug:!1,length:x,counter:0},j=class _ShortUniqueId{constructor(s={}){__publicField(this,"counter"),__publicField(this,"debug"),__publicField(this,"dict"),__publicField(this,"version"),__publicField(this,"dictIndex",0),__publicField(this,"dictRange",[]),__publicField(this,"lowerBound",0),__publicField(this,"upperBound",0),__publicField(this,"dictLength",0),__publicField(this,"uuidLength"),__publicField(this,"_digit_first_ascii",48),__publicField(this,"_digit_last_ascii",58),__publicField(this,"_alpha_lower_first_ascii",97),__publicField(this,"_alpha_lower_last_ascii",123),__publicField(this,"_hex_last_ascii",103),__publicField(this,"_alpha_upper_first_ascii",65),__publicField(this,"_alpha_upper_last_ascii",91),__publicField(this,"_number_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii]}),__publicField(this,"_alpha_dict_ranges",{lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]}),__publicField(this,"_alpha_lower_dict_ranges",{lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]}),__publicField(this,"_alpha_upper_dict_ranges",{upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]}),__publicField(this,"_alphanum_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]}),__publicField(this,"_alphanum_lower_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]}),__publicField(this,"_alphanum_upper_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]}),__publicField(this,"_hex_dict_ranges",{decDigits:[this._digit_first_ascii,this._digit_last_ascii],alphaDigits:[this._alpha_lower_first_ascii,this._hex_last_ascii]}),__publicField(this,"_dict_ranges",{_number_dict_ranges:this._number_dict_ranges,_alpha_dict_ranges:this._alpha_dict_ranges,_alpha_lower_dict_ranges:this._alpha_lower_dict_ranges,_alpha_upper_dict_ranges:this._alpha_upper_dict_ranges,_alphanum_dict_ranges:this._alphanum_dict_ranges,_alphanum_lower_dict_ranges:this._alphanum_lower_dict_ranges,_alphanum_upper_dict_ranges:this._alphanum_upper_dict_ranges,_hex_dict_ranges:this._hex_dict_ranges}),__publicField(this,"log",((...s)=>{const o=[...s];o[0]="[short-unique-id] ".concat(s[0]),!0!==this.debug||"undefined"==typeof console||null===console||console.log(...o)})),__publicField(this,"_normalizeDictionary",((s,o)=>{let i;if(s&&Array.isArray(s)&&s.length>1)i=s;else{i=[],this.dictIndex=0;const o="_".concat(s,"_dict_ranges"),a=this._dict_ranges[o];let u=0;for(const[,s]of Object.entries(a)){const[o,i]=s;u+=Math.abs(i-o)}i=new Array(u);let _=0;for(const[,s]of Object.entries(a)){this.dictRange=s,this.lowerBound=this.dictRange[0],this.upperBound=this.dictRange[1];const o=this.lowerBound<=this.upperBound,a=this.lowerBound,u=this.upperBound;if(o)for(let s=a;su;s--)i[_++]=String.fromCharCode(s),this.dictIndex=s}i.length=_}if(o){for(let s=i.length-1;s>0;s--){const o=Math.floor(Math.random()*(s+1));[i[s],i[o]]=[i[o],i[s]]}}return i})),__publicField(this,"setDictionary",((s,o)=>{this.dict=this._normalizeDictionary(s,o),this.dictLength=this.dict.length,this.setCounter(0)})),__publicField(this,"seq",(()=>this.sequentialUUID())),__publicField(this,"sequentialUUID",(()=>{const s=this.dictLength,o=this.dict;let i=this.counter;const a=[];do{const u=i%s;i=Math.trunc(i/s),a.push(o[u])}while(0!==i);const u=a.join("");return this.counter+=1,u})),__publicField(this,"rnd",((s=this.uuidLength||x)=>this.randomUUID(s))),__publicField(this,"randomUUID",((s=this.uuidLength||x)=>{if(null==s||s<1)throw new Error("Invalid UUID Length Provided");const o=new Array(s),i=this.dictLength,a=this.dict;for(let u=0;uthis.formattedUUID(s,o))),__publicField(this,"formattedUUID",((s,o)=>{const i={$r:this.randomUUID,$s:this.sequentialUUID,$t:this.stamp};return s.replace(/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g,(s=>{const a=s.slice(0,2),u=Number.parseInt(s.slice(2),10);return"$s"===a?i[a]().padStart(u,"0"):"$t"===a&&o?i[a](u,o):i[a](u)}))})),__publicField(this,"availableUUIDs",((s=this.uuidLength)=>Number.parseFloat(([...new Set(this.dict)].length**s).toFixed(0)))),__publicField(this,"_collisionCache",new Map),__publicField(this,"approxMaxBeforeCollision",((s=this.availableUUIDs(this.uuidLength))=>{const o=s,i=this._collisionCache.get(o);if(void 0!==i)return i;const a=Number.parseFloat(Math.sqrt(Math.PI/2*s).toFixed(20));return this._collisionCache.set(o,a),a})),__publicField(this,"collisionProbability",((s=this.availableUUIDs(this.uuidLength),o=this.uuidLength)=>Number.parseFloat((this.approxMaxBeforeCollision(s)/this.availableUUIDs(o)).toFixed(20)))),__publicField(this,"uniqueness",((s=this.availableUUIDs(this.uuidLength))=>{const o=Number.parseFloat((1-this.approxMaxBeforeCollision(s)/s).toFixed(20));return o>1?1:o<0?0:o})),__publicField(this,"getVersion",(()=>this.version)),__publicField(this,"stamp",((s,o)=>{const i=Math.floor(+(o||new Date)/1e3).toString(16);if("number"==typeof s&&0===s)return i;if("number"!=typeof s||s<10)throw new Error(["Param finalLength must be a number greater than or equal to 10,","or 0 if you want the raw hexadecimal timestamp"].join("\n"));const a=s-9,u=Math.round(Math.random()*(a>15?15:a)),_=this.randomUUID(a);return"".concat(_.substring(0,u)).concat(i).concat(_.substring(u)).concat(u.toString(16))})),__publicField(this,"parseStamp",((s,o)=>{if(o&&!/t0|t[1-9]\d{1,}/.test(o))throw new Error("Cannot extract date from a formated UUID with no timestamp in the format");const i=o?o.replace(/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g,(s=>{const o={$r:s=>[...Array(s)].map((()=>"r")).join(""),$s:s=>[...Array(s)].map((()=>"s")).join(""),$t:s=>[...Array(s)].map((()=>"t")).join("")},i=s.slice(0,2),a=Number.parseInt(s.slice(2),10);return o[i](a)})).replace(/^(.*?)(t{8,})(.*)$/g,((o,i,a)=>s.substring(i.length,i.length+a.length))):s;if(8===i.length)return new Date(1e3*Number.parseInt(i,16));if(i.length<10)throw new Error("Stamp length invalid");const a=Number.parseInt(i.substring(i.length-1),16);return new Date(1e3*Number.parseInt(i.substring(a,a+8),16))})),__publicField(this,"setCounter",(s=>{this.counter=s})),__publicField(this,"validate",((s,o)=>{const i=o?this._normalizeDictionary(o):this.dict;return s.split("").every((s=>i.includes(s)))}));const o=__spreadValues(__spreadValues({},C),s);this.counter=0,this.debug=!1,this.dict=[],this.version="5.3.2";const{dictionary:i,shuffle:a,length:u,counter:_}=o;this.uuidLength=u,this.setDictionary(i,a),this.setCounter(_),this.debug=o.debug,this.log(this.dict),this.log("Generator instantiated with Dictionary Size ".concat(this.dictLength," and counter set to ").concat(this.counter)),this.log=this.log.bind(this),this.setDictionary=this.setDictionary.bind(this),this.setCounter=this.setCounter.bind(this),this.seq=this.seq.bind(this),this.sequentialUUID=this.sequentialUUID.bind(this),this.rnd=this.rnd.bind(this),this.randomUUID=this.randomUUID.bind(this),this.fmt=this.fmt.bind(this),this.formattedUUID=this.formattedUUID.bind(this),this.availableUUIDs=this.availableUUIDs.bind(this),this.approxMaxBeforeCollision=this.approxMaxBeforeCollision.bind(this),this.collisionProbability=this.collisionProbability.bind(this),this.uniqueness=this.uniqueness.bind(this),this.getVersion=this.getVersion.bind(this),this.stamp=this.stamp.bind(this),this.parseStamp=this.parseStamp.bind(this)}};__publicField(j,"default",j);var L,B=j;return L=w,((a,_,w,x)=>{if(_&&"object"==typeof _||"function"==typeof _)for(let C of i(_))u.call(a,C)||C===w||s(a,C,{get:()=>_[C],enumerable:!(x=o(_,C))||x.enumerable});return a})(s({},"__esModule",{value:!0}),L)})();s.exports=o.default,"undefined"!=typeof window&&(o=o.default)},9325:(s,o,i)=>{var a=i(34840),u="object"==typeof self&&self&&self.Object===Object&&self,_=a||u||Function("return this")();s.exports=_},9404:function(s){s.exports=function(){"use strict";var s=Array.prototype.slice;function createClass(s,o){o&&(s.prototype=Object.create(o.prototype)),s.prototype.constructor=s}function Iterable(s){return isIterable(s)?s:Seq(s)}function KeyedIterable(s){return isKeyed(s)?s:KeyedSeq(s)}function IndexedIterable(s){return isIndexed(s)?s:IndexedSeq(s)}function SetIterable(s){return isIterable(s)&&!isAssociative(s)?s:SetSeq(s)}function isIterable(s){return!(!s||!s[o])}function isKeyed(s){return!(!s||!s[i])}function isIndexed(s){return!(!s||!s[a])}function isAssociative(s){return isKeyed(s)||isIndexed(s)}function isOrdered(s){return!(!s||!s[u])}createClass(KeyedIterable,Iterable),createClass(IndexedIterable,Iterable),createClass(SetIterable,Iterable),Iterable.isIterable=isIterable,Iterable.isKeyed=isKeyed,Iterable.isIndexed=isIndexed,Iterable.isAssociative=isAssociative,Iterable.isOrdered=isOrdered,Iterable.Keyed=KeyedIterable,Iterable.Indexed=IndexedIterable,Iterable.Set=SetIterable;var o="@@__IMMUTABLE_ITERABLE__@@",i="@@__IMMUTABLE_KEYED__@@",a="@@__IMMUTABLE_INDEXED__@@",u="@@__IMMUTABLE_ORDERED__@@",_="delete",w=5,x=1<>>0;if(""+i!==o||4294967295===i)return NaN;o=i}return o<0?ensureSize(s)+o:o}function returnTrue(){return!0}function wholeSlice(s,o,i){return(0===s||void 0!==i&&s<=-i)&&(void 0===o||void 0!==i&&o>=i)}function resolveBegin(s,o){return resolveIndex(s,o,0)}function resolveEnd(s,o){return resolveIndex(s,o,o)}function resolveIndex(s,o,i){return void 0===s?i:s<0?Math.max(0,o+s):void 0===o?s:Math.min(o,s)}var $=0,V=1,U=2,z="function"==typeof Symbol&&Symbol.iterator,Y="@@iterator",Z=z||Y;function Iterator(s){this.next=s}function iteratorValue(s,o,i,a){var u=0===s?o:1===s?i:[o,i];return a?a.value=u:a={value:u,done:!1},a}function iteratorDone(){return{value:void 0,done:!0}}function hasIterator(s){return!!getIteratorFn(s)}function isIterator(s){return s&&"function"==typeof s.next}function getIterator(s){var o=getIteratorFn(s);return o&&o.call(s)}function getIteratorFn(s){var o=s&&(z&&s[z]||s[Y]);if("function"==typeof o)return o}function isArrayLike(s){return s&&"number"==typeof s.length}function Seq(s){return null==s?emptySequence():isIterable(s)?s.toSeq():seqFromValue(s)}function KeyedSeq(s){return null==s?emptySequence().toKeyedSeq():isIterable(s)?isKeyed(s)?s.toSeq():s.fromEntrySeq():keyedSeqFromValue(s)}function IndexedSeq(s){return null==s?emptySequence():isIterable(s)?isKeyed(s)?s.entrySeq():s.toIndexedSeq():indexedSeqFromValue(s)}function SetSeq(s){return(null==s?emptySequence():isIterable(s)?isKeyed(s)?s.entrySeq():s:indexedSeqFromValue(s)).toSetSeq()}Iterator.prototype.toString=function(){return"[Iterator]"},Iterator.KEYS=$,Iterator.VALUES=V,Iterator.ENTRIES=U,Iterator.prototype.inspect=Iterator.prototype.toSource=function(){return this.toString()},Iterator.prototype[Z]=function(){return this},createClass(Seq,Iterable),Seq.of=function(){return Seq(arguments)},Seq.prototype.toSeq=function(){return this},Seq.prototype.toString=function(){return this.__toString("Seq {","}")},Seq.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},Seq.prototype.__iterate=function(s,o){return seqIterate(this,s,o,!0)},Seq.prototype.__iterator=function(s,o){return seqIterator(this,s,o,!0)},createClass(KeyedSeq,Seq),KeyedSeq.prototype.toKeyedSeq=function(){return this},createClass(IndexedSeq,Seq),IndexedSeq.of=function(){return IndexedSeq(arguments)},IndexedSeq.prototype.toIndexedSeq=function(){return this},IndexedSeq.prototype.toString=function(){return this.__toString("Seq [","]")},IndexedSeq.prototype.__iterate=function(s,o){return seqIterate(this,s,o,!1)},IndexedSeq.prototype.__iterator=function(s,o){return seqIterator(this,s,o,!1)},createClass(SetSeq,Seq),SetSeq.of=function(){return SetSeq(arguments)},SetSeq.prototype.toSetSeq=function(){return this},Seq.isSeq=isSeq,Seq.Keyed=KeyedSeq,Seq.Set=SetSeq,Seq.Indexed=IndexedSeq;var ee,ie,ae,ce="@@__IMMUTABLE_SEQ__@@";function ArraySeq(s){this._array=s,this.size=s.length}function ObjectSeq(s){var o=Object.keys(s);this._object=s,this._keys=o,this.size=o.length}function IterableSeq(s){this._iterable=s,this.size=s.length||s.size}function IteratorSeq(s){this._iterator=s,this._iteratorCache=[]}function isSeq(s){return!(!s||!s[ce])}function emptySequence(){return ee||(ee=new ArraySeq([]))}function keyedSeqFromValue(s){var o=Array.isArray(s)?new ArraySeq(s).fromEntrySeq():isIterator(s)?new IteratorSeq(s).fromEntrySeq():hasIterator(s)?new IterableSeq(s).fromEntrySeq():"object"==typeof s?new ObjectSeq(s):void 0;if(!o)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+s);return o}function indexedSeqFromValue(s){var o=maybeIndexedSeqFromValue(s);if(!o)throw new TypeError("Expected Array or iterable object of values: "+s);return o}function seqFromValue(s){var o=maybeIndexedSeqFromValue(s)||"object"==typeof s&&new ObjectSeq(s);if(!o)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+s);return o}function maybeIndexedSeqFromValue(s){return isArrayLike(s)?new ArraySeq(s):isIterator(s)?new IteratorSeq(s):hasIterator(s)?new IterableSeq(s):void 0}function seqIterate(s,o,i,a){var u=s._cache;if(u){for(var _=u.length-1,w=0;w<=_;w++){var x=u[i?_-w:w];if(!1===o(x[1],a?x[0]:w,s))return w+1}return w}return s.__iterateUncached(o,i)}function seqIterator(s,o,i,a){var u=s._cache;if(u){var _=u.length-1,w=0;return new Iterator((function(){var s=u[i?_-w:w];return w++>_?iteratorDone():iteratorValue(o,a?s[0]:w-1,s[1])}))}return s.__iteratorUncached(o,i)}function fromJS(s,o){return o?fromJSWith(o,s,"",{"":s}):fromJSDefault(s)}function fromJSWith(s,o,i,a){return Array.isArray(o)?s.call(a,i,IndexedSeq(o).map((function(i,a){return fromJSWith(s,i,a,o)}))):isPlainObj(o)?s.call(a,i,KeyedSeq(o).map((function(i,a){return fromJSWith(s,i,a,o)}))):o}function fromJSDefault(s){return Array.isArray(s)?IndexedSeq(s).map(fromJSDefault).toList():isPlainObj(s)?KeyedSeq(s).map(fromJSDefault).toMap():s}function isPlainObj(s){return s&&(s.constructor===Object||void 0===s.constructor)}function is(s,o){if(s===o||s!=s&&o!=o)return!0;if(!s||!o)return!1;if("function"==typeof s.valueOf&&"function"==typeof o.valueOf){if((s=s.valueOf())===(o=o.valueOf())||s!=s&&o!=o)return!0;if(!s||!o)return!1}return!("function"!=typeof s.equals||"function"!=typeof o.equals||!s.equals(o))}function deepEqual(s,o){if(s===o)return!0;if(!isIterable(o)||void 0!==s.size&&void 0!==o.size&&s.size!==o.size||void 0!==s.__hash&&void 0!==o.__hash&&s.__hash!==o.__hash||isKeyed(s)!==isKeyed(o)||isIndexed(s)!==isIndexed(o)||isOrdered(s)!==isOrdered(o))return!1;if(0===s.size&&0===o.size)return!0;var i=!isAssociative(s);if(isOrdered(s)){var a=s.entries();return o.every((function(s,o){var u=a.next().value;return u&&is(u[1],s)&&(i||is(u[0],o))}))&&a.next().done}var u=!1;if(void 0===s.size)if(void 0===o.size)"function"==typeof s.cacheResult&&s.cacheResult();else{u=!0;var _=s;s=o,o=_}var w=!0,x=o.__iterate((function(o,a){if(i?!s.has(o):u?!is(o,s.get(a,j)):!is(s.get(a,j),o))return w=!1,!1}));return w&&s.size===x}function Repeat(s,o){if(!(this instanceof Repeat))return new Repeat(s,o);if(this._value=s,this.size=void 0===o?1/0:Math.max(0,o),0===this.size){if(ie)return ie;ie=this}}function invariant(s,o){if(!s)throw new Error(o)}function Range(s,o,i){if(!(this instanceof Range))return new Range(s,o,i);if(invariant(0!==i,"Cannot step a Range by 0"),s=s||0,void 0===o&&(o=1/0),i=void 0===i?1:Math.abs(i),oa?iteratorDone():iteratorValue(s,u,i[o?a-u++:u++])}))},createClass(ObjectSeq,KeyedSeq),ObjectSeq.prototype.get=function(s,o){return void 0===o||this.has(s)?this._object[s]:o},ObjectSeq.prototype.has=function(s){return this._object.hasOwnProperty(s)},ObjectSeq.prototype.__iterate=function(s,o){for(var i=this._object,a=this._keys,u=a.length-1,_=0;_<=u;_++){var w=a[o?u-_:_];if(!1===s(i[w],w,this))return _+1}return _},ObjectSeq.prototype.__iterator=function(s,o){var i=this._object,a=this._keys,u=a.length-1,_=0;return new Iterator((function(){var w=a[o?u-_:_];return _++>u?iteratorDone():iteratorValue(s,w,i[w])}))},ObjectSeq.prototype[u]=!0,createClass(IterableSeq,IndexedSeq),IterableSeq.prototype.__iterateUncached=function(s,o){if(o)return this.cacheResult().__iterate(s,o);var i=getIterator(this._iterable),a=0;if(isIterator(i))for(var u;!(u=i.next()).done&&!1!==s(u.value,a++,this););return a},IterableSeq.prototype.__iteratorUncached=function(s,o){if(o)return this.cacheResult().__iterator(s,o);var i=getIterator(this._iterable);if(!isIterator(i))return new Iterator(iteratorDone);var a=0;return new Iterator((function(){var o=i.next();return o.done?o:iteratorValue(s,a++,o.value)}))},createClass(IteratorSeq,IndexedSeq),IteratorSeq.prototype.__iterateUncached=function(s,o){if(o)return this.cacheResult().__iterate(s,o);for(var i,a=this._iterator,u=this._iteratorCache,_=0;_=a.length){var o=i.next();if(o.done)return o;a[u]=o.value}return iteratorValue(s,u,a[u++])}))},createClass(Repeat,IndexedSeq),Repeat.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},Repeat.prototype.get=function(s,o){return this.has(s)?this._value:o},Repeat.prototype.includes=function(s){return is(this._value,s)},Repeat.prototype.slice=function(s,o){var i=this.size;return wholeSlice(s,o,i)?this:new Repeat(this._value,resolveEnd(o,i)-resolveBegin(s,i))},Repeat.prototype.reverse=function(){return this},Repeat.prototype.indexOf=function(s){return is(this._value,s)?0:-1},Repeat.prototype.lastIndexOf=function(s){return is(this._value,s)?this.size:-1},Repeat.prototype.__iterate=function(s,o){for(var i=0;i=0&&o=0&&ii?iteratorDone():iteratorValue(s,_++,w)}))},Range.prototype.equals=function(s){return s instanceof Range?this._start===s._start&&this._end===s._end&&this._step===s._step:deepEqual(this,s)},createClass(Collection,Iterable),createClass(KeyedCollection,Collection),createClass(IndexedCollection,Collection),createClass(SetCollection,Collection),Collection.Keyed=KeyedCollection,Collection.Indexed=IndexedCollection,Collection.Set=SetCollection;var le="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function imul(s,o){var i=65535&(s|=0),a=65535&(o|=0);return i*a+((s>>>16)*a+i*(o>>>16)<<16>>>0)|0};function smi(s){return s>>>1&1073741824|3221225471&s}function hash(s){if(!1===s||null==s)return 0;if("function"==typeof s.valueOf&&(!1===(s=s.valueOf())||null==s))return 0;if(!0===s)return 1;var o=typeof s;if("number"===o){if(s!=s||s===1/0)return 0;var i=0|s;for(i!==s&&(i^=4294967295*s);s>4294967295;)i^=s/=4294967295;return smi(i)}if("string"===o)return s.length>Se?cachedHashString(s):hashString(s);if("function"==typeof s.hashCode)return s.hashCode();if("object"===o)return hashJSObj(s);if("function"==typeof s.toString)return hashString(s.toString());throw new Error("Value type "+o+" cannot be hashed.")}function cachedHashString(s){var o=Pe[s];return void 0===o&&(o=hashString(s),xe===we&&(xe=0,Pe={}),xe++,Pe[s]=o),o}function hashString(s){for(var o=0,i=0;i0)switch(s.nodeType){case 1:return s.uniqueID;case 9:return s.documentElement&&s.documentElement.uniqueID}}var fe,ye="function"==typeof WeakMap;ye&&(fe=new WeakMap);var be=0,_e="__immutablehash__";"function"==typeof Symbol&&(_e=Symbol(_e));var Se=16,we=255,xe=0,Pe={};function assertNotInfinite(s){invariant(s!==1/0,"Cannot perform this action with an infinite size.")}function Map(s){return null==s?emptyMap():isMap(s)&&!isOrdered(s)?s:emptyMap().withMutations((function(o){var i=KeyedIterable(s);assertNotInfinite(i.size),i.forEach((function(s,i){return o.set(i,s)}))}))}function isMap(s){return!(!s||!s[Re])}createClass(Map,KeyedCollection),Map.of=function(){var o=s.call(arguments,0);return emptyMap().withMutations((function(s){for(var i=0;i=o.length)throw new Error("Missing value for key: "+o[i]);s.set(o[i],o[i+1])}}))},Map.prototype.toString=function(){return this.__toString("Map {","}")},Map.prototype.get=function(s,o){return this._root?this._root.get(0,void 0,s,o):o},Map.prototype.set=function(s,o){return updateMap(this,s,o)},Map.prototype.setIn=function(s,o){return this.updateIn(s,j,(function(){return o}))},Map.prototype.remove=function(s){return updateMap(this,s,j)},Map.prototype.deleteIn=function(s){return this.updateIn(s,(function(){return j}))},Map.prototype.update=function(s,o,i){return 1===arguments.length?s(this):this.updateIn([s],o,i)},Map.prototype.updateIn=function(s,o,i){i||(i=o,o=void 0);var a=updateInDeepMap(this,forceIterator(s),o,i);return a===j?void 0:a},Map.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):emptyMap()},Map.prototype.merge=function(){return mergeIntoMapWith(this,void 0,arguments)},Map.prototype.mergeWith=function(o){return mergeIntoMapWith(this,o,s.call(arguments,1))},Map.prototype.mergeIn=function(o){var i=s.call(arguments,1);return this.updateIn(o,emptyMap(),(function(s){return"function"==typeof s.merge?s.merge.apply(s,i):i[i.length-1]}))},Map.prototype.mergeDeep=function(){return mergeIntoMapWith(this,deepMerger,arguments)},Map.prototype.mergeDeepWith=function(o){var i=s.call(arguments,1);return mergeIntoMapWith(this,deepMergerWith(o),i)},Map.prototype.mergeDeepIn=function(o){var i=s.call(arguments,1);return this.updateIn(o,emptyMap(),(function(s){return"function"==typeof s.mergeDeep?s.mergeDeep.apply(s,i):i[i.length-1]}))},Map.prototype.sort=function(s){return OrderedMap(sortFactory(this,s))},Map.prototype.sortBy=function(s,o){return OrderedMap(sortFactory(this,o,s))},Map.prototype.withMutations=function(s){var o=this.asMutable();return s(o),o.wasAltered()?o.__ensureOwner(this.__ownerID):this},Map.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new OwnerID)},Map.prototype.asImmutable=function(){return this.__ensureOwner()},Map.prototype.wasAltered=function(){return this.__altered},Map.prototype.__iterator=function(s,o){return new MapIterator(this,s,o)},Map.prototype.__iterate=function(s,o){var i=this,a=0;return this._root&&this._root.iterate((function(o){return a++,s(o[1],o[0],i)}),o),a},Map.prototype.__ensureOwner=function(s){return s===this.__ownerID?this:s?makeMap(this.size,this._root,s,this.__hash):(this.__ownerID=s,this.__altered=!1,this)},Map.isMap=isMap;var Te,Re="@@__IMMUTABLE_MAP__@@",$e=Map.prototype;function ArrayMapNode(s,o){this.ownerID=s,this.entries=o}function BitmapIndexedNode(s,o,i){this.ownerID=s,this.bitmap=o,this.nodes=i}function HashArrayMapNode(s,o,i){this.ownerID=s,this.count=o,this.nodes=i}function HashCollisionNode(s,o,i){this.ownerID=s,this.keyHash=o,this.entries=i}function ValueNode(s,o,i){this.ownerID=s,this.keyHash=o,this.entry=i}function MapIterator(s,o,i){this._type=o,this._reverse=i,this._stack=s._root&&mapIteratorFrame(s._root)}function mapIteratorValue(s,o){return iteratorValue(s,o[0],o[1])}function mapIteratorFrame(s,o){return{node:s,index:0,__prev:o}}function makeMap(s,o,i,a){var u=Object.create($e);return u.size=s,u._root=o,u.__ownerID=i,u.__hash=a,u.__altered=!1,u}function emptyMap(){return Te||(Te=makeMap(0))}function updateMap(s,o,i){var a,u;if(s._root){var _=MakeRef(L),w=MakeRef(B);if(a=updateNode(s._root,s.__ownerID,0,void 0,o,i,_,w),!w.value)return s;u=s.size+(_.value?i===j?-1:1:0)}else{if(i===j)return s;u=1,a=new ArrayMapNode(s.__ownerID,[[o,i]])}return s.__ownerID?(s.size=u,s._root=a,s.__hash=void 0,s.__altered=!0,s):a?makeMap(u,a):emptyMap()}function updateNode(s,o,i,a,u,_,w,x){return s?s.update(o,i,a,u,_,w,x):_===j?s:(SetRef(x),SetRef(w),new ValueNode(o,a,[u,_]))}function isLeafNode(s){return s.constructor===ValueNode||s.constructor===HashCollisionNode}function mergeIntoNode(s,o,i,a,u){if(s.keyHash===a)return new HashCollisionNode(o,a,[s.entry,u]);var _,x=(0===i?s.keyHash:s.keyHash>>>i)&C,j=(0===i?a:a>>>i)&C;return new BitmapIndexedNode(o,1<>>=1)w[C]=1&i?o[_++]:void 0;return w[a]=u,new HashArrayMapNode(s,_+1,w)}function mergeIntoMapWith(s,o,i){for(var a=[],u=0;u>1&1431655765))+(s>>2&858993459))+(s>>4)&252645135,s+=s>>8,127&(s+=s>>16)}function setIn(s,o,i,a){var u=a?s:arrCopy(s);return u[o]=i,u}function spliceIn(s,o,i,a){var u=s.length+1;if(a&&o+1===u)return s[o]=i,s;for(var _=new Array(u),w=0,x=0;x=qe)return createNodes(s,C,a,u);var V=s&&s===this.ownerID,U=V?C:arrCopy(C);return $?x?L===B-1?U.pop():U[L]=U.pop():U[L]=[a,u]:U.push([a,u]),V?(this.entries=U,this):new ArrayMapNode(s,U)}},BitmapIndexedNode.prototype.get=function(s,o,i,a){void 0===o&&(o=hash(i));var u=1<<((0===s?o:o>>>s)&C),_=this.bitmap;return _&u?this.nodes[popCount(_&u-1)].get(s+w,o,i,a):a},BitmapIndexedNode.prototype.update=function(s,o,i,a,u,_,x){void 0===i&&(i=hash(a));var L=(0===o?i:i>>>o)&C,B=1<=ze)return expandNodes(s,z,$,L,Z);if(V&&!Z&&2===z.length&&isLeafNode(z[1^U]))return z[1^U];if(V&&Z&&1===z.length&&isLeafNode(Z))return Z;var ee=s&&s===this.ownerID,ie=V?Z?$:$^B:$|B,ae=V?Z?setIn(z,U,Z,ee):spliceOut(z,U,ee):spliceIn(z,U,Z,ee);return ee?(this.bitmap=ie,this.nodes=ae,this):new BitmapIndexedNode(s,ie,ae)},HashArrayMapNode.prototype.get=function(s,o,i,a){void 0===o&&(o=hash(i));var u=(0===s?o:o>>>s)&C,_=this.nodes[u];return _?_.get(s+w,o,i,a):a},HashArrayMapNode.prototype.update=function(s,o,i,a,u,_,x){void 0===i&&(i=hash(a));var L=(0===o?i:i>>>o)&C,B=u===j,$=this.nodes,V=$[L];if(B&&!V)return this;var U=updateNode(V,s,o+w,i,a,u,_,x);if(U===V)return this;var z=this.count;if(V){if(!U&&--z0&&a=0&&s>>o&C;if(a>=this.array.length)return new VNode([],s);var u,_=0===a;if(o>0){var x=this.array[a];if((u=x&&x.removeBefore(s,o-w,i))===x&&_)return this}if(_&&!u)return this;var j=editableVNode(this,s);if(!_)for(var L=0;L>>o&C;if(u>=this.array.length)return this;if(o>0){var _=this.array[u];if((a=_&&_.removeAfter(s,o-w,i))===_&&u===this.array.length-1)return this}var x=editableVNode(this,s);return x.array.splice(u+1),a&&(x.array[u]=a),x};var Xe,Qe,et={};function iterateList(s,o){var i=s._origin,a=s._capacity,u=getTailOffset(a),_=s._tail;return iterateNodeOrLeaf(s._root,s._level,0);function iterateNodeOrLeaf(s,o,i){return 0===o?iterateLeaf(s,i):iterateNode(s,o,i)}function iterateLeaf(s,w){var C=w===u?_&&_.array:s&&s.array,j=w>i?0:i-w,L=a-w;return L>x&&(L=x),function(){if(j===L)return et;var s=o?--L:j++;return C&&C[s]}}function iterateNode(s,u,_){var C,j=s&&s.array,L=_>i?0:i-_>>u,B=1+(a-_>>u);return B>x&&(B=x),function(){for(;;){if(C){var s=C();if(s!==et)return s;C=null}if(L===B)return et;var i=o?--B:L++;C=iterateNodeOrLeaf(j&&j[i],u-w,_+(i<=s.size||o<0)return s.withMutations((function(s){o<0?setListBounds(s,o).set(0,i):setListBounds(s,0,o+1).set(o,i)}));o+=s._origin;var a=s._tail,u=s._root,_=MakeRef(B);return o>=getTailOffset(s._capacity)?a=updateVNode(a,s.__ownerID,0,o,i,_):u=updateVNode(u,s.__ownerID,s._level,o,i,_),_.value?s.__ownerID?(s._root=u,s._tail=a,s.__hash=void 0,s.__altered=!0,s):makeList(s._origin,s._capacity,s._level,u,a):s}function updateVNode(s,o,i,a,u,_){var x,j=a>>>i&C,L=s&&j0){var B=s&&s.array[j],$=updateVNode(B,o,i-w,a,u,_);return $===B?s:((x=editableVNode(s,o)).array[j]=$,x)}return L&&s.array[j]===u?s:(SetRef(_),x=editableVNode(s,o),void 0===u&&j===x.array.length-1?x.array.pop():x.array[j]=u,x)}function editableVNode(s,o){return o&&s&&o===s.ownerID?s:new VNode(s?s.array.slice():[],o)}function listNodeFor(s,o){if(o>=getTailOffset(s._capacity))return s._tail;if(o<1<0;)i=i.array[o>>>a&C],a-=w;return i}}function setListBounds(s,o,i){void 0!==o&&(o|=0),void 0!==i&&(i|=0);var a=s.__ownerID||new OwnerID,u=s._origin,_=s._capacity,x=u+o,j=void 0===i?_:i<0?_+i:u+i;if(x===u&&j===_)return s;if(x>=j)return s.clear();for(var L=s._level,B=s._root,$=0;x+$<0;)B=new VNode(B&&B.array.length?[void 0,B]:[],a),$+=1<<(L+=w);$&&(x+=$,u+=$,j+=$,_+=$);for(var V=getTailOffset(_),U=getTailOffset(j);U>=1<V?new VNode([],a):z;if(z&&U>V&&x<_&&z.array.length){for(var Z=B=editableVNode(B,a),ee=L;ee>w;ee-=w){var ie=V>>>ee&C;Z=Z.array[ie]=editableVNode(Z.array[ie],a)}Z.array[V>>>w&C]=z}if(j<_&&(Y=Y&&Y.removeAfter(a,0,j)),x>=U)x-=U,j-=U,L=w,B=null,Y=Y&&Y.removeBefore(a,0,x);else if(x>u||U>>L&C;if(ae!==U>>>L&C)break;ae&&($+=(1<u&&(B=B.removeBefore(a,L,x-$)),B&&Uu&&(u=x.size),isIterable(w)||(x=x.map((function(s){return fromJS(s)}))),a.push(x)}return u>s.size&&(s=s.setSize(u)),mergeIntoCollectionWith(s,o,a)}function getTailOffset(s){return s>>w<=x&&w.size>=2*_.size?(a=(u=w.filter((function(s,o){return void 0!==s&&C!==o}))).toKeyedSeq().map((function(s){return s[0]})).flip().toMap(),s.__ownerID&&(a.__ownerID=u.__ownerID=s.__ownerID)):(a=_.remove(o),u=C===w.size-1?w.pop():w.set(C,void 0))}else if(L){if(i===w.get(C)[1])return s;a=_,u=w.set(C,[o,i])}else a=_.set(o,w.size),u=w.set(w.size,[o,i]);return s.__ownerID?(s.size=a.size,s._map=a,s._list=u,s.__hash=void 0,s):makeOrderedMap(a,u)}function ToKeyedSequence(s,o){this._iter=s,this._useKeys=o,this.size=s.size}function ToIndexedSequence(s){this._iter=s,this.size=s.size}function ToSetSequence(s){this._iter=s,this.size=s.size}function FromEntriesSequence(s){this._iter=s,this.size=s.size}function flipFactory(s){var o=makeSequence(s);return o._iter=s,o.size=s.size,o.flip=function(){return s},o.reverse=function(){var o=s.reverse.apply(this);return o.flip=function(){return s.reverse()},o},o.has=function(o){return s.includes(o)},o.includes=function(o){return s.has(o)},o.cacheResult=cacheResultThrough,o.__iterateUncached=function(o,i){var a=this;return s.__iterate((function(s,i){return!1!==o(i,s,a)}),i)},o.__iteratorUncached=function(o,i){if(o===U){var a=s.__iterator(o,i);return new Iterator((function(){var s=a.next();if(!s.done){var o=s.value[0];s.value[0]=s.value[1],s.value[1]=o}return s}))}return s.__iterator(o===V?$:V,i)},o}function mapFactory(s,o,i){var a=makeSequence(s);return a.size=s.size,a.has=function(o){return s.has(o)},a.get=function(a,u){var _=s.get(a,j);return _===j?u:o.call(i,_,a,s)},a.__iterateUncached=function(a,u){var _=this;return s.__iterate((function(s,u,w){return!1!==a(o.call(i,s,u,w),u,_)}),u)},a.__iteratorUncached=function(a,u){var _=s.__iterator(U,u);return new Iterator((function(){var u=_.next();if(u.done)return u;var w=u.value,x=w[0];return iteratorValue(a,x,o.call(i,w[1],x,s),u)}))},a}function reverseFactory(s,o){var i=makeSequence(s);return i._iter=s,i.size=s.size,i.reverse=function(){return s},s.flip&&(i.flip=function(){var o=flipFactory(s);return o.reverse=function(){return s.flip()},o}),i.get=function(i,a){return s.get(o?i:-1-i,a)},i.has=function(i){return s.has(o?i:-1-i)},i.includes=function(o){return s.includes(o)},i.cacheResult=cacheResultThrough,i.__iterate=function(o,i){var a=this;return s.__iterate((function(s,i){return o(s,i,a)}),!i)},i.__iterator=function(o,i){return s.__iterator(o,!i)},i}function filterFactory(s,o,i,a){var u=makeSequence(s);return a&&(u.has=function(a){var u=s.get(a,j);return u!==j&&!!o.call(i,u,a,s)},u.get=function(a,u){var _=s.get(a,j);return _!==j&&o.call(i,_,a,s)?_:u}),u.__iterateUncached=function(u,_){var w=this,x=0;return s.__iterate((function(s,_,C){if(o.call(i,s,_,C))return x++,u(s,a?_:x-1,w)}),_),x},u.__iteratorUncached=function(u,_){var w=s.__iterator(U,_),x=0;return new Iterator((function(){for(;;){var _=w.next();if(_.done)return _;var C=_.value,j=C[0],L=C[1];if(o.call(i,L,j,s))return iteratorValue(u,a?j:x++,L,_)}}))},u}function countByFactory(s,o,i){var a=Map().asMutable();return s.__iterate((function(u,_){a.update(o.call(i,u,_,s),0,(function(s){return s+1}))})),a.asImmutable()}function groupByFactory(s,o,i){var a=isKeyed(s),u=(isOrdered(s)?OrderedMap():Map()).asMutable();s.__iterate((function(_,w){u.update(o.call(i,_,w,s),(function(s){return(s=s||[]).push(a?[w,_]:_),s}))}));var _=iterableClass(s);return u.map((function(o){return reify(s,_(o))}))}function sliceFactory(s,o,i,a){var u=s.size;if(void 0!==o&&(o|=0),void 0!==i&&(i===1/0?i=u:i|=0),wholeSlice(o,i,u))return s;var _=resolveBegin(o,u),w=resolveEnd(i,u);if(_!=_||w!=w)return sliceFactory(s.toSeq().cacheResult(),o,i,a);var x,C=w-_;C==C&&(x=C<0?0:C);var j=makeSequence(s);return j.size=0===x?x:s.size&&x||void 0,!a&&isSeq(s)&&x>=0&&(j.get=function(o,i){return(o=wrapIndex(this,o))>=0&&ox)return iteratorDone();var s=u.next();return a||o===V?s:iteratorValue(o,C-1,o===$?void 0:s.value[1],s)}))},j}function takeWhileFactory(s,o,i){var a=makeSequence(s);return a.__iterateUncached=function(a,u){var _=this;if(u)return this.cacheResult().__iterate(a,u);var w=0;return s.__iterate((function(s,u,x){return o.call(i,s,u,x)&&++w&&a(s,u,_)})),w},a.__iteratorUncached=function(a,u){var _=this;if(u)return this.cacheResult().__iterator(a,u);var w=s.__iterator(U,u),x=!0;return new Iterator((function(){if(!x)return iteratorDone();var s=w.next();if(s.done)return s;var u=s.value,C=u[0],j=u[1];return o.call(i,j,C,_)?a===U?s:iteratorValue(a,C,j,s):(x=!1,iteratorDone())}))},a}function skipWhileFactory(s,o,i,a){var u=makeSequence(s);return u.__iterateUncached=function(u,_){var w=this;if(_)return this.cacheResult().__iterate(u,_);var x=!0,C=0;return s.__iterate((function(s,_,j){if(!x||!(x=o.call(i,s,_,j)))return C++,u(s,a?_:C-1,w)})),C},u.__iteratorUncached=function(u,_){var w=this;if(_)return this.cacheResult().__iterator(u,_);var x=s.__iterator(U,_),C=!0,j=0;return new Iterator((function(){var s,_,L;do{if((s=x.next()).done)return a||u===V?s:iteratorValue(u,j++,u===$?void 0:s.value[1],s);var B=s.value;_=B[0],L=B[1],C&&(C=o.call(i,L,_,w))}while(C);return u===U?s:iteratorValue(u,_,L,s)}))},u}function concatFactory(s,o){var i=isKeyed(s),a=[s].concat(o).map((function(s){return isIterable(s)?i&&(s=KeyedIterable(s)):s=i?keyedSeqFromValue(s):indexedSeqFromValue(Array.isArray(s)?s:[s]),s})).filter((function(s){return 0!==s.size}));if(0===a.length)return s;if(1===a.length){var u=a[0];if(u===s||i&&isKeyed(u)||isIndexed(s)&&isIndexed(u))return u}var _=new ArraySeq(a);return i?_=_.toKeyedSeq():isIndexed(s)||(_=_.toSetSeq()),(_=_.flatten(!0)).size=a.reduce((function(s,o){if(void 0!==s){var i=o.size;if(void 0!==i)return s+i}}),0),_}function flattenFactory(s,o,i){var a=makeSequence(s);return a.__iterateUncached=function(a,u){var _=0,w=!1;function flatDeep(s,x){var C=this;s.__iterate((function(s,u){return(!o||x0}function zipWithFactory(s,o,i){var a=makeSequence(s);return a.size=new ArraySeq(i).map((function(s){return s.size})).min(),a.__iterate=function(s,o){for(var i,a=this.__iterator(V,o),u=0;!(i=a.next()).done&&!1!==s(i.value,u++,this););return u},a.__iteratorUncached=function(s,a){var u=i.map((function(s){return s=Iterable(s),getIterator(a?s.reverse():s)})),_=0,w=!1;return new Iterator((function(){var i;return w||(i=u.map((function(s){return s.next()})),w=i.some((function(s){return s.done}))),w?iteratorDone():iteratorValue(s,_++,o.apply(null,i.map((function(s){return s.value}))))}))},a}function reify(s,o){return isSeq(s)?o:s.constructor(o)}function validateEntry(s){if(s!==Object(s))throw new TypeError("Expected [K, V] tuple: "+s)}function resolveSize(s){return assertNotInfinite(s.size),ensureSize(s)}function iterableClass(s){return isKeyed(s)?KeyedIterable:isIndexed(s)?IndexedIterable:SetIterable}function makeSequence(s){return Object.create((isKeyed(s)?KeyedSeq:isIndexed(s)?IndexedSeq:SetSeq).prototype)}function cacheResultThrough(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):Seq.prototype.cacheResult.call(this)}function defaultComparator(s,o){return s>o?1:s=0;i--)o={value:arguments[i],next:o};return this.__ownerID?(this.size=s,this._head=o,this.__hash=void 0,this.__altered=!0,this):makeStack(s,o)},Stack.prototype.pushAll=function(s){if(0===(s=IndexedIterable(s)).size)return this;assertNotInfinite(s.size);var o=this.size,i=this._head;return s.reverse().forEach((function(s){o++,i={value:s,next:i}})),this.__ownerID?(this.size=o,this._head=i,this.__hash=void 0,this.__altered=!0,this):makeStack(o,i)},Stack.prototype.pop=function(){return this.slice(1)},Stack.prototype.unshift=function(){return this.push.apply(this,arguments)},Stack.prototype.unshiftAll=function(s){return this.pushAll(s)},Stack.prototype.shift=function(){return this.pop.apply(this,arguments)},Stack.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):emptyStack()},Stack.prototype.slice=function(s,o){if(wholeSlice(s,o,this.size))return this;var i=resolveBegin(s,this.size);if(resolveEnd(o,this.size)!==this.size)return IndexedCollection.prototype.slice.call(this,s,o);for(var a=this.size-i,u=this._head;i--;)u=u.next;return this.__ownerID?(this.size=a,this._head=u,this.__hash=void 0,this.__altered=!0,this):makeStack(a,u)},Stack.prototype.__ensureOwner=function(s){return s===this.__ownerID?this:s?makeStack(this.size,this._head,s,this.__hash):(this.__ownerID=s,this.__altered=!1,this)},Stack.prototype.__iterate=function(s,o){if(o)return this.reverse().__iterate(s);for(var i=0,a=this._head;a&&!1!==s(a.value,i++,this);)a=a.next;return i},Stack.prototype.__iterator=function(s,o){if(o)return this.reverse().__iterator(s);var i=0,a=this._head;return new Iterator((function(){if(a){var o=a.value;return a=a.next,iteratorValue(s,i++,o)}return iteratorDone()}))},Stack.isStack=isStack;var at,ct="@@__IMMUTABLE_STACK__@@",lt=Stack.prototype;function makeStack(s,o,i,a){var u=Object.create(lt);return u.size=s,u._head=o,u.__ownerID=i,u.__hash=a,u.__altered=!1,u}function emptyStack(){return at||(at=makeStack(0))}function mixin(s,o){var keyCopier=function(i){s.prototype[i]=o[i]};return Object.keys(o).forEach(keyCopier),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(o).forEach(keyCopier),s}lt[ct]=!0,lt.withMutations=$e.withMutations,lt.asMutable=$e.asMutable,lt.asImmutable=$e.asImmutable,lt.wasAltered=$e.wasAltered,Iterable.Iterator=Iterator,mixin(Iterable,{toArray:function(){assertNotInfinite(this.size);var s=new Array(this.size||0);return this.valueSeq().__iterate((function(o,i){s[i]=o})),s},toIndexedSeq:function(){return new ToIndexedSequence(this)},toJS:function(){return this.toSeq().map((function(s){return s&&"function"==typeof s.toJS?s.toJS():s})).__toJS()},toJSON:function(){return this.toSeq().map((function(s){return s&&"function"==typeof s.toJSON?s.toJSON():s})).__toJS()},toKeyedSeq:function(){return new ToKeyedSequence(this,!0)},toMap:function(){return Map(this.toKeyedSeq())},toObject:function(){assertNotInfinite(this.size);var s={};return this.__iterate((function(o,i){s[i]=o})),s},toOrderedMap:function(){return OrderedMap(this.toKeyedSeq())},toOrderedSet:function(){return OrderedSet(isKeyed(this)?this.valueSeq():this)},toSet:function(){return Set(isKeyed(this)?this.valueSeq():this)},toSetSeq:function(){return new ToSetSequence(this)},toSeq:function(){return isIndexed(this)?this.toIndexedSeq():isKeyed(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Stack(isKeyed(this)?this.valueSeq():this)},toList:function(){return List(isKeyed(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(s,o){return 0===this.size?s+o:s+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+o},concat:function(){return reify(this,concatFactory(this,s.call(arguments,0)))},includes:function(s){return this.some((function(o){return is(o,s)}))},entries:function(){return this.__iterator(U)},every:function(s,o){assertNotInfinite(this.size);var i=!0;return this.__iterate((function(a,u,_){if(!s.call(o,a,u,_))return i=!1,!1})),i},filter:function(s,o){return reify(this,filterFactory(this,s,o,!0))},find:function(s,o,i){var a=this.findEntry(s,o);return a?a[1]:i},forEach:function(s,o){return assertNotInfinite(this.size),this.__iterate(o?s.bind(o):s)},join:function(s){assertNotInfinite(this.size),s=void 0!==s?""+s:",";var o="",i=!0;return this.__iterate((function(a){i?i=!1:o+=s,o+=null!=a?a.toString():""})),o},keys:function(){return this.__iterator($)},map:function(s,o){return reify(this,mapFactory(this,s,o))},reduce:function(s,o,i){var a,u;return assertNotInfinite(this.size),arguments.length<2?u=!0:a=o,this.__iterate((function(o,_,w){u?(u=!1,a=o):a=s.call(i,a,o,_,w)})),a},reduceRight:function(s,o,i){var a=this.toKeyedSeq().reverse();return a.reduce.apply(a,arguments)},reverse:function(){return reify(this,reverseFactory(this,!0))},slice:function(s,o){return reify(this,sliceFactory(this,s,o,!0))},some:function(s,o){return!this.every(not(s),o)},sort:function(s){return reify(this,sortFactory(this,s))},values:function(){return this.__iterator(V)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some((function(){return!0}))},count:function(s,o){return ensureSize(s?this.toSeq().filter(s,o):this)},countBy:function(s,o){return countByFactory(this,s,o)},equals:function(s){return deepEqual(this,s)},entrySeq:function(){var s=this;if(s._cache)return new ArraySeq(s._cache);var o=s.toSeq().map(entryMapper).toIndexedSeq();return o.fromEntrySeq=function(){return s.toSeq()},o},filterNot:function(s,o){return this.filter(not(s),o)},findEntry:function(s,o,i){var a=i;return this.__iterate((function(i,u,_){if(s.call(o,i,u,_))return a=[u,i],!1})),a},findKey:function(s,o){var i=this.findEntry(s,o);return i&&i[0]},findLast:function(s,o,i){return this.toKeyedSeq().reverse().find(s,o,i)},findLastEntry:function(s,o,i){return this.toKeyedSeq().reverse().findEntry(s,o,i)},findLastKey:function(s,o){return this.toKeyedSeq().reverse().findKey(s,o)},first:function(){return this.find(returnTrue)},flatMap:function(s,o){return reify(this,flatMapFactory(this,s,o))},flatten:function(s){return reify(this,flattenFactory(this,s,!0))},fromEntrySeq:function(){return new FromEntriesSequence(this)},get:function(s,o){return this.find((function(o,i){return is(i,s)}),void 0,o)},getIn:function(s,o){for(var i,a=this,u=forceIterator(s);!(i=u.next()).done;){var _=i.value;if((a=a&&a.get?a.get(_,j):j)===j)return o}return a},groupBy:function(s,o){return groupByFactory(this,s,o)},has:function(s){return this.get(s,j)!==j},hasIn:function(s){return this.getIn(s,j)!==j},isSubset:function(s){return s="function"==typeof s.includes?s:Iterable(s),this.every((function(o){return s.includes(o)}))},isSuperset:function(s){return(s="function"==typeof s.isSubset?s:Iterable(s)).isSubset(this)},keyOf:function(s){return this.findKey((function(o){return is(o,s)}))},keySeq:function(){return this.toSeq().map(keyMapper).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(s){return this.toKeyedSeq().reverse().keyOf(s)},max:function(s){return maxFactory(this,s)},maxBy:function(s,o){return maxFactory(this,o,s)},min:function(s){return maxFactory(this,s?neg(s):defaultNegComparator)},minBy:function(s,o){return maxFactory(this,o?neg(o):defaultNegComparator,s)},rest:function(){return this.slice(1)},skip:function(s){return this.slice(Math.max(0,s))},skipLast:function(s){return reify(this,this.toSeq().reverse().skip(s).reverse())},skipWhile:function(s,o){return reify(this,skipWhileFactory(this,s,o,!0))},skipUntil:function(s,o){return this.skipWhile(not(s),o)},sortBy:function(s,o){return reify(this,sortFactory(this,o,s))},take:function(s){return this.slice(0,Math.max(0,s))},takeLast:function(s){return reify(this,this.toSeq().reverse().take(s).reverse())},takeWhile:function(s,o){return reify(this,takeWhileFactory(this,s,o))},takeUntil:function(s,o){return this.takeWhile(not(s),o)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=hashIterable(this))}});var ut=Iterable.prototype;ut[o]=!0,ut[Z]=ut.values,ut.__toJS=ut.toArray,ut.__toStringMapper=quoteString,ut.inspect=ut.toSource=function(){return this.toString()},ut.chain=ut.flatMap,ut.contains=ut.includes,mixin(KeyedIterable,{flip:function(){return reify(this,flipFactory(this))},mapEntries:function(s,o){var i=this,a=0;return reify(this,this.toSeq().map((function(u,_){return s.call(o,[_,u],a++,i)})).fromEntrySeq())},mapKeys:function(s,o){var i=this;return reify(this,this.toSeq().flip().map((function(a,u){return s.call(o,a,u,i)})).flip())}});var pt=KeyedIterable.prototype;function keyMapper(s,o){return o}function entryMapper(s,o){return[o,s]}function not(s){return function(){return!s.apply(this,arguments)}}function neg(s){return function(){return-s.apply(this,arguments)}}function quoteString(s){return"string"==typeof s?JSON.stringify(s):String(s)}function defaultZipper(){return arrCopy(arguments)}function defaultNegComparator(s,o){return so?-1:0}function hashIterable(s){if(s.size===1/0)return 0;var o=isOrdered(s),i=isKeyed(s),a=o?1:0;return murmurHashOfSize(s.__iterate(i?o?function(s,o){a=31*a+hashMerge(hash(s),hash(o))|0}:function(s,o){a=a+hashMerge(hash(s),hash(o))|0}:o?function(s){a=31*a+hash(s)|0}:function(s){a=a+hash(s)|0}),a)}function murmurHashOfSize(s,o){return o=le(o,3432918353),o=le(o<<15|o>>>-15,461845907),o=le(o<<13|o>>>-13,5),o=le((o=o+3864292196^s)^o>>>16,2246822507),o=smi((o=le(o^o>>>13,3266489909))^o>>>16)}function hashMerge(s,o){return s^o+2654435769+(s<<6)+(s>>2)}return pt[i]=!0,pt[Z]=ut.entries,pt.__toJS=ut.toObject,pt.__toStringMapper=function(s,o){return JSON.stringify(o)+": "+quoteString(s)},mixin(IndexedIterable,{toKeyedSeq:function(){return new ToKeyedSequence(this,!1)},filter:function(s,o){return reify(this,filterFactory(this,s,o,!1))},findIndex:function(s,o){var i=this.findEntry(s,o);return i?i[0]:-1},indexOf:function(s){var o=this.keyOf(s);return void 0===o?-1:o},lastIndexOf:function(s){var o=this.lastKeyOf(s);return void 0===o?-1:o},reverse:function(){return reify(this,reverseFactory(this,!1))},slice:function(s,o){return reify(this,sliceFactory(this,s,o,!1))},splice:function(s,o){var i=arguments.length;if(o=Math.max(0|o,0),0===i||2===i&&!o)return this;s=resolveBegin(s,s<0?this.count():this.size);var a=this.slice(0,s);return reify(this,1===i?a:a.concat(arrCopy(arguments,2),this.slice(s+o)))},findLastIndex:function(s,o){var i=this.findLastEntry(s,o);return i?i[0]:-1},first:function(){return this.get(0)},flatten:function(s){return reify(this,flattenFactory(this,s,!1))},get:function(s,o){return(s=wrapIndex(this,s))<0||this.size===1/0||void 0!==this.size&&s>this.size?o:this.find((function(o,i){return i===s}),void 0,o)},has:function(s){return(s=wrapIndex(this,s))>=0&&(void 0!==this.size?this.size===1/0||s{"use strict";i(71340);var a=i(92046);s.exports=a.Object.assign},9999:(s,o,i)=>{var a=i(37217),u=i(83729),_=i(16547),w=i(74733),x=i(43838),C=i(93290),j=i(23007),L=i(92271),B=i(48948),$=i(50002),V=i(83349),U=i(5861),z=i(76189),Y=i(77199),Z=i(35529),ee=i(56449),ie=i(3656),ae=i(87730),ce=i(23805),le=i(38440),pe=i(95950),de=i(37241),fe="[object Arguments]",ye="[object Function]",be="[object Object]",_e={};_e[fe]=_e["[object Array]"]=_e["[object ArrayBuffer]"]=_e["[object DataView]"]=_e["[object Boolean]"]=_e["[object Date]"]=_e["[object Float32Array]"]=_e["[object Float64Array]"]=_e["[object Int8Array]"]=_e["[object Int16Array]"]=_e["[object Int32Array]"]=_e["[object Map]"]=_e["[object Number]"]=_e[be]=_e["[object RegExp]"]=_e["[object Set]"]=_e["[object String]"]=_e["[object Symbol]"]=_e["[object Uint8Array]"]=_e["[object Uint8ClampedArray]"]=_e["[object Uint16Array]"]=_e["[object Uint32Array]"]=!0,_e["[object Error]"]=_e[ye]=_e["[object WeakMap]"]=!1,s.exports=function baseClone(s,o,i,Se,we,xe){var Pe,Te=1&o,Re=2&o,$e=4&o;if(i&&(Pe=we?i(s,Se,we,xe):i(s)),void 0!==Pe)return Pe;if(!ce(s))return s;var qe=ee(s);if(qe){if(Pe=z(s),!Te)return j(s,Pe)}else{var ze=U(s),We=ze==ye||"[object GeneratorFunction]"==ze;if(ie(s))return C(s,Te);if(ze==be||ze==fe||We&&!we){if(Pe=Re||We?{}:Z(s),!Te)return Re?B(s,x(Pe,s)):L(s,w(Pe,s))}else{if(!_e[ze])return we?s:{};Pe=Y(s,ze,Te)}}xe||(xe=new a);var He=xe.get(s);if(He)return He;xe.set(s,Pe),le(s)?s.forEach((function(a){Pe.add(baseClone(a,o,i,a,s,xe))})):ae(s)&&s.forEach((function(a,u){Pe.set(u,baseClone(a,o,i,u,s,xe))}));var Ye=qe?void 0:($e?Re?V:$:Re?de:pe)(s);return u(Ye||s,(function(a,u){Ye&&(a=s[u=a]),_(Pe,u,baseClone(a,o,i,u,s,xe))})),Pe}},10023:(s,o,i)=>{const a=i(6205),INTS=()=>[{type:a.RANGE,from:48,to:57}],WORDS=()=>[{type:a.CHAR,value:95},{type:a.RANGE,from:97,to:122},{type:a.RANGE,from:65,to:90}].concat(INTS()),WHITESPACE=()=>[{type:a.CHAR,value:9},{type:a.CHAR,value:10},{type:a.CHAR,value:11},{type:a.CHAR,value:12},{type:a.CHAR,value:13},{type:a.CHAR,value:32},{type:a.CHAR,value:160},{type:a.CHAR,value:5760},{type:a.RANGE,from:8192,to:8202},{type:a.CHAR,value:8232},{type:a.CHAR,value:8233},{type:a.CHAR,value:8239},{type:a.CHAR,value:8287},{type:a.CHAR,value:12288},{type:a.CHAR,value:65279}];o.words=()=>({type:a.SET,set:WORDS(),not:!1}),o.notWords=()=>({type:a.SET,set:WORDS(),not:!0}),o.ints=()=>({type:a.SET,set:INTS(),not:!1}),o.notInts=()=>({type:a.SET,set:INTS(),not:!0}),o.whitespace=()=>({type:a.SET,set:WHITESPACE(),not:!1}),o.notWhitespace=()=>({type:a.SET,set:WHITESPACE(),not:!0}),o.anyChar=()=>({type:a.SET,set:[{type:a.CHAR,value:10},{type:a.CHAR,value:13},{type:a.CHAR,value:8232},{type:a.CHAR,value:8233}],not:!0})},10043:(s,o,i)=>{"use strict";var a=i(54018),u=String,_=TypeError;s.exports=function(s){if(a(s))return s;throw new _("Can't set "+u(s)+" as a prototype")}},10124:(s,o,i)=>{var a=i(9325);s.exports=function(){return a.Date.now()}},10300:(s,o,i)=>{"use strict";var a=i(13930),u=i(82159),_=i(36624),w=i(4640),x=i(73448),C=TypeError;s.exports=function(s,o){var i=arguments.length<2?x(s):o;if(u(i))return _(a(i,s));throw new C(w(s)+" is not iterable")}},10316:(s,o,i)=>{const a=i(2404),u=i(55973),_=i(92340);class Element{constructor(s,o,i){o&&(this.meta=o),i&&(this.attributes=i),this.content=s}freeze(){Object.isFrozen(this)||(this._meta&&(this.meta.parent=this,this.meta.freeze()),this._attributes&&(this.attributes.parent=this,this.attributes.freeze()),this.children.forEach((s=>{s.parent=this,s.freeze()}),this),this.content&&Array.isArray(this.content)&&Object.freeze(this.content),Object.freeze(this))}primitive(){}clone(){const s=new this.constructor;return s.element=this.element,this.meta.length&&(s._meta=this.meta.clone()),this.attributes.length&&(s._attributes=this.attributes.clone()),this.content?this.content.clone?s.content=this.content.clone():Array.isArray(this.content)?s.content=this.content.map((s=>s.clone())):s.content=this.content:s.content=this.content,s}toValue(){return this.content instanceof Element?this.content.toValue():this.content instanceof u?{key:this.content.key.toValue(),value:this.content.value?this.content.value.toValue():void 0}:this.content&&this.content.map?this.content.map((s=>s.toValue()),this):this.content}toRef(s){if(""===this.id.toValue())throw Error("Cannot create reference to an element that does not contain an ID");const o=new this.RefElement(this.id.toValue());return s&&(o.path=s),o}findRecursive(...s){if(arguments.length>1&&!this.isFrozen)throw new Error("Cannot find recursive with multiple element names without first freezing the element. Call `element.freeze()`");const o=s.pop();let i=new _;const append=(s,o)=>(s.push(o),s),checkElement=(s,i)=>{i.element===o&&s.push(i);const a=i.findRecursive(o);return a&&a.reduce(append,s),i.content instanceof u&&(i.content.key&&checkElement(s,i.content.key),i.content.value&&checkElement(s,i.content.value)),s};return this.content&&(this.content.element&&checkElement(i,this.content),Array.isArray(this.content)&&this.content.reduce(checkElement,i)),s.isEmpty||(i=i.filter((o=>{let i=o.parents.map((s=>s.element));for(const o in s){const a=s[o],u=i.indexOf(a);if(-1===u)return!1;i=i.splice(0,u)}return!0}))),i}set(s){return this.content=s,this}equals(s){return a(this.toValue(),s)}getMetaProperty(s,o){if(!this.meta.hasKey(s)){if(this.isFrozen){const s=this.refract(o);return s.freeze(),s}this.meta.set(s,o)}return this.meta.get(s)}setMetaProperty(s,o){this.meta.set(s,o)}get element(){return this._storedElement||"element"}set element(s){this._storedElement=s}get content(){return this._content}set content(s){if(s instanceof Element)this._content=s;else if(s instanceof _)this.content=s.elements;else if("string"==typeof s||"number"==typeof s||"boolean"==typeof s||"null"===s||null==s)this._content=s;else if(s instanceof u)this._content=s;else if(Array.isArray(s))this._content=s.map(this.refract);else{if("object"!=typeof s)throw new Error("Cannot set content to given value");this._content=Object.keys(s).map((o=>new this.MemberElement(o,s[o])))}}get meta(){if(!this._meta){if(this.isFrozen){const s=new this.ObjectElement;return s.freeze(),s}this._meta=new this.ObjectElement}return this._meta}set meta(s){s instanceof this.ObjectElement?this._meta=s:this.meta.set(s||{})}get attributes(){if(!this._attributes){if(this.isFrozen){const s=new this.ObjectElement;return s.freeze(),s}this._attributes=new this.ObjectElement}return this._attributes}set attributes(s){s instanceof this.ObjectElement?this._attributes=s:this.attributes.set(s||{})}get id(){return this.getMetaProperty("id","")}set id(s){this.setMetaProperty("id",s)}get classes(){return this.getMetaProperty("classes",[])}set classes(s){this.setMetaProperty("classes",s)}get title(){return this.getMetaProperty("title","")}set title(s){this.setMetaProperty("title",s)}get description(){return this.getMetaProperty("description","")}set description(s){this.setMetaProperty("description",s)}get links(){return this.getMetaProperty("links",[])}set links(s){this.setMetaProperty("links",s)}get isFrozen(){return Object.isFrozen(this)}get parents(){let{parent:s}=this;const o=new _;for(;s;)o.push(s),s=s.parent;return o}get children(){if(Array.isArray(this.content))return new _(this.content);if(this.content instanceof u){const s=new _([this.content.key]);return this.content.value&&s.push(this.content.value),s}return this.content instanceof Element?new _([this.content]):new _}get recursiveChildren(){const s=new _;return this.children.forEach((o=>{s.push(o),o.recursiveChildren.forEach((o=>{s.push(o)}))})),s}}s.exports=Element},10392:s=>{s.exports=function getValue(s,o){return null==s?void 0:s[o]}},10776:(s,o,i)=>{var a=i(30756),u=i(95950);s.exports=function getMatchData(s){for(var o=u(s),i=o.length;i--;){var _=o[i],w=s[_];o[i]=[_,w,a(w)]}return o}},10866:(s,o,i)=>{const a=i(6048),u=i(92340);class ObjectSlice extends u{map(s,o){return this.elements.map((i=>s.bind(o)(i.value,i.key,i)))}filter(s,o){return new ObjectSlice(this.elements.filter((i=>s.bind(o)(i.value,i.key,i))))}reject(s,o){return this.filter(a(s.bind(o)))}forEach(s,o){return this.elements.forEach(((i,a)=>{s.bind(o)(i.value,i.key,i,a)}))}keys(){return this.map(((s,o)=>o.toValue()))}values(){return this.map((s=>s.toValue()))}}s.exports=ObjectSlice},11042:(s,o,i)=>{"use strict";var a=i(85582),u=i(1907),_=i(24443),w=i(87170),x=i(36624),C=u([].concat);s.exports=a("Reflect","ownKeys")||function ownKeys(s){var o=_.f(x(s)),i=w.f;return i?C(o,i(s)):o}},11091:(s,o,i)=>{"use strict";var a=i(45951),u=i(76024),_=i(92361),w=i(62250),x=i(13846).f,C=i(7463),j=i(92046),L=i(28311),B=i(61626),$=i(49724);i(36128);var wrapConstructor=function(s){var Wrapper=function(o,i,a){if(this instanceof Wrapper){switch(arguments.length){case 0:return new s;case 1:return new s(o);case 2:return new s(o,i)}return new s(o,i,a)}return u(s,this,arguments)};return Wrapper.prototype=s.prototype,Wrapper};s.exports=function(s,o){var i,u,V,U,z,Y,Z,ee,ie,ae=s.target,ce=s.global,le=s.stat,pe=s.proto,de=ce?a:le?a[ae]:a[ae]&&a[ae].prototype,fe=ce?j:j[ae]||B(j,ae,{})[ae],ye=fe.prototype;for(U in o)u=!(i=C(ce?U:ae+(le?".":"#")+U,s.forced))&&de&&$(de,U),Y=fe[U],u&&(Z=s.dontCallGetSet?(ie=x(de,U))&&ie.value:de[U]),z=u&&Z?Z:o[U],(i||pe||typeof Y!=typeof z)&&(ee=s.bind&&u?L(z,a):s.wrap&&u?wrapConstructor(z):pe&&w(z)?_(z):z,(s.sham||z&&z.sham||Y&&Y.sham)&&B(ee,"sham",!0),B(fe,U,ee),pe&&($(j,V=ae+"Prototype")||B(j,V,{}),B(j[V],U,z),s.real&&ye&&(i||!ye[U])&&B(ye,U,z)))}},11287:s=>{s.exports=function getHolder(s){return s.placeholder}},11331:(s,o,i)=>{var a=i(72552),u=i(28879),_=i(40346),w=Function.prototype,x=Object.prototype,C=w.toString,j=x.hasOwnProperty,L=C.call(Object);s.exports=function isPlainObject(s){if(!_(s)||"[object Object]"!=a(s))return!1;var o=u(s);if(null===o)return!0;var i=j.call(o,"constructor")&&o.constructor;return"function"==typeof i&&i instanceof i&&C.call(i)==L}},11470:(s,o,i)=>{"use strict";var a=i(1907),u=i(65482),_=i(90160),w=i(74239),x=a("".charAt),C=a("".charCodeAt),j=a("".slice),createMethod=function(s){return function(o,i){var a,L,B=_(w(o)),$=u(i),V=B.length;return $<0||$>=V?s?"":void 0:(a=C(B,$))<55296||a>56319||$+1===V||(L=C(B,$+1))<56320||L>57343?s?x(B,$):a:s?j(B,$,$+2):L-56320+(a-55296<<10)+65536}};s.exports={codeAt:createMethod(!1),charAt:createMethod(!0)}},11842:(s,o,i)=>{var a=i(82819),u=i(9325);s.exports=function createBind(s,o,i){var _=1&o,w=a(s);return function wrapper(){return(this&&this!==u&&this instanceof wrapper?w:s).apply(_?i:this,arguments)}}},12242:(s,o,i)=>{const a=i(10316);s.exports=class BooleanElement extends a{constructor(s,o,i){super(s,o,i),this.element="boolean"}primitive(){return"boolean"}}},12507:(s,o,i)=>{var a=i(28754),u=i(49698),_=i(63912),w=i(13222);s.exports=function createCaseFirst(s){return function(o){o=w(o);var i=u(o)?_(o):void 0,x=i?i[0]:o.charAt(0),C=i?a(i,1).join(""):o.slice(1);return x[s]()+C}}},12560:(s,o,i)=>{"use strict";i(99363);var a=i(19287),u=i(45951),_=i(14840),w=i(93742);for(var x in a)_(u[x],x),w[x]=w.Array},12651:(s,o,i)=>{var a=i(74218);s.exports=function getMapData(s,o){var i=s.__data__;return a(o)?i["string"==typeof o?"string":"hash"]:i.map}},12749:(s,o,i)=>{var a=i(81042),u=Object.prototype.hasOwnProperty;s.exports=function hashHas(s){var o=this.__data__;return a?void 0!==o[s]:u.call(o,s)}},13222:(s,o,i)=>{var a=i(77556);s.exports=function toString(s){return null==s?"":a(s)}},13846:(s,o,i)=>{"use strict";var a=i(39447),u=i(13930),_=i(22574),w=i(75817),x=i(4993),C=i(70470),j=i(49724),L=i(73648),B=Object.getOwnPropertyDescriptor;o.f=a?B:function getOwnPropertyDescriptor(s,o){if(s=x(s),o=C(o),L)try{return B(s,o)}catch(s){}if(j(s,o))return w(!u(_.f,s,o),s[o])}},13930:(s,o,i)=>{"use strict";var a=i(41505),u=Function.prototype.call;s.exports=a?u.bind(u):function(){return u.apply(u,arguments)}},14248:s=>{s.exports=function arraySome(s,o){for(var i=-1,a=null==s?0:s.length;++i{s.exports=function arrayPush(s,o){for(var i=-1,a=o.length,u=s.length;++i{const a=i(10316);s.exports=class RefElement extends a{constructor(s,o,i){super(s||[],o,i),this.element="ref",this.path||(this.path="element")}get path(){return this.attributes.get("path")}set path(s){this.attributes.set("path",s)}}},14744:s=>{"use strict";var o=function isMergeableObject(s){return function isNonNullObject(s){return!!s&&"object"==typeof s}(s)&&!function isSpecial(s){var o=Object.prototype.toString.call(s);return"[object RegExp]"===o||"[object Date]"===o||function isReactElement(s){return s.$$typeof===i}(s)}(s)};var i="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function cloneUnlessOtherwiseSpecified(s,o){return!1!==o.clone&&o.isMergeableObject(s)?deepmerge(function emptyTarget(s){return Array.isArray(s)?[]:{}}(s),s,o):s}function defaultArrayMerge(s,o,i){return s.concat(o).map((function(s){return cloneUnlessOtherwiseSpecified(s,i)}))}function getKeys(s){return Object.keys(s).concat(function getEnumerableOwnPropertySymbols(s){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(s).filter((function(o){return Object.propertyIsEnumerable.call(s,o)})):[]}(s))}function propertyIsOnObject(s,o){try{return o in s}catch(s){return!1}}function mergeObject(s,o,i){var a={};return i.isMergeableObject(s)&&getKeys(s).forEach((function(o){a[o]=cloneUnlessOtherwiseSpecified(s[o],i)})),getKeys(o).forEach((function(u){(function propertyIsUnsafe(s,o){return propertyIsOnObject(s,o)&&!(Object.hasOwnProperty.call(s,o)&&Object.propertyIsEnumerable.call(s,o))})(s,u)||(propertyIsOnObject(s,u)&&i.isMergeableObject(o[u])?a[u]=function getMergeFunction(s,o){if(!o.customMerge)return deepmerge;var i=o.customMerge(s);return"function"==typeof i?i:deepmerge}(u,i)(s[u],o[u],i):a[u]=cloneUnlessOtherwiseSpecified(o[u],i))})),a}function deepmerge(s,i,a){(a=a||{}).arrayMerge=a.arrayMerge||defaultArrayMerge,a.isMergeableObject=a.isMergeableObject||o,a.cloneUnlessOtherwiseSpecified=cloneUnlessOtherwiseSpecified;var u=Array.isArray(i);return u===Array.isArray(s)?u?a.arrayMerge(s,i,a):mergeObject(s,i,a):cloneUnlessOtherwiseSpecified(i,a)}deepmerge.all=function deepmergeAll(s,o){if(!Array.isArray(s))throw new Error("first argument should be an array");return s.reduce((function(s,i){return deepmerge(s,i,o)}),{})};var a=deepmerge;s.exports=a},14792:(s,o,i)=>{var a=i(13222),u=i(55808);s.exports=function capitalize(s){return u(a(s).toLowerCase())}},14840:(s,o,i)=>{"use strict";var a=i(52623),u=i(74284).f,_=i(61626),w=i(49724),x=i(54878),C=i(76264)("toStringTag");s.exports=function(s,o,i,j){var L=i?s:s&&s.prototype;L&&(w(L,C)||u(L,C,{configurable:!0,value:o}),j&&!a&&_(L,"toString",x))}},14974:s=>{s.exports=function safeGet(s,o){if(("constructor"!==o||"function"!=typeof s[o])&&"__proto__"!=o)return s[o]}},15287:(s,o)=>{"use strict";var i=Symbol.for("react.element"),a=Symbol.for("react.portal"),u=Symbol.for("react.fragment"),_=Symbol.for("react.strict_mode"),w=Symbol.for("react.profiler"),x=Symbol.for("react.provider"),C=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),L=Symbol.for("react.suspense"),B=Symbol.for("react.memo"),$=Symbol.for("react.lazy"),V=Symbol.iterator;var U={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},z=Object.assign,Y={};function E(s,o,i){this.props=s,this.context=o,this.refs=Y,this.updater=i||U}function F(){}function G(s,o,i){this.props=s,this.context=o,this.refs=Y,this.updater=i||U}E.prototype.isReactComponent={},E.prototype.setState=function(s,o){if("object"!=typeof s&&"function"!=typeof s&&null!=s)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,s,o,"setState")},E.prototype.forceUpdate=function(s){this.updater.enqueueForceUpdate(this,s,"forceUpdate")},F.prototype=E.prototype;var Z=G.prototype=new F;Z.constructor=G,z(Z,E.prototype),Z.isPureReactComponent=!0;var ee=Array.isArray,ie=Object.prototype.hasOwnProperty,ae={current:null},ce={key:!0,ref:!0,__self:!0,__source:!0};function M(s,o,a){var u,_={},w=null,x=null;if(null!=o)for(u in void 0!==o.ref&&(x=o.ref),void 0!==o.key&&(w=""+o.key),o)ie.call(o,u)&&!ce.hasOwnProperty(u)&&(_[u]=o[u]);var C=arguments.length-2;if(1===C)_.children=a;else if(1{var a=i(96131);s.exports=function arrayIncludes(s,o){return!!(null==s?0:s.length)&&a(s,o,0)>-1}},15340:()=>{},15389:(s,o,i)=>{var a=i(93663),u=i(87978),_=i(83488),w=i(56449),x=i(50583);s.exports=function baseIteratee(s){return"function"==typeof s?s:null==s?_:"object"==typeof s?w(s)?u(s[0],s[1]):a(s):x(s)}},15972:(s,o,i)=>{"use strict";var a=i(49724),u=i(62250),_=i(39298),w=i(92522),x=i(57382),C=w("IE_PROTO"),j=Object,L=j.prototype;s.exports=x?j.getPrototypeOf:function(s){var o=_(s);if(a(o,C))return o[C];var i=o.constructor;return u(i)&&o instanceof i?i.prototype:o instanceof j?L:null}},16038:(s,o,i)=>{var a=i(5861),u=i(40346);s.exports=function baseIsSet(s){return u(s)&&"[object Set]"==a(s)}},16426:s=>{s.exports=function(){var s=document.getSelection();if(!s.rangeCount)return function(){};for(var o=document.activeElement,i=[],a=0;a{var a=i(43360),u=i(75288),_=Object.prototype.hasOwnProperty;s.exports=function assignValue(s,o,i){var w=s[o];_.call(s,o)&&u(w,i)&&(void 0!==i||o in s)||a(s,o,i)}},16708:(s,o,i)=>{"use strict";var a,u=i(65606);function CorkedRequest(s){var o=this;this.next=null,this.entry=null,this.finish=function(){!function onCorkedFinish(s,o,i){var a=s.entry;s.entry=null;for(;a;){var u=a.callback;o.pendingcb--,u(i),a=a.next}o.corkedRequestsFree.next=s}(o,s)}}s.exports=Writable,Writable.WritableState=WritableState;var _={deprecate:i(94643)},w=i(40345),x=i(48287).Buffer,C=(void 0!==i.g?i.g:"undefined"!=typeof window?window:"undefined"!=typeof self?self:{}).Uint8Array||function(){};var j,L=i(75896),B=i(65291).getHighWaterMark,$=i(86048).F,V=$.ERR_INVALID_ARG_TYPE,U=$.ERR_METHOD_NOT_IMPLEMENTED,z=$.ERR_MULTIPLE_CALLBACK,Y=$.ERR_STREAM_CANNOT_PIPE,Z=$.ERR_STREAM_DESTROYED,ee=$.ERR_STREAM_NULL_VALUES,ie=$.ERR_STREAM_WRITE_AFTER_END,ae=$.ERR_UNKNOWN_ENCODING,ce=L.errorOrDestroy;function nop(){}function WritableState(s,o,_){a=a||i(25382),s=s||{},"boolean"!=typeof _&&(_=o instanceof a),this.objectMode=!!s.objectMode,_&&(this.objectMode=this.objectMode||!!s.writableObjectMode),this.highWaterMark=B(this,s,"writableHighWaterMark",_),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var w=!1===s.decodeStrings;this.decodeStrings=!w,this.defaultEncoding=s.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(s){!function onwrite(s,o){var i=s._writableState,a=i.sync,_=i.writecb;if("function"!=typeof _)throw new z;if(function onwriteStateUpdate(s){s.writing=!1,s.writecb=null,s.length-=s.writelen,s.writelen=0}(i),o)!function onwriteError(s,o,i,a,_){--o.pendingcb,i?(u.nextTick(_,a),u.nextTick(finishMaybe,s,o),s._writableState.errorEmitted=!0,ce(s,a)):(_(a),s._writableState.errorEmitted=!0,ce(s,a),finishMaybe(s,o))}(s,i,a,o,_);else{var w=needFinish(i)||s.destroyed;w||i.corked||i.bufferProcessing||!i.bufferedRequest||clearBuffer(s,i),a?u.nextTick(afterWrite,s,i,w,_):afterWrite(s,i,w,_)}}(o,s)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==s.emitClose,this.autoDestroy=!!s.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new CorkedRequest(this)}function Writable(s){var o=this instanceof(a=a||i(25382));if(!o&&!j.call(Writable,this))return new Writable(s);this._writableState=new WritableState(s,this,o),this.writable=!0,s&&("function"==typeof s.write&&(this._write=s.write),"function"==typeof s.writev&&(this._writev=s.writev),"function"==typeof s.destroy&&(this._destroy=s.destroy),"function"==typeof s.final&&(this._final=s.final)),w.call(this)}function doWrite(s,o,i,a,u,_,w){o.writelen=a,o.writecb=w,o.writing=!0,o.sync=!0,o.destroyed?o.onwrite(new Z("write")):i?s._writev(u,o.onwrite):s._write(u,_,o.onwrite),o.sync=!1}function afterWrite(s,o,i,a){i||function onwriteDrain(s,o){0===o.length&&o.needDrain&&(o.needDrain=!1,s.emit("drain"))}(s,o),o.pendingcb--,a(),finishMaybe(s,o)}function clearBuffer(s,o){o.bufferProcessing=!0;var i=o.bufferedRequest;if(s._writev&&i&&i.next){var a=o.bufferedRequestCount,u=new Array(a),_=o.corkedRequestsFree;_.entry=i;for(var w=0,x=!0;i;)u[w]=i,i.isBuf||(x=!1),i=i.next,w+=1;u.allBuffers=x,doWrite(s,o,!0,o.length,u,"",_.finish),o.pendingcb++,o.lastBufferedRequest=null,_.next?(o.corkedRequestsFree=_.next,_.next=null):o.corkedRequestsFree=new CorkedRequest(o),o.bufferedRequestCount=0}else{for(;i;){var C=i.chunk,j=i.encoding,L=i.callback;if(doWrite(s,o,!1,o.objectMode?1:C.length,C,j,L),i=i.next,o.bufferedRequestCount--,o.writing)break}null===i&&(o.lastBufferedRequest=null)}o.bufferedRequest=i,o.bufferProcessing=!1}function needFinish(s){return s.ending&&0===s.length&&null===s.bufferedRequest&&!s.finished&&!s.writing}function callFinal(s,o){s._final((function(i){o.pendingcb--,i&&ce(s,i),o.prefinished=!0,s.emit("prefinish"),finishMaybe(s,o)}))}function finishMaybe(s,o){var i=needFinish(o);if(i&&(function prefinish(s,o){o.prefinished||o.finalCalled||("function"!=typeof s._final||o.destroyed?(o.prefinished=!0,s.emit("prefinish")):(o.pendingcb++,o.finalCalled=!0,u.nextTick(callFinal,s,o)))}(s,o),0===o.pendingcb&&(o.finished=!0,s.emit("finish"),o.autoDestroy))){var a=s._readableState;(!a||a.autoDestroy&&a.endEmitted)&&s.destroy()}return i}i(56698)(Writable,w),WritableState.prototype.getBuffer=function getBuffer(){for(var s=this.bufferedRequest,o=[];s;)o.push(s),s=s.next;return o},function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:_.deprecate((function writableStateBufferGetter(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(s){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(j=Function.prototype[Symbol.hasInstance],Object.defineProperty(Writable,Symbol.hasInstance,{value:function value(s){return!!j.call(this,s)||this===Writable&&(s&&s._writableState instanceof WritableState)}})):j=function realHasInstance(s){return s instanceof this},Writable.prototype.pipe=function(){ce(this,new Y)},Writable.prototype.write=function(s,o,i){var a=this._writableState,_=!1,w=!a.objectMode&&function _isUint8Array(s){return x.isBuffer(s)||s instanceof C}(s);return w&&!x.isBuffer(s)&&(s=function _uint8ArrayToBuffer(s){return x.from(s)}(s)),"function"==typeof o&&(i=o,o=null),w?o="buffer":o||(o=a.defaultEncoding),"function"!=typeof i&&(i=nop),a.ending?function writeAfterEnd(s,o){var i=new ie;ce(s,i),u.nextTick(o,i)}(this,i):(w||function validChunk(s,o,i,a){var _;return null===i?_=new ee:"string"==typeof i||o.objectMode||(_=new V("chunk",["string","Buffer"],i)),!_||(ce(s,_),u.nextTick(a,_),!1)}(this,a,s,i))&&(a.pendingcb++,_=function writeOrBuffer(s,o,i,a,u,_){if(!i){var w=function decodeChunk(s,o,i){s.objectMode||!1===s.decodeStrings||"string"!=typeof o||(o=x.from(o,i));return o}(o,a,u);a!==w&&(i=!0,u="buffer",a=w)}var C=o.objectMode?1:a.length;o.length+=C;var j=o.length-1))throw new ae(s);return this._writableState.defaultEncoding=s,this},Object.defineProperty(Writable.prototype,"writableBuffer",{enumerable:!1,get:function get(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(Writable.prototype,"writableHighWaterMark",{enumerable:!1,get:function get(){return this._writableState.highWaterMark}}),Writable.prototype._write=function(s,o,i){i(new U("_write()"))},Writable.prototype._writev=null,Writable.prototype.end=function(s,o,i){var a=this._writableState;return"function"==typeof s?(i=s,s=null,o=null):"function"==typeof o&&(i=o,o=null),null!=s&&this.write(s,o),a.corked&&(a.corked=1,this.uncork()),a.ending||function endWritable(s,o,i){o.ending=!0,finishMaybe(s,o),i&&(o.finished?u.nextTick(i):s.once("finish",i));o.ended=!0,s.writable=!1}(this,a,i),this},Object.defineProperty(Writable.prototype,"writableLength",{enumerable:!1,get:function get(){return this._writableState.length}}),Object.defineProperty(Writable.prototype,"destroyed",{enumerable:!1,get:function get(){return void 0!==this._writableState&&this._writableState.destroyed},set:function set(s){this._writableState&&(this._writableState.destroyed=s)}}),Writable.prototype.destroy=L.destroy,Writable.prototype._undestroy=L.undestroy,Writable.prototype._destroy=function(s,o){o(s)}},16946:(s,o,i)=>{"use strict";var a=i(1907),u=i(98828),_=i(45807),w=Object,x=a("".split);s.exports=u((function(){return!w("z").propertyIsEnumerable(0)}))?function(s){return"String"===_(s)?x(s,""):w(s)}:w},16962:(s,o)=>{o.aliasToReal={each:"forEach",eachRight:"forEachRight",entries:"toPairs",entriesIn:"toPairsIn",extend:"assignIn",extendAll:"assignInAll",extendAllWith:"assignInAllWith",extendWith:"assignInWith",first:"head",conforms:"conformsTo",matches:"isMatch",property:"get",__:"placeholder",F:"stubFalse",T:"stubTrue",all:"every",allPass:"overEvery",always:"constant",any:"some",anyPass:"overSome",apply:"spread",assoc:"set",assocPath:"set",complement:"negate",compose:"flowRight",contains:"includes",dissoc:"unset",dissocPath:"unset",dropLast:"dropRight",dropLastWhile:"dropRightWhile",equals:"isEqual",identical:"eq",indexBy:"keyBy",init:"initial",invertObj:"invert",juxt:"over",omitAll:"omit",nAry:"ary",path:"get",pathEq:"matchesProperty",pathOr:"getOr",paths:"at",pickAll:"pick",pipe:"flow",pluck:"map",prop:"get",propEq:"matchesProperty",propOr:"getOr",props:"at",symmetricDifference:"xor",symmetricDifferenceBy:"xorBy",symmetricDifferenceWith:"xorWith",takeLast:"takeRight",takeLastWhile:"takeRightWhile",unapply:"rest",unnest:"flatten",useWith:"overArgs",where:"conformsTo",whereEq:"isMatch",zipObj:"zipObject"},o.aryMethod={1:["assignAll","assignInAll","attempt","castArray","ceil","create","curry","curryRight","defaultsAll","defaultsDeepAll","floor","flow","flowRight","fromPairs","invert","iteratee","memoize","method","mergeAll","methodOf","mixin","nthArg","over","overEvery","overSome","rest","reverse","round","runInContext","spread","template","trim","trimEnd","trimStart","uniqueId","words","zipAll"],2:["add","after","ary","assign","assignAllWith","assignIn","assignInAllWith","at","before","bind","bindAll","bindKey","chunk","cloneDeepWith","cloneWith","concat","conformsTo","countBy","curryN","curryRightN","debounce","defaults","defaultsDeep","defaultTo","delay","difference","divide","drop","dropRight","dropRightWhile","dropWhile","endsWith","eq","every","filter","find","findIndex","findKey","findLast","findLastIndex","findLastKey","flatMap","flatMapDeep","flattenDepth","forEach","forEachRight","forIn","forInRight","forOwn","forOwnRight","get","groupBy","gt","gte","has","hasIn","includes","indexOf","intersection","invertBy","invoke","invokeMap","isEqual","isMatch","join","keyBy","lastIndexOf","lt","lte","map","mapKeys","mapValues","matchesProperty","maxBy","meanBy","merge","mergeAllWith","minBy","multiply","nth","omit","omitBy","overArgs","pad","padEnd","padStart","parseInt","partial","partialRight","partition","pick","pickBy","propertyOf","pull","pullAll","pullAt","random","range","rangeRight","rearg","reject","remove","repeat","restFrom","result","sampleSize","some","sortBy","sortedIndex","sortedIndexOf","sortedLastIndex","sortedLastIndexOf","sortedUniqBy","split","spreadFrom","startsWith","subtract","sumBy","take","takeRight","takeRightWhile","takeWhile","tap","throttle","thru","times","trimChars","trimCharsEnd","trimCharsStart","truncate","union","uniqBy","uniqWith","unset","unzipWith","without","wrap","xor","zip","zipObject","zipObjectDeep"],3:["assignInWith","assignWith","clamp","differenceBy","differenceWith","findFrom","findIndexFrom","findLastFrom","findLastIndexFrom","getOr","includesFrom","indexOfFrom","inRange","intersectionBy","intersectionWith","invokeArgs","invokeArgsMap","isEqualWith","isMatchWith","flatMapDepth","lastIndexOfFrom","mergeWith","orderBy","padChars","padCharsEnd","padCharsStart","pullAllBy","pullAllWith","rangeStep","rangeStepRight","reduce","reduceRight","replace","set","slice","sortedIndexBy","sortedLastIndexBy","transform","unionBy","unionWith","update","xorBy","xorWith","zipWith"],4:["fill","setWith","updateWith"]},o.aryRearg={2:[1,0],3:[2,0,1],4:[3,2,0,1]},o.iterateeAry={dropRightWhile:1,dropWhile:1,every:1,filter:1,find:1,findFrom:1,findIndex:1,findIndexFrom:1,findKey:1,findLast:1,findLastFrom:1,findLastIndex:1,findLastIndexFrom:1,findLastKey:1,flatMap:1,flatMapDeep:1,flatMapDepth:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},o.iterateeRearg={mapKeys:[1],reduceRight:[1,0]},o.methodRearg={assignInAllWith:[1,0],assignInWith:[1,2,0],assignAllWith:[1,0],assignWith:[1,2,0],differenceBy:[1,2,0],differenceWith:[1,2,0],getOr:[2,1,0],intersectionBy:[1,2,0],intersectionWith:[1,2,0],isEqualWith:[1,2,0],isMatchWith:[2,1,0],mergeAllWith:[1,0],mergeWith:[1,2,0],padChars:[2,1,0],padCharsEnd:[2,1,0],padCharsStart:[2,1,0],pullAllBy:[2,1,0],pullAllWith:[2,1,0],rangeStep:[1,2,0],rangeStepRight:[1,2,0],setWith:[3,1,2,0],sortedIndexBy:[2,1,0],sortedLastIndexBy:[2,1,0],unionBy:[1,2,0],unionWith:[1,2,0],updateWith:[3,1,2,0],xorBy:[1,2,0],xorWith:[1,2,0],zipWith:[1,2,0]},o.methodSpread={assignAll:{start:0},assignAllWith:{start:0},assignInAll:{start:0},assignInAllWith:{start:0},defaultsAll:{start:0},defaultsDeepAll:{start:0},invokeArgs:{start:2},invokeArgsMap:{start:2},mergeAll:{start:0},mergeAllWith:{start:0},partial:{start:1},partialRight:{start:1},without:{start:1},zipAll:{start:0}},o.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAllWith:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignAll:!0,assignAllWith:!0,assignIn:!0,assignInAll:!0,assignInAllWith:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsAll:!0,defaultsDeep:!0,defaultsDeepAll:!0,merge:!0,mergeAll:!0,mergeAllWith:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0,update:!0,updateWith:!0}},o.realToAlias=function(){var s=Object.prototype.hasOwnProperty,i=o.aliasToReal,a={};for(var u in i){var _=i[u];s.call(a,_)?a[_].push(u):a[_]=[u]}return a}(),o.remap={assignAll:"assign",assignAllWith:"assignWith",assignInAll:"assignIn",assignInAllWith:"assignInWith",curryN:"curry",curryRightN:"curryRight",defaultsAll:"defaults",defaultsDeepAll:"defaultsDeep",findFrom:"find",findIndexFrom:"findIndex",findLastFrom:"findLast",findLastIndexFrom:"findLastIndex",getOr:"get",includesFrom:"includes",indexOfFrom:"indexOf",invokeArgs:"invoke",invokeArgsMap:"invokeMap",lastIndexOfFrom:"lastIndexOf",mergeAll:"merge",mergeAllWith:"mergeWith",padChars:"pad",padCharsEnd:"padEnd",padCharsStart:"padStart",propertyOf:"get",rangeStep:"range",rangeStepRight:"rangeRight",restFrom:"rest",spreadFrom:"spread",trimChars:"trim",trimCharsEnd:"trimEnd",trimCharsStart:"trimStart",zipAll:"zip"},o.skipFixed={castArray:!0,flow:!0,flowRight:!0,iteratee:!0,mixin:!0,rearg:!0,runInContext:!0},o.skipRearg={add:!0,assign:!0,assignIn:!0,bind:!0,bindKey:!0,concat:!0,difference:!0,divide:!0,eq:!0,gt:!0,gte:!0,isEqual:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,multiply:!0,overArgs:!0,partial:!0,partialRight:!0,propertyOf:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,zip:!0,zipObject:!0,zipObjectDeep:!0}},17255:(s,o,i)=>{var a=i(47422);s.exports=function basePropertyDeep(s){return function(o){return a(o,s)}}},17285:s=>{function source(s){return s?"string"==typeof s?s:s.source:null}function lookahead(s){return concat("(?=",s,")")}function concat(...s){return s.map((s=>source(s))).join("")}function either(...s){return"("+s.map((s=>source(s))).join("|")+")"}s.exports=function xml(s){const o=concat(/[A-Z_]/,function optional(s){return concat("(",s,")?")}(/[A-Z0-9_.-]*:/),/[A-Z0-9_.-]*/),i={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},a={begin:/\s/,contains:[{className:"meta-keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},u=s.inherit(a,{begin:/\(/,end:/\)/}),_=s.inherit(s.APOS_STRING_MODE,{className:"meta-string"}),w=s.inherit(s.QUOTE_STRING_MODE,{className:"meta-string"}),x={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin://,relevance:10,contains:[a,w,_,u,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[a,u,w,_]}]}]},s.COMMENT(//,{relevance:10}),{begin://,relevance:10},i,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[x],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[x],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:concat(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:o,relevance:0,starts:x}]},{className:"tag",begin:concat(/<\//,lookahead(concat(o,/>/))),contains:[{className:"name",begin:o,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}},17400:(s,o,i)=>{var a=i(99374),u=1/0;s.exports=function toFinite(s){return s?(s=a(s))===u||s===-1/0?17976931348623157e292*(s<0?-1:1):s==s?s:0:0===s?s:0}},17533:s=>{s.exports=function yaml(s){var o="true false yes no null",i="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[s.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},u=s.inherit(a,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),_={className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},w={end:",",endsWithParent:!0,excludeEnd:!0,keywords:o,relevance:0},x={begin:/\{/,end:/\}/,contains:[w],illegal:"\\n",relevance:0},C={begin:"\\[",end:"\\]",contains:[w],illegal:"\\n",relevance:0},j=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+i},{className:"type",begin:"!<"+i+">"},{className:"type",begin:"!"+i},{className:"type",begin:"!!"+i},{className:"meta",begin:"&"+s.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+s.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},s.HASH_COMMENT_MODE,{beginKeywords:o,keywords:{literal:o}},_,{className:"number",begin:s.C_NUMBER_RE+"\\b",relevance:0},x,C,a],L=[...j];return L.pop(),L.push(u),w.contains=L,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:j}}},17670:(s,o,i)=>{var a=i(12651);s.exports=function mapCacheDelete(s){var o=a(this,s).delete(s);return this.size-=o?1:0,o}},17965:(s,o,i)=>{"use strict";var a=i(16426),u={"text/plain":"Text","text/html":"Url",default:"Text"};s.exports=function copy(s,o){var i,_,w,x,C,j,L=!1;o||(o={}),i=o.debug||!1;try{if(w=a(),x=document.createRange(),C=document.getSelection(),(j=document.createElement("span")).textContent=s,j.ariaHidden="true",j.style.all="unset",j.style.position="fixed",j.style.top=0,j.style.clip="rect(0, 0, 0, 0)",j.style.whiteSpace="pre",j.style.webkitUserSelect="text",j.style.MozUserSelect="text",j.style.msUserSelect="text",j.style.userSelect="text",j.addEventListener("copy",(function(a){if(a.stopPropagation(),o.format)if(a.preventDefault(),void 0===a.clipboardData){i&&console.warn("unable to use e.clipboardData"),i&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var _=u[o.format]||u.default;window.clipboardData.setData(_,s)}else a.clipboardData.clearData(),a.clipboardData.setData(o.format,s);o.onCopy&&(a.preventDefault(),o.onCopy(a.clipboardData))})),document.body.appendChild(j),x.selectNodeContents(j),C.addRange(x),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");L=!0}catch(a){i&&console.error("unable to copy using execCommand: ",a),i&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(o.format||"text",s),o.onCopy&&o.onCopy(window.clipboardData),L=!0}catch(a){i&&console.error("unable to copy using clipboardData: ",a),i&&console.error("falling back to prompt"),_=function format(s){var o=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C";return s.replace(/#{\s*key\s*}/g,o)}("message"in o?o.message:"Copy to clipboard: #{key}, Enter"),window.prompt(_,s)}}finally{C&&("function"==typeof C.removeRange?C.removeRange(x):C.removeAllRanges()),j&&document.body.removeChild(j),w()}return L}},18073:(s,o,i)=>{var a=i(85087),u=i(54641),_=i(70981);s.exports=function createRecurry(s,o,i,w,x,C,j,L,B,$){var V=8&o;o|=V?32:64,4&(o&=~(V?64:32))||(o&=-4);var U=[s,o,x,V?C:void 0,V?j:void 0,V?void 0:C,V?void 0:j,L,B,$],z=i.apply(void 0,U);return a(s)&&u(z,U),z.placeholder=w,_(z,s,o)}},19123:(s,o,i)=>{var a=i(65606),u=i(31499),_=i(88310).Stream;function resolve(s,o,i){var a,_=function create_indent(s,o){return new Array(o||0).join(s||"")}(o,i=i||0),w=s;if("object"==typeof s&&((w=s[a=Object.keys(s)[0]])&&w._elem))return w._elem.name=a,w._elem.icount=i,w._elem.indent=o,w._elem.indents=_,w._elem.interrupt=w,w._elem;var x,C=[],j=[];function get_attributes(s){Object.keys(s).forEach((function(o){C.push(function attribute(s,o){return s+'="'+u(o)+'"'}(o,s[o]))}))}switch(typeof w){case"object":if(null===w)break;w._attr&&get_attributes(w._attr),w._cdata&&j.push(("/g,"]]]]>")+"]]>"),w.forEach&&(x=!1,j.push(""),w.forEach((function(s){"object"==typeof s?"_attr"==Object.keys(s)[0]?get_attributes(s._attr):j.push(resolve(s,o,i+1)):(j.pop(),x=!0,j.push(u(s)))})),x||j.push(""));break;default:j.push(u(w))}return{name:a,interrupt:!1,attributes:C,content:j,icount:i,indents:_,indent:o}}function format(s,o,i){if("object"!=typeof o)return s(!1,o);var a=o.interrupt?1:o.content.length;function proceed(){for(;o.content.length;){var u=o.content.shift();if(void 0!==u){if(interrupt(u))return;format(s,u)}}s(!1,(a>1?o.indents:"")+(o.name?"":"")+(o.indent&&!i?"\n":"")),i&&i()}function interrupt(o){return!!o.interrupt&&(o.interrupt.append=s,o.interrupt.end=proceed,o.interrupt=!1,s(!0),!0)}if(s(!1,o.indents+(o.name?"<"+o.name:"")+(o.attributes.length?" "+o.attributes.join(" "):"")+(a?o.name?">":"":o.name?"/>":"")+(o.indent&&a>1?"\n":"")),!a)return s(!1,o.indent?"\n":"");interrupt(o)||proceed()}s.exports=function xml(s,o){"object"!=typeof o&&(o={indent:o});var i=o.stream?new _:null,u="",w=!1,x=o.indent?!0===o.indent?" ":o.indent:"",C=!0;function delay(s){C?a.nextTick(s):s()}function append(s,o){if(void 0!==o&&(u+=o),s&&!w&&(i=i||new _,w=!0),s&&w){var a=u;delay((function(){i.emit("data",a)})),u=""}}function add(s,o){format(append,resolve(s,x,x?1:0),o)}function end(){if(i){var s=u;delay((function(){i.emit("data",s),i.emit("end"),i.readable=!1,i.emit("close")}))}}return delay((function(){C=!1})),o.declaration&&function addXmlDeclaration(s){var o={version:"1.0",encoding:s.encoding||"UTF-8"};s.standalone&&(o.standalone=s.standalone),add({"?xml":{_attr:o}}),u=u.replace("/>","?>")}(o.declaration),s&&s.forEach?s.forEach((function(o,i){var a;i+1===s.length&&(a=end),add(o,a)})):add(s,end),i?(i.readable=!0,i):u},s.exports.element=s.exports.Element=function element(){var s={_elem:resolve(Array.prototype.slice.call(arguments)),push:function(s){if(!this.append)throw new Error("not assigned to a parent!");var o=this,i=this._elem.indent;format(this.append,resolve(s,i,this._elem.icount+(i?1:0)),(function(){o.append(!0)}))},close:function(s){void 0!==s&&this.push(s),this.end&&this.end()}};return s}},19219:s=>{s.exports=function cacheHas(s,o){return s.has(o)}},19287:s=>{"use strict";s.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},19358:(s,o,i)=>{"use strict";var a=i(85582),u=i(49724),_=i(61626),w=i(88280),x=i(79192),C=i(19595),j=i(54829),L=i(34084),B=i(32096),$=i(39259),V=i(85884),U=i(39447),z=i(7376);s.exports=function(s,o,i,Y){var Z="stackTraceLimit",ee=Y?2:1,ie=s.split("."),ae=ie[ie.length-1],ce=a.apply(null,ie);if(ce){var le=ce.prototype;if(!z&&u(le,"cause")&&delete le.cause,!i)return ce;var pe=a("Error"),de=o((function(s,o){var i=B(Y?o:s,void 0),a=Y?new ce(s):new ce;return void 0!==i&&_(a,"message",i),V(a,de,a.stack,2),this&&w(le,this)&&L(a,this,de),arguments.length>ee&&$(a,arguments[ee]),a}));if(de.prototype=le,"Error"!==ae?x?x(de,pe):C(de,pe,{name:!0}):U&&Z in ce&&(j(de,ce,Z),j(de,ce,"prepareStackTrace")),C(de,ce),!z)try{le.name!==ae&&_(le,"name",ae),le.constructor=de}catch(s){}return de}}},19570:(s,o,i)=>{var a=i(37334),u=i(93243),_=i(83488),w=u?function(s,o){return u(s,"toString",{configurable:!0,enumerable:!1,value:a(o),writable:!0})}:_;s.exports=w},19595:(s,o,i)=>{"use strict";var a=i(49724),u=i(11042),_=i(13846),w=i(74284);s.exports=function(s,o,i){for(var x=u(o),C=w.f,j=_.f,L=0;L{"use strict";var a=i(23034);s.exports=a},19846:(s,o,i)=>{"use strict";var a=i(20798),u=i(98828),_=i(45951).String;s.exports=!!Object.getOwnPropertySymbols&&!u((function(){var s=Symbol("symbol detection");return!_(s)||!(Object(s)instanceof Symbol)||!Symbol.sham&&a&&a<41}))},19931:(s,o,i)=>{var a=i(31769),u=i(68090),_=i(68969),w=i(77797);s.exports=function baseUnset(s,o){return o=a(o,s),null==(s=_(s,o))||delete s[w(u(o))]}},20181:(s,o,i)=>{var a=/^\s+|\s+$/g,u=/^[-+]0x[0-9a-f]+$/i,_=/^0b[01]+$/i,w=/^0o[0-7]+$/i,x=parseInt,C="object"==typeof i.g&&i.g&&i.g.Object===Object&&i.g,j="object"==typeof self&&self&&self.Object===Object&&self,L=C||j||Function("return this")(),B=Object.prototype.toString,$=Math.max,V=Math.min,now=function(){return L.Date.now()};function isObject(s){var o=typeof s;return!!s&&("object"==o||"function"==o)}function toNumber(s){if("number"==typeof s)return s;if(function isSymbol(s){return"symbol"==typeof s||function isObjectLike(s){return!!s&&"object"==typeof s}(s)&&"[object Symbol]"==B.call(s)}(s))return NaN;if(isObject(s)){var o="function"==typeof s.valueOf?s.valueOf():s;s=isObject(o)?o+"":o}if("string"!=typeof s)return 0===s?s:+s;s=s.replace(a,"");var i=_.test(s);return i||w.test(s)?x(s.slice(2),i?2:8):u.test(s)?NaN:+s}s.exports=function debounce(s,o,i){var a,u,_,w,x,C,j=0,L=!1,B=!1,U=!0;if("function"!=typeof s)throw new TypeError("Expected a function");function invokeFunc(o){var i=a,_=u;return a=u=void 0,j=o,w=s.apply(_,i)}function shouldInvoke(s){var i=s-C;return void 0===C||i>=o||i<0||B&&s-j>=_}function timerExpired(){var s=now();if(shouldInvoke(s))return trailingEdge(s);x=setTimeout(timerExpired,function remainingWait(s){var i=o-(s-C);return B?V(i,_-(s-j)):i}(s))}function trailingEdge(s){return x=void 0,U&&a?invokeFunc(s):(a=u=void 0,w)}function debounced(){var s=now(),i=shouldInvoke(s);if(a=arguments,u=this,C=s,i){if(void 0===x)return function leadingEdge(s){return j=s,x=setTimeout(timerExpired,o),L?invokeFunc(s):w}(C);if(B)return x=setTimeout(timerExpired,o),invokeFunc(C)}return void 0===x&&(x=setTimeout(timerExpired,o)),w}return o=toNumber(o)||0,isObject(i)&&(L=!!i.leading,_=(B="maxWait"in i)?$(toNumber(i.maxWait)||0,o):_,U="trailing"in i?!!i.trailing:U),debounced.cancel=function cancel(){void 0!==x&&clearTimeout(x),j=0,a=C=u=x=void 0},debounced.flush=function flush(){return void 0===x?w:trailingEdge(now())},debounced}},20317:s=>{s.exports=function mapToArray(s){var o=-1,i=Array(s.size);return s.forEach((function(s,a){i[++o]=[a,s]})),i}},20334:(s,o,i)=>{"use strict";var a=i(48287).Buffer;class NonError extends Error{constructor(s){super(NonError._prepareSuperMessage(s)),Object.defineProperty(this,"name",{value:"NonError",configurable:!0,writable:!0}),Error.captureStackTrace&&Error.captureStackTrace(this,NonError)}static _prepareSuperMessage(s){try{return JSON.stringify(s)}catch{return String(s)}}}const u=[{property:"name",enumerable:!1},{property:"message",enumerable:!1},{property:"stack",enumerable:!1},{property:"code",enumerable:!0}],_=Symbol(".toJSON called"),destroyCircular=({from:s,seen:o,to_:i,forceEnumerable:w,maxDepth:x,depth:C})=>{const j=i||(Array.isArray(s)?[]:{});if(o.push(s),C>=x)return j;if("function"==typeof s.toJSON&&!0!==s[_])return(s=>{s[_]=!0;const o=s.toJSON();return delete s[_],o})(s);for(const[i,u]of Object.entries(s))"function"==typeof a&&a.isBuffer(u)?j[i]="[object Buffer]":"function"!=typeof u&&(u&&"object"==typeof u?o.includes(s[i])?j[i]="[Circular]":(C++,j[i]=destroyCircular({from:s[i],seen:o.slice(),forceEnumerable:w,maxDepth:x,depth:C})):j[i]=u);for(const{property:o,enumerable:i}of u)"string"==typeof s[o]&&Object.defineProperty(j,o,{value:s[o],enumerable:!!w||i,configurable:!0,writable:!0});return j};s.exports={serializeError:(s,o={})=>{const{maxDepth:i=Number.POSITIVE_INFINITY}=o;return"object"==typeof s&&null!==s?destroyCircular({from:s,seen:[],forceEnumerable:!0,maxDepth:i,depth:0}):"function"==typeof s?`[Function: ${s.name||"anonymous"}]`:s},deserializeError:(s,o={})=>{const{maxDepth:i=Number.POSITIVE_INFINITY}=o;if(s instanceof Error)return s;if("object"==typeof s&&null!==s&&!Array.isArray(s)){const o=new Error;return destroyCircular({from:s,seen:[],to_:o,maxDepth:i,depth:0}),o}return new NonError(s)}}},20426:s=>{var o=Object.prototype.hasOwnProperty;s.exports=function baseHas(s,i){return null!=s&&o.call(s,i)}},20575:(s,o,i)=>{"use strict";var a=i(3121);s.exports=function(s){return a(s.length)}},20798:(s,o,i)=>{"use strict";var a,u,_=i(45951),w=i(96794),x=_.process,C=_.Deno,j=x&&x.versions||C&&C.version,L=j&&j.v8;L&&(u=(a=L.split("."))[0]>0&&a[0]<4?1:+(a[0]+a[1])),!u&&w&&(!(a=w.match(/Edge\/(\d+)/))||a[1]>=74)&&(a=w.match(/Chrome\/(\d+)/))&&(u=+a[1]),s.exports=u},20850:(s,o,i)=>{"use strict";s.exports=i(46076)},20999:(s,o,i)=>{var a=i(69302),u=i(36800);s.exports=function createAssigner(s){return a((function(o,i){var a=-1,_=i.length,w=_>1?i[_-1]:void 0,x=_>2?i[2]:void 0;for(w=s.length>3&&"function"==typeof w?(_--,w):void 0,x&&u(i[0],i[1],x)&&(w=_<3?void 0:w,_=1),o=Object(o);++a<_;){var C=i[a];C&&s(o,C,a,w)}return o}))}},21549:(s,o,i)=>{var a=i(22032),u=i(63862),_=i(66721),w=i(12749),x=i(35749);function Hash(s){var o=-1,i=null==s?0:s.length;for(this.clear();++o{var a=i(16547),u=i(43360);s.exports=function copyObject(s,o,i,_){var w=!i;i||(i={});for(var x=-1,C=o.length;++x{var a=i(51873),u=i(37828),_=i(75288),w=i(25911),x=i(20317),C=i(84247),j=a?a.prototype:void 0,L=j?j.valueOf:void 0;s.exports=function equalByTag(s,o,i,a,j,B,$){switch(i){case"[object DataView]":if(s.byteLength!=o.byteLength||s.byteOffset!=o.byteOffset)return!1;s=s.buffer,o=o.buffer;case"[object ArrayBuffer]":return!(s.byteLength!=o.byteLength||!B(new u(s),new u(o)));case"[object Boolean]":case"[object Date]":case"[object Number]":return _(+s,+o);case"[object Error]":return s.name==o.name&&s.message==o.message;case"[object RegExp]":case"[object String]":return s==o+"";case"[object Map]":var V=x;case"[object Set]":var U=1&a;if(V||(V=C),s.size!=o.size&&!U)return!1;var z=$.get(s);if(z)return z==o;a|=2,$.set(s,o);var Y=w(V(s),V(o),a,j,B,$);return $.delete(s),Y;case"[object Symbol]":if(L)return L.call(s)==L.call(o)}return!1}},22032:(s,o,i)=>{var a=i(81042);s.exports=function hashClear(){this.__data__=a?a(null):{},this.size=0}},22225:s=>{var o="\\ud800-\\udfff",i="\\u2700-\\u27bf",a="a-z\\xdf-\\xf6\\xf8-\\xff",u="A-Z\\xc0-\\xd6\\xd8-\\xde",_="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",w="["+_+"]",x="\\d+",C="["+i+"]",j="["+a+"]",L="[^"+o+_+x+i+a+u+"]",B="(?:\\ud83c[\\udde6-\\uddff]){2}",$="[\\ud800-\\udbff][\\udc00-\\udfff]",V="["+u+"]",U="(?:"+j+"|"+L+")",z="(?:"+V+"|"+L+")",Y="(?:['’](?:d|ll|m|re|s|t|ve))?",Z="(?:['’](?:D|LL|M|RE|S|T|VE))?",ee="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",ie="[\\ufe0e\\ufe0f]?",ae=ie+ee+("(?:\\u200d(?:"+["[^"+o+"]",B,$].join("|")+")"+ie+ee+")*"),ce="(?:"+[C,B,$].join("|")+")"+ae,le=RegExp([V+"?"+j+"+"+Y+"(?="+[w,V,"$"].join("|")+")",z+"+"+Z+"(?="+[w,V+U,"$"].join("|")+")",V+"?"+U+"+"+Y,V+"+"+Z,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",x,ce].join("|"),"g");s.exports=function unicodeWords(s){return s.match(le)||[]}},22551:(s,o,i)=>{"use strict";var a=i(96540),u=i(69982);function p(s){for(var o="https://reactjs.org/docs/error-decoder.html?invariant="+s,i=1;i